Trident IoT Zigbee SDK
Loading...
Searching...
No Matches
Build System

Back to Trident IoT SDK

Overview


The Zigbee SDK build system is based on CMake.

It's not important to know much about CMake to compile a Zigbee application, but the more knowledge, the more flexibility.

This page explains what you can expect to find inside a Zigbee project, what the build output contains, some details of how the secure bootloader is tied into all of this, and some common troubleshooting steps.

Project Directory Structure


The following shows the directory structure for the On/Off Switch project template (output from tree -L 2). The below sections will explain what all these files/directories are used for in a project.

.
├── app_gcc_cm3_mcu_2mb.ld
├── arm-gcc-toolchain-T32CM11.cmake
├── bootloader
│   └── bootloader_T32Cx1x
├── CMakeLists.txt
├── CMakePresets.json
├── config.cmake
├── tr_plugin_config.cmake
├── generated
│   ├── tr_zcl_endpoint_config.c
│   ├── tr_zcl_endpoint_config.h
│   ├── tr_zcl_id.h
│   ├── tr_zcl_plugin_include.h
│   ├── tr_zcl_plugin_stubs.c
│   └── tr_zcl_type.h
├── hal_config_custom_T32CM11
│   ├── tr_hal_config.c
│   └── tr_hal_config.h
├── hal_config_dkncm11_T32CM11
│   ├── tr_hal_config.c
│   └── tr_hal_config.h
├── keys
│   ├── tr_private_signing_key.pem
│   ├── tr_public_signing_key.der
│   └── tr_public_signing_key.json
├── README.md
├── src
│   ├── on_off_switch_app.c
│   └── project_app_tokens.h
├── tridentiot-sdk
│   ├── framework
│   ├── platform
│   ├── tools
│   ├── tridentiot-sdk.toml
│   └── zigbee
├── trident.toml
└── zap_config.zap
Note
More information about the switch project can be found here: On/Off Switch SZED

Build System Files


File Name Description Notes
app_gcc_cm3_mcu_2mb.ld Linker file for T32CM11C Can be modified to change flash partition sizes (must update OTA logic to align with correct addesses)
arm-gcc-toolchain-T32CM11.cmake Toolchain file for T32CM11C Used to set compiler/linker flags for the build
CMakeLists.txt Primary build system file, contains all files being built Common file to modify to add/remove functionality from a project
CMakePresets.json Build presets used by elcap to build a project Changing the presets may break the elcap build capabilities
config.cmake Configuration file for high level build system settings Can be modified to adjust things like signing keys location or Zigbee device type
tr_plugin_config.cmake Configuration file for adding/modifying plugins Can be modified to change which plugins exist in the project and modify and plugin settings
Note
Search for [USER HELP] comments in the build system files for common areas of interest.
See Plugin Configuration Guide for how to use tr_plugin_config.cmake

Bootloader Files


bootloader sub-directory structure within the project (output from tree -L 3)

.
└── bootloader_T32Cx1x
├── arm-gcc-toolchain-BTL-T32CM11.cmake
├── bootloader_gcc_cm3_mcu.ld
├── CMakeLists.txt
├── config.cmake
├── hal_config_custom_T32CM11
│   ├── tr_hal_config.c
│   └── tr_hal_config.h
├── hal_config_dkncm11_T32CM11
│   ├── tr_hal_config.c
│   └── tr_hal_config.h
└── src
├── bootloader.c
├── bootloader.h
└── xmodem.c
File Name Description Notes
bootloader_gcc_cm3_mcu.ld Linker file for T32CM11C bootloader Should not be modified
arm-gcc-toolchain-BTL-T32CM11.cmake Toolchain file for T32CM11C bootloader Used to set compiler/linker flags for the build
CMakeLists.txt Primary build system file Should not be modified
config.cmake Used to set relevant paths Should not be modified
hal_config_custom_T32CM11/ Contains hardware configs for CM11 based custom PCB target Users should modify these for custom PCB targets as needed
hal_config_dkncm11_T32CM11/ Contains hardware configs for DKNCM11 PCB target Users can modify these as needed
src/ Contains source files for bootloader project Can modify as needed, any files added here will be added to the build
Note
The bootloader is built and combined with the overall project automatically

Hardware Files


Hardware files for the application exist in 2 directories by default:

Directory Name Description Notes
hal_config_custom_T32CM11/ Contains hardware configs for CM11 based custom PCB target Users should modify these for custom PCB targets as needed
hal_config_dkncm11_T32CM11/ Contains hardware configs for DKNCM11 PCB target Users can modify these as needed

This mechanism provides a powerful way to support multiple PCB targets within a single build. It enables Trident engineers to deliver higher-quality support, since we can run your application on hardware we already have available.

  • If your project does not require multiple PCB targets, you can simply rename or remove any unused hal_config directories.
  • To add support for an additional target, create a new directory named hal_config_<target>_T32CM11C.

Each hal_config directory contains the configuration files that adapt the Trident HAL to a specific PCB. These files define how the HAL interfaces with the chip peripherals for each supported PCB target.

Generated Files


The generated directory contains all application-layer configuration files. All of these files are automatically produced by the ZAP tool and should never be edited by hand. Instead, update configurations through ZAP and re-generate the files to ensure consistency.

ZAP Generated File Name Description Notes
tr_zcl_endpoint_config.c Configures device endpoint(s) and ZCL profile Do not edit manually
tr_zcl_endpoint_config.h Configures device endpoint(s) and ZCL profile Do not edit manually
tr_zcl_id.h List of all ZAP supported ZCL IDs Do not edit manually
tr_zcl_plugin_include.h Includes all enabled ZCL plugin header files Allows app to utilize enabled Trident ZCL plugins. Do not edit manually
tr_zcl_plugin_stubs.c ZCL plugin initialization stubs file Allows app to build with or without Trident ZCL plugins. Do not edit manually
tr_zcl_type.h ZCL definitions for types, enums, and data structures Do not edit manually
Note
See ZAP User Guide for how to modify these generated files

Key Files


The private_key.pem and public_key.der keys are required to satisfy the secure bootloader. These keys will be generated by the build system if they do not exist. If the files to exist as described in the config.cmake file, then those keys will be used instead.

Key Generation Logic

  1. Define paths to the public and private keys in the config.cmake file. Default configuration:
    # [USER HELP] Path/to/keys for signing binary files. If these keys do not exist, they will be created at build time
    set(TSDK_CONFIG_PRIVATE_SIGNING_KEY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/keys/tr_private_signing_key.pem")
    set(TSDK_CONFIG_PUBLIC_SIGNING_KEY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/keys/tr_public_signing_key.der")
  2. During a project build, if the keys defined in step 1 do not exist, the build system will generate them.
  3. If the keys files exist, then the build system will use them as-is.
    Note
    Private key must be a .pem and public key must be a .der file format.
  4. The tokens.json file needed to write the key tokens manually is created at build time. See T32CM11 Secure Bootloader for how these tokens are used.

Manual Key Generation

If you wish to create the signing keys manually, you can do so with the following commands:

  1. Generate a private key:
    openssl ecparam -genkey -name prime256v1 -noout -out private_key.pem
    zb_uint8_t * name
    Definition tr_zcl_cmd_structs.h:3504
  2. Generate a public key from the private key:
    openssl ec -in private_key.pem --outform DER -pubout -out public_key.der
  3. Update TSDK_CONFIG_PRIVATE_SIGNING_KEY_PATH and TSDK_CONFIG_PUBLIC_SIGNING_KEY_PATH in config.cmake to point at the new key locations. The tokens.json file will be generated into the directory in which the public key lives.

Source Files


The src directory is where all application-specific logic should be implemented. This is the place to add your project’s custom source and header files.

The build system automatically includes files in src recursively, so you can freely organize your code into subdirectories and layers of modules without additional configuration. Any .c or .h files placed anywhere under src will be picked up during the build.

Note
When adding or removing files from src, you must perform a clean rebuild to ensure the changes are detected. Use the following command:
elcap build --clean

Trident IoT SDK Files


The tridentiot-sdk directory contains all of the SDK components relevant to Zigbee projects. This means the SDK already includes the full set of source files, libraries, and headers needed for development.

When you want to add functionality to your project, you do not need to create or copy new files. Instead, you simply update your project’s tr_plugin_config.cmake file to enable the desired plugin. The build system will include the needed files automatically based on the configurations selected.

If you want to add file of your own, just put them inside of the project's src directory and they will be added on the next full build.

Miscellaneous Files


A project also includes several supporting files that are primarily used by development tools and for reference:

  • trident.toml – Project definition file required by elcap.
  • zap_config.zap – Stores the configuration data used by the ZAP tool.
  • README.md – Provides helpful links to Trident documentation and other project resources.

Build Output


The output of the build contains a mixture of files that can be used to:

  • flash the device
  • perform over-the-air firmware updates
  • test the over-the-air firmware update cluster at the certification lab
  • debug the project using Segger Ozone
  • interact with APP or MFG tokens (see elcap Tokens documentation)
  • allow intellisense in vs code to know what project configurations are active
  • unlock the SWD lines after they were locked via elcap (CM11 only)

The build output for the On/Off Switch project template example can be found below:

.
├── bootloader
├── cm11_swd_unlock-signed.bin
├── CMakeCache.txt
├── CMakeFiles
├── cmake_install.cmake
├── compile_commands.json
├── Makefile
├── null-file-v0x00000001.ota
├── null-file-v0xffffffff.ota
├── platform
├── switch-custom.bin
├── switch-custom.elf
├── switch-custom.hex
├── switch-custom.jdebug
├── switch-custom-signed.bin
├── switch-custom-signed-combined.bin
├── switch-custom-signed-combined.hex
├── switch-custom-signed.hex
├── switch-custom-v0x01020304.ota
├── switch-dkncm11.bin
├── switch-dkncm11.elf
├── switch-dkncm11.hex
├── switch-dkncm11.jdebug
├── switch-dkncm11-signed.bin
├── switch-dkncm11-signed-combined.bin
├── switch-dkncm11-signed-combined.hex
├── switch-dkncm11-signed.hex
├── switch-dkncm11-v0x01020304.ota
├── switch.map
├── T32CM11C_app_token_def.json
├── tr_bootloader-prefix
└── tr_hal

Files to Flash


During the build process, several .bin, .elf, and .hex files are generated. Most of these are intermediate artifacts that you typically won’t need, but they are preserved in case you want to use them to create other outputs.

For example, a .bin file is required when generating custom OTA files with Trident tools.

File Naming Convention

Build outputs follow the naming pattern:

[project name]-[pcb target].[file extension]

For instance, the On/Off Switch project produces files for both a custom PCB target and the Trident development board (DKNCM11).

  • Files with "-signed" have been cryptographically signed using the keys defined in config.cmake. See Key Files for details.
  • Files with "-combined" bundle both the bootloader and the application into a single image.

Commonly Used Files (Example using DKNCM11 PCB target)

File Name Description Notes
switch-dkncm11-signed-combined.hex Signed application combined with bootloader and TR_MFG_TOKEN_SIGNED_BOOTLOADER_KEY tokens This file allows a device to boot and run out of the box
switch-dkncm11-signed.hex Signed application without bootloader or token data Useful for reprogramming a running device without the bootloader
switch-dkncm11-signed.bin Signed binary file without flash address information Useful for creating custom OTA files using elcap

OTA Files


An over-the-air upgrade (OTA) file will be generated at build time if the following requirements are met:

  1. Project contains the OTA Client in the ZAP generated files
  2. Project contains the OTA Client Current File Version attribute (Attribute ID: 0x0002)
  3. Project contains the OTA Client Manufacturer ID attribute (Attribute ID: 0x0007)
  4. Project contains the OTA Client Image Type ID attribute (Attribute ID: 0x0008)

If all above requirements are satisfied, the build system will pull the default values for these attributes from the ZAP generated files to construct the following OTA files (Example using DKNCM11 PCB target):

File Name Description Notes
switch-dkncm11-v0x01020304.ota OTA upgrade file for switch application Uses default attribute values generated from ZAP to populate version, MFG ID, and Image Type ID
null-file-v0x00000001.ota NULL downgrade file for certification testing Uses default attribute values generated from ZAP to populate MFG ID, and Image Type ID
null-file-v0xffffffff.ota NULL upgrade file for certification testing Uses default attribute values generated from ZAP to populate MFG ID, and Image Type ID
Note
If you want to populate version, MFG ID, or image type ID using tokens or other non-ZAP related methods, you will need to construct the OTA file manually using elcap

Build System Generated OTA File Helpful Information

  • uses the signed application binary file to create the Zigbee OTA file (Eg. switch-dkncm11-signed.bin)
  • contains the image integrity code sub-element with the zigbee specified hash value
  • contains manufacturer specific tag ID 0xFFFF with tag data of all 0xFF's to ensure that the application image remains page aligned in flash
    • this is done to allow the bootloader to successfully verify the application signature when receiving an image over the air and when booting the application from the application partition
    • if you need additional manufacturer specific tags, please use any of the other tag ID values

Ozone Debugger Files


Debugger project files compatible with Segger Ozone are generated as part of the build process (Eg. switch-dkncm11.jdebug). To use this file to debug a project please see: Debugging a Project using SEGGER Ozone

Token Files


There are 2 areas that generate token related files when a project is built:

  1. The signing key MFG tokens data file is created in the keys directory of you project (see Key Files)
  2. The APP tokens definition file is generated into the build directory (Eg. T32CM11C_app_token_def.json)

First, the signing key MFG token data file (Eg. tr_public_signing_key.json) contains the data needed by the bootloader to verify the image signature at boot. This file can be used along with elcap to write those tokens manually. For example:

elcap tokens write --target T32CM11C --file tr_public_signing_key.json

Second, in order to use the APP specific tokens defined in src/project_app_tokens.h, the flash address information needs to be defined in a format that elcap can use to locate them. This token definition file (Eg. T32CM11C_app_token_def.json) provides that address data to elcap. Please see the elcap Tokens documentation for details on how to use this.

Intellisense

The build directory contains two types of subdirectories:

  1. Build artifact directories - Named using the pattern CHIP_PN.BUILD_TYPE
  2. Generated directory - Contains build system helper files

Example:

/build$ tree -L 1
.
├── generated
├── T32CM11C.Debug
└── T32CM11C.Release

Build artifact directories (e.g., T32CM11C.Debug) contain the compiled outputs as described in the previous sections.

Generated directory serves two purposes:

  • Maps project configurations from tr_plugin_config.cmake to the source files required by the build system
  • Contains a summary header file used by VS Code IntelliSense to accurately represent your project's configuration (this file is not included in the build itself)

CM11 SWD Unlock Application


Once flash protection is enabled on the T32CM11C, the SWD interface is disabled. This means that after the device is locked, it cannot be unlocked through SWD alone.

An unlock application is included in every project build to provide a method for recovering SWD access while preserving security. This unlock app is signed using the project’s signing keys, ensuring that its signature is verified before the device is unlocked.

Using the Unlock Application

Unlocking a locked device requires transferring the signed unlock binary to the target using XMODEM.

Example: Locking a Device

  1. Flash the signed-combined.hex file (e.g., switch-dkncm11-signed-combined.hex).
  2. Set the TR_MFG_TOKEN_SERIAL_BOOT_DELAY_SEC token to a value greater than 0:
    elcap tokens write --name TR_MFG_TOKEN_SERIAL_BOOT_DELAY_SEC --value 3 --value-type int --target T32CM11C
  3. Lock the device:
    elcap device lock --target T32CM11C
  4. Verify the device is locked by attempting to use the SWD interface, for example:
    elcap device erase

Example: Unlocking a Device

  1. Open a serial connection using a terminal that supports XMODEM transfers.
  2. Reset the device using the CLI reset command.
  3. When prompted by the bootloader, press 'x':
    [BOOT] Bootloader V0.3
    [BOOT] FOTA image overflow.
    [BOOT] FOTA no image found
    [BOOT] APP: Image signature verified.
    [BOOT] Bootloader check successful.
    [BOOT] Looking for xmodem start ('x') for 3 sec ..
  4. Wait for the XMODEM session to begin:
    [XMODEM] Erasing flash
    [XMODEM] Starting xmodem.
  5. Transfer cm11_swd_unlock-signed.bin using XMODEM.
  6. After the transfer completes, perform a hardware reset.
  7. The SWD pins should now be accessible again.
Warning
The TR_MFG_TOKEN_SERIAL_BOOT_DELAY_SEC token MUST be written for the bootloader to expose XMODEM mode. Without writing this token it is not possible to unlock a CM11 based device!

Troubleshooting


  1. When in doubt, run:
    elcap build --clean
  2. How can I add build time definitions or cmake cache variables to my project?
    • Search the CMakeLists.txt file for GLOBAL_COMPILE_DEFINITIONS and add your desired definition there. Example adding MY_DEFINITION with a value of 1:
      set(GLOBAL_COMPILE_DEFINITIONS
      TR_PLATFORM_${PLATFORM_VARIANT}
      MY_DEFINITION=1
      # [USER HELP] Add additional compile definitions here
      )
  3. Why is my OTA file not being generated even though I meet the requirements described in OTA Files
    • The OTA file generation script expects the ZAP defaults to be in hex format with a leading '0x'. Make sure the attribute values start with a '0x' in ZAP then regenerate
  4. What if I want to include additional files in my build that live outside of the /src directory?
    • Search the CMakeLists.txt file for ADDITIONAL_SOURCES and ADDITIONAL_INCLUDES.
    • Add the path/to/source.c and path/to/includes to ADDITIONAL_SOURCES and ADDITIONAL_INCLUDES respectively.
  5. Contact support at: support@tridentiot.com