*********************************************************************************************************************
* MMMMMMMM MMMMMMMM hhhhhhh XXXXXXX XXXXXXX *
* M:::::::M M:::::::M h:::::h X:::::X X:::::X *
* M::::::::M M::::::::M h:::::h X:::::X X:::::X *
* M:::::::::M M:::::::::M h:::::h X::::::X X:::::X *
* M::::::::::M M::::::::::M eeeeeeeeeeee ssssssssss h:::: hhhhhh XX:::::X X:::::XX *
* M:::::::::::M M:::::::::::M ee::::::::::::ee ss::::::::::s h::::::::::hhh X:::::X X:::::X *
* M:::::::M::::M M::::M:::::::M e::::::eeeee:::::eess:::::::::::::s h::::::::::::::hh X:::::X:::::X *
* M::::::M M::::M M::::M M::::::Me::::::e e:::::es::::::ssss:::::sh:::::::hhh::::::h X:::::::::X *
* M::::::M M::::M::::M M::::::Me:::::::eeeee::::::e s:::::s ssssss h::::::h h::::::h X:::::::::X *
* M::::::M M:::::::M M::::::Me:::::::::::::::::e s::::::s h:::::h h:::::h X:::::X:::::X *
* M::::::M M:::::M M::::::Me::::::eeeeeeeeeee s::::::s h:::::h h:::::h X:::::X X:::::X *
* M::::::M MMMMM M::::::Me:::::::e ssssss s:::::s h:::::h h:::::h XXX:::::X X:::::XXX *
* M::::::M M::::::Me::::::::e s:::::ssss::::::sh:::::h h:::::h X::::::X X::::::X *
* M::::::M M::::::M e::::::::eeeeeeee s::::::::::::::s h:::::h h:::::h X:::::X X:::::X *
* M::::::M M::::::M ee:::::::::::::e s:::::::::::ss h:::::h h:::::h X:::::X X:::::X *
* MMMMMMMM MMMMMMMM eeeeeeeeeeeeee sssssssssss hhhhhhh hhhhhhh XXXXXXX XXXXXXX *
*********************************************************************************************************************MeshX is a portable C implementation of a Bluetooth Low Energy (BLE) Mesh node stack and example components. It is designed to be portable across board support packages (BSPs), microcontroller units (MCUs) and SDKs via a CMake-driven build system and small platform abstraction layers.
This README documents the new portability model, the BSP/MCU/SDK support available in this repository, and how to build MeshX using the CMake-level build system.
- Portable CMake-based build integration for multiple BSPs and MCUs
- Current BSP:
weact_c3(WeAct ESP32-C3 board) - Current MCU family:
espwith supported MCU:esp32c3 - SDK integration: ESP-IDF (driven by the
IDF_PATHenvironment variable) - CMake options to select BSP, product profile, and build an executable
CMakeLists.txt- Top-level CMake entry. Defines project variables and includes the selected BSP.main/CMakeLists.txt- Collects sources frommain/component/meshxand registers the component with the platform.port/bsp/- BSPs live here. Each BSP contains board-specific CMake configuration and product profiles.port/platform/esp/- ESP platform integration (ESP-IDF glue and esp32c3 support files).tools/scripts/- Helper scripts and code-generation utilities (code_gen.py,build.sh, etc.).
| BSP name | Board / Notes | Location (CMake) |
|---|---|---|
| weact_c3 | WeAct ESP32-C3 development board | port/bsp/weact_c3/bsp.cmake |
| MCU family | Target | Notes / Location |
|---|---|---|
| esp | esp32c3 | port/platform/esp/esp32c3/esp32c3.cmake |
| SDK | Integration notes | Required env / file |
|---|---|---|
| ESP-IDF | ESP-IDF integration via port/platform/esp/esp_idf/esp_idf.cmake. Uses idf_component_register under the hood. |
IDF_PATH environment variable; run $IDF_PATH/export.sh |
If you want to add support for another BSP or MCU, add a directory under port/bsp/ for the BSP and a corresponding port/platform/<family>/<mcu>/<mcu>.cmake for the MCU/platform glue.
MeshX is driven from the top-level CMakeLists.txt. The most important CMake options you can set are:
-DBSP=<bsp-name>— Select which BSP to include. Default:weact_c3.-DPROD_NAME=<product_name>— Required product name used by the code generation pipeline.-DPROD_PROFILE=<path>— Path to the product profile YAML (defaults toport/bsp/${BSP}/prod_profile.yml).-DIDF_PATH=<path>— (Exported as environment variable) The ESP-IDF path is read from theIDF_PATHenvironment variable.-DELF=<executable_name>— Name of the final CMake project/ELF. Default set in top-level CMake.-DENABLE_TESTS=ON— Enable unit tests if the chosen platform supports it.
- Set up ESP-IDF environment (example — bash):
export IDF_PATH=/path/to/esp-idf
source $IDF_PATH/export.sh- Create build directory and configure CMake (replacing PROD_NAME):
mkdir -p build
cmake -S . -B build -DBSP=weact_c3 -DPROD_NAME=4_relay_panel -DPROD_PROFILE=../port/bsp/weact_c3/prod_profile.yml
cmake --build buildThis will include the BSP CMake (port/bsp/weact_c3/bsp.cmake), which in turn includes the platform glue port/platform/esp/esp32c3/esp32c3.cmake and the ESP-IDF integration.
PROD_NAMEis required;port/bsp/bsp_common.cmakewill calltools/scripts/code_gen.pyto generate product-specific source at configure time. IfPROD_NAMEis not provided, CMake will stop with a helpful error.- The build system registers MeshX sources with the platform via a helper
register_component()function implemented in the platform glue (for ESP-IDF this maps toidf_component_register).
tools/scripts/build.shandtools/scripts/build_ci.shwrap the typical configure + build flow and drivecode_gen.py. They are useful for CI or convenient local builds. You can inspect and adapt them to new BSPs or product profiles.
- Product profiles live in
port/bsp/<bsp>/prod_profile.yml. Add a product by adding an entry under theproductsmapping. The build scripts andcode_gen.pywill read this profile to generate product-specific composition files. - Model profiles are under
tools/scripts/model_profile.yml(used by the code generator).
If you want to add a new product for a BSP, create or edit port/bsp/<bsp>/prod_profile.yml and add a product entry under the products mapping. The product profile describes the product id, CID, elements and optional components.
prod:
cid: 0x7908
products:
- name: my_new_product
pid: 0x0100
elements:
- switch_relay_server: 2- prod.cid: Company identifier for the product set (hex integer).
- products[].name: Human- and tool-friendly product name (string). This name is used as
PROD_NAMEwhen invoking the build. - products[].pid: Product ID (hex integer).
- products[].elements: Ordered list of elements used by the product. Each element is expressed as a mapping of element-name:instance-count. Element names must match keys in
tools/scripts/model_profile.ymlunderelements. - products[].components (optional): list of small component toggles, e.g.
- unit_test: true.
prod:
cid: 0x7908
products:
- name: 4_relay_panel
pid: 0x0001
elements:
- switch_relay_server: 4
- name: all_in_one
pid: 0x0004
elements:
- switch_relay_client: 1
- switch_relay_server: 1
- light_cwww_server: 1
- light_cwww_client: 1
components:
- unit_test: truetools/scripts/code_gen.pyreads the product profile andtools/scripts/model_profile.ymland constructs:- compile-time macros (e.g.
CONFIG_PID_ID,CONFIG_MAX_ELEMENT_COUNT) written intomeshx_config.h. - a list of source files and include directories from the selected elements and models so the build system can register them.
- compile-time macros (e.g.
-
Choose your BSP and ensure you have the BSP's
prod_profile.yml(for quick tests you can copytools/scripts/prod_profile.ci.ymltoport/bsp/weact_c3/prod_profile.yml). -
Run the code generator directly to verify it finds the product and creates
meshx_config.h:
# from repo root (example product name: 4_relay_panel)
python3 tools/scripts/code_gen.py 4_relay_panel --root main/component/meshx --config main/component/meshx/default/inc --profile tools/scripts/prod_profile.ci.yml
# Inspect the generated header
ls -l main/component/meshx/default/inc/meshx_config.h
cat main/component/meshx/default/inc/meshx_config.h- If the generator complains
Product Not Found, check thatproducts[].nameexactly matches the name you passed tocode_gen.py/PROD_NAME.
- Always re-run CMake (or the helper build script) after changing product profiles because the profile is processed at configure time.
- Use
tools/scripts/model_profile.ymlto see available element names and how they map to source paths and macros. - Keep
pidvalues unique within acidnamespace to avoid accidental conflicts when you test product identification.
When building for ESP-IDF targets, the typical flash+monitor flow uses idf.py provided by ESP-IDF. For example:
# from the build directory configured with ESP-IDF environment
idf.py -p /dev/ttyUSB0 flash monitorIf you are using the build.sh helper it will generate an IDF project and artifacts compatible with idf.py.
- Add a BSP: create
port/bsp/<your_bsp>/bsp.cmakeand aprod_profile.ymlfor your board. Follow the pattern established byweact_c3. - Add a platform glue directory:
port/platform/<family>/<mcu>/<mcu>.cmakethat setsBASE_PLAT_SRC,BASE_PLAT_INC,PLAT_LIBS, and exposesregister_component()that maps to your target SDK build helpers. - If integrating with a new SDK, provide a small
register_component()implementation that wires MeshX sources into that SDK's build system (for ESP-IDF we callidf_component_register).
To make it easier to add a new BSP or MCU, this repository includes simple templates you can copy and adapt:
port/bsp/template_bsp/bsp.cmake— minimal BSP CMake that validatesPROD_NAMEand includes platform glue.port/bsp/template_bsp/prod_profile.yml— example product profile you can start from.port/platform/template_family/template_mcu/template_mcu.cmake— minimal platform glue template you can adapt to your SDK.
Quick step-by-step: add a new BSP + MCU
- Copy the BSP template and update variables:
cp -r port/bsp/template_bsp port/bsp/my_board
# Edit port/bsp/my_board/bsp.cmake and set BOARD_NAME, BOARD_MCU, MCU_FAMILY- Copy and edit the product profile for your board:
cp port/bsp/template_bsp/prod_profile.yml port/bsp/my_board/prod_profile.yml
# Edit prod_profile.yml: set cid, add products[].name, pid, and elements- Create platform glue for your MCU family/target by copying the template and filling in SDK specifics:
mkdir -p port/platform/my_family/my_mcu
cp port/platform/template_family/template_mcu/template_mcu.cmake port/platform/my_family/my_mcu/my_mcu.cmake
# Edit my_mcu.cmake to set BASE_PLAT_INC, BASE_PLAT_SRC, PLAT_LIBS and implement register_component() using your SDK's API- Configure a local CMake build to test:
mkdir -p build && cd build
cmake .. -DBSP=my_board -DPROD_NAME=example_product -DPROD_PROFILE=../port/bsp/my_board/prod_profile.yml
cmake --build .- Flash / monitor using your SDK's toolchain (for ESP-IDF use
idf.py) after the build completes.
- If CMake fails with "PROD_NAME is not set", re-run CMake with
-DPROD_NAME=<your_product>. - Ensure
IDF_PATHis exported andsource $IDF_PATH/export.shhas been run when building ESP targets. tools/scripts/code_gen.pyis invoked at configure time. If you change product profiles, re-run CMake to regenerate sources.
Contributions that add BSPs or improve portability are welcome. Please follow repository conventions and add CMake glue under port/bsp and port/platform.
See LICENSE.md for licensing information.