Skip to main content

How to: Project Generator

The CHESTER SDK Project Generator manages variants of catalog applications and generates their configuration from a YAML file. You can look at project.yaml files to see different variants.

Then you call west chester-update --variant "CHESTER Clime 1W" to update project files, then you call west build to recompile project.

WEST Command​

west chester-update <name> Generate files based on project.yaml features.

west chester-update <name> --list List all available variants.

west chester-update <name> --variant <variant-name> Generate files based on project.yaml variant features.

west chester-update <name> --version <v.X.Y.Z> Generate files based on project.yaml using the specified fw_version.

Examples:

west chester-update clime --variant chester-clime-z

west chester-update clime --variant chester-clime-rtd --version v3.2.1

tip

After any change in project.yaml this command could be called to update the project with the new changes.

info

The command can be executed without specifying <name> if you are already in the project folder.

Project YAML​

The project.yaml configuration file serves as the cornerstone for setting up and customizing your project.

This comprehensive guide outlines the step-by-step process to effectively configure your project using the provided YAML structure.

Project Information​

Enter essential project details as outlined in the YAML configuration.

project:
variant: Variant-name
company: 2024 COMPANY a.s.
license: 'SPDX-License-Identifier: LicenseRef-COMPANY-5-Clause'
fw_name: CHESTER Example
fw_bundle: com.hardwario.chester.example
fw_version: v1.0.0

Furthermore, the variant is included in Kconfig.variant such as:

config VARIANT_<VARIANT-NAME>
bool "Enable VARIANT_<VARIANT-NAME>"
default y

It can be used in the project using:

#if defined(CONFIG_VARIANT_<VARIANT-NAME>)
// Your code
#endif /* defined(CONFIG_VARIANT_<VARIANT-NAME>) */

Feature Specification​

This section outlines the available features or subsystems that can be included in the project configuration. Each feature represents a specific functionality or component that can be integrated into the project.

Subsystem features​

The term subsystem- refers to a functional module or component within the software architecture. Example:

features:
- subsystem-bluetooth
Subsystem Feature Options
NameFeatureConfiguration in prj.conf
Shellsubsystem-shellCONFIG_CTR_SHELL=y
ADCsubsystem-adcCONFIG_CTR_ADC=y
Accelerometersubsystem-accelCONFIG_CTR_ACCEL=y
Batterysubsystem-battCONFIG_CTR_BATT=y
Buffersubsystem-bufCONFIG_CTR_BUF=y
BLE Tagsubsystem-ble-tagCONFIG_CTR_BLE_TAG=y
Bluetoothsubsystem-bleCONFIG_CTR_BLE=y
Buttonsubsystem-buttonCONFIG_CTR_BUTTON=y
CBPrintf FP Supportsubsystem-cbprintf-fp-supportCONFIG_CBPRINTF_FP_SUPPORT=y
Configsubsystem-configCONFIG_CTR_CONFIG=y
Cloudsubsystem-cloudCONFIG_CTR_CLOUD=y
Defaultssubsystem-defaultsCONFIG_CTR_DEFAULTS=y
DS18B20subsystem-ds18b20CONFIG_CTR_DS18B20=y
Edgesubsystem-edgeCONFIG_CTR_EDGE=y
Entropy Generatorsubsystem-entropy-generatorCONFIG_ENTROPY_GENERATOR=y
Flashsubsystem-flashCONFIG_CTR_FLASH=y
GNSSsubsystem-gnssCONFIG_CTR_GNSS=y
GPIOsubsystem-gpioCONFIG_CTR_GPIO=y
Hygrosubsystem-hygroCONFIG_CTR_HYGRO=y
Infosubsystem-infoCONFIG_CTR_INFO=y
LEDsubsystem-ledCONFIG_CTR_LED=y
Logsubsystem-logCONFIG_CTR_LOG=y
LTEsubsystem-lteCONFIG_CTR_LTE_CLKSYNC=y
LTE V2subsystem-lte-v2CONFIG_CTR_LTE_V2=y
LRWsubsystem-lrwCONFIG_CTR_LRW=y
Machine Probesubsystem-machine-probeCONFIG_CTR_MACHINE_PROBE=y
MB7066-Asubsystem-mb7066-aCONFIG_MB7066_TIMER4=y CONFIG_MB7066_SAMPLE_COUNT=1
MB7066-Bsubsystem-mb7066-bCONFIG_MB7066_TIMER4=y CONFIG_MB7066_SAMPLE_COUNT=1
RTCsubsystem-rtcCONFIG_CTR_RTC=y
RTDsubsystem-rtdCONFIG_CTR_RTD=y
Settingssubsystem-settingsCONFIG_SETTINGS=y
Signalsubsystem-signalCONFIG_CTR_SIGNAL=y
Soil Sensorsubsystem-soil-sensorCONFIG_CTR_SOIL_SENSOR=y
Testsubsystem-testCONFIG_CTR_TEST=y
Thermsubsystem-thermCONFIG_CTR_THERM=y
WDOGsubsystem-wdogCONFIG_CTR_WDOG=y
W1subsystem-w1CONFIG_CTR_W1=y
ZCBORsubsystem-zcborCONFIG_ZCBOR=y CONFIG_ZCBOR_STOP_ON_ERROR=y
BT Filter Accept Listsubsystem-bt-filter-accept-listCONFIG_BT_FILTER_ACCEPT_LIST=y
BT Observersubsystem-bt-observerCONFIG_BT_OBSERVER=y

Hardware CHESTER feature​

The term hardware-chester- refers to a specific hardware component or device within the project's hardware ecosystem. Example:

features:
- hardware-chester-z

Custom Feature​

Refers to a feature that a customer can add based on specific requirements. Example:

features:
- custom-x
- custom-y

These features will enable the necessary configurations on: app.overlay, Kconfig, prj.conf. Furthermore, they are also included in features.h by pre-pending FEATURE_* such as:

#define FEATURE_SUBSYSTEM_BLE 1
#define FEATURE_HARDWARE_CHESTER_Z 1
#define FEATURE_CUSTOM_X 1
#define FEATURE_CUSTOM_Y 1

File features.h is included during compilation automatically and it is not needed to include it by #include anywhere.

Config Options​

Each config option allows for specific parameter settings, enabling precise control and customization of the application's behavior. These are then generated to app_config.c and app_config.h.

  • Type: int
parameters:
- name: interval-sample # Name separated by '-'
type: int
min: 30 # Minimum value
max: 86400 # Maximum value
default: 1800 # Default value
help: 'Get/Set sample itnerval' # Help parameter message
  • Type: float
parameters:
- name: alarm-threshold # Name separated by '-'
type: float
min: -40.0 # Minimum value
max: 500.0 # Maximum value
default: 125.5 # Default value
help: 'Get/Set alarm threshold' # Help parameter message
  • Type: enum
- name: scan-mode
type: enum
help: "Get/Set scan mode"
default: "off"
valueset:
- "off"
- "interval"
- "daily"
- "weekly"
- "monthly"
  • Type: string
parameters:
- name: string-param-name # Name separated by '-'
type: string
buffer_size: 35 # Buffer string size
default: "Let's connect and control ANYTHING" # Default string
help: 'Get/Set string-param-name' # Help parameter message
  • Type: bool
parameters:
- name: ch1-enabled # Name separated by '-'
type: bool
default: true
help: 'Get/Set CH1 enable' # Help parameter message
  • Type: int array
parameters:
- name: int-array-name # Name separated by '-'
type: array[int]
len: 4 # Length of the array
min: 30 # Minimum array element value
max: 86400 # Maximum array element value
default: [31, 32, 33, 34] # or null to declare [0, 0, 0, 0]
help: 'Get/Set int-array-name' # Help parameter message
  • Type: float array
parameters:
- name: float-array-name # Name separated by '-'
type: array[float]
len: 4 # Length of the array
min: 0.0 # Minimum array element value
max: 25.0 # Maximum array element value
default: [1.0, 2.0, 3.0, 4.0] # or null to declare [0.0, 0.0, 0.0, 0.0]
help: 'Get/Set float-array-name' # Help parameter message
  • Type: bool array
parameters:
- name: bool-array-name # Name separated by '-'
type: array[bool]
len: 4 # Length of the array
default: [true, false, true, true] # or null to declare [false, false, false, false]
help: 'Get/Set bool-array-name' # Help parameter message
  • Type: enum
parameters:
- name: enum-name-{} # Name separated by '-' and '{}' in the index location
type: enum
valueset: # Enumerators
- trigger
- counter
- voltage
- current

In app_config.c:

const struct ctr_config_item items[] = {
CTR_CONFIG_ITEM_ENUM("enum-name-1", m_config_interim.enum_name_1, ((const char*[]){"trigger", "counter", "voltage", "current"}), "Get/Set enum-name-1", APP_CONFIG_ENUM_NAME_TRIGGER),
CTR_CONFIG_ITEM_ENUM("enum-name-2", m_config_interim.enum_name_2, ((const char*[]){"trigger", "counter", "voltage", "current"}), "Get/Set enum-name-2", APP_CONFIG_ENUM_NAME_COUNTER),
CTR_CONFIG_ITEM_ENUM("enum-name-3", m_config_interim.enum_name_3, ((const char*[]){"trigger", "counter", "voltage", "current"}), "Get/Set enum-name-3", APP_CONFIG_ENUM_NAME_VOLTAGE),
CTR_CONFIG_ITEM_ENUM("enum-name-4", m_config_interim.enum_name_4, ((const char*[]){"trigger", "counter", "voltage", "current"}), "Get/Set enum-name-4", APP_CONFIG_ENUM_NAME_CURRENT),
};

In app_config.h:

enum app_config_enum_name_ {
APP_CONFIG_ENUM_NAME_TRIGGER = 0,
APP_CONFIG_ENUM_NAME_COUNTER = 1,
APP_CONFIG_ENUM_NAME_VOLTAGE = 2,
APP_CONFIG_ENUM_NAME_CURRENT = 3,
};
struct app_config {
enum app_config_enum_name enum_name_1;
enum app_config_enum_name enum_name_2;
enum app_config_enum_name enum_name_3;
enum app_config_enum_name enum_name_4;
};
info

In the application's configuration files (app_config.c and app_config.h), the valueset is associated with enum-name indices.

  • Type: enum (Custom)
parameters:
- name: enum-name # Name separated by '-'
type: enum
valueset: # Enumerators
- npn
- pnp
related: # variable(s) of enum
- name: trigger # Name separated by '-'
default: npn # Default
help: 'Get/Set trigger-enum-name' # Help parameter message
- name: counter # Name separated by '-'
default: pnp # Default
help: 'Get/Set counter-enum-name' # Help parameter message
info

The related section specifies enum variables associated with the enum-name parameter. These variables (trigger, counter, etc.) share the same enum values (npn, pnp, etc.) and provide specific default values and help messages for each variable.

In app_config.c:

const struct ctr_config_item items[] = {
CTR_CONFIG_ITEM_ENUM("trigger-enum-name", m_config_interim.trigger_enum_name, ((const char*[]){"npn", "pnp"}), "Get/Set trigger-enum-name", APP_CONFIG_ENUM_NAME_NPN),
CTR_CONFIG_ITEM_ENUM("counter-enum-name", m_config_interim.counter_enum_name, ((const char*[]){"npn", "pnp"}), "Get/Set counter-enum-name", APP_CONFIG_ENUM_NAME_PNP),
};

In app_config.h:

struct app_config {
enum app_config_enum_name trigger_enum_name;
enum app_config_enum_name counter_enum_name;
};

Features depends_on​

Once the Project Generator is executed features.h and variants.h are generated based on the selected variant and features. This enables the addition of dependencies to any parameter by including lines such as:

depends_on: defined(FEATURE_<feature_name>)`

or

depends_on: defined(VARIANT_<variant_name>)`
tip

Additionally, you can utilize logical operators && (AND) and || (OR) to incorporate multiple dependencies.

Example: In project.yaml:

parameters:
- name: float-param-name
type: float
min: -40.0
max: 5000.0
default: 125.5
help: 'Get/Set float-param'
depends_on: defined(FEATURE_HARDWARE_CHESTER_Z)
- name: int-array-name
type: array[int]
len: 4
min: 30
max: 86400
default: [31, 32, 33, 34]
help: 'Get/Set int-array-name'

In app_config.c:

const struct ctr_config_item items[] = {
#if defined(FEATURE_HARDWARE_CHESTER_Z)
CTR_CONFIG_ITEM_FLOAT("float-param-name", m_config_interim.float_param_name, -40.0f, 5000.0f, "Get/Set float-param.", 125.5f),
#endif /* defined(FEATURE_HARDWARE_CHESTER_Z) */

CTR_CONFIG_ITEM_FLOAT("int-array-name-1", m_config_interim.int_array_name[0], 30, 86400, "Get/Set int-array-name-1", 31),
CTR_CONFIG_ITEM_FLOAT("int-array-name-2", m_config_interim.int_array_name[1], 30, 86400, "Get/Set int-array-name-1", 32),
CTR_CONFIG_ITEM_FLOAT("int-array-name-3", m_config_interim.int_array_name[2], 30, 86400, "Get/Set int-array-name-1", 33),
CTR_CONFIG_ITEM_FLOAT("int-array-name-4", m_config_interim.int_array_name[3], 30, 86400, "Get/Set int-array-name-1", 34),
};

In app_config.h:

struct app_config {
#if defined(FEATURE_HARDWARE_CHESTER_Z)
float float_param_name;
#endif /* defined(FEATURE_HARDWARE_CHESTER_Z) */

int int_array_name[4];
};

Preserved Code Blocks​

Sections of generated files that are designated to remain unchanged during updates are called preserved code blocks. In prj.conf the config block is preserved, so put any non-default CONFIG_* options of your project there:

# ### Preserved code "config" (begin)
CONFIG_ADC_TLA2021_INIT_PRIORITY=60
CONFIG_NEWLIB_LIBC_NANO=n
# ^^^ Preserved code "config" (end)
info

Anything enclosed between these markers is kept as is when you run west chester-update.