From 8963812ed51bf1a45537d223a72dba7c7863bf37 Mon Sep 17 00:00:00 2001 From: Douglas Rocha Ferraz Date: Tue, 19 Apr 2022 21:30:01 -0400 Subject: [PATCH] Chef Sample App - yaml configuration file (#17330) * chg: removed config file, SDK path needs to be set as environment variable Change-Id: Ied6a186f5d7370818461f921e76309a0508aaaf5 * chg: config file is now a YAML file Change-Id: Ia34b45c1e54245b94da06dca626170a78581b7b9 * chg: zap-generated files in independent folders by device type Change-Id: If86a393576166a03f1aa801947b36233308e6df4 * fix: fixes CMakeLists files for ESP32 and nrfconnect to build on current tot Change-Id: Ia6f94dfc6a186036f41af1c567b4b8416ff2ef22 * chg: applied restyle Change-Id: I38f52568e0a7f967b35ad42ca7ade1373235c3fe * fix: added a words to .wordslist Change-Id: I84a7cb6ea7830146711450d0d713b9da2fd895b4 * Update .wordlist.txt * Update README.md * Update README.md * Update .wordlist.txt * fix: reverted unwanted change to submodule hash reference Change-Id: I15fee54e792d8aa06d83051b803c9e27093d29d3 --- examples/chef/.gitignore | 2 +- examples/chef/README.md | 30 ++++++- examples/chef/chef.py | 101 +++++++++++++++++------- examples/chef/chef_config.py | 17 ---- examples/chef/esp32/main/CMakeLists.txt | 3 +- examples/chef/esp32/main/main.cpp | 4 +- examples/chef/linux/BUILD.gn | 3 +- examples/chef/nrfconnect/CMakeLists.txt | 21 +++-- examples/chef/nrfconnect/Kconfig | 20 +++++ examples/chef/nrfconnect/main.cpp | 80 +++++++++++++------ examples/chef/nrfconnect/prj.conf | 38 ++++++--- 11 files changed, 224 insertions(+), 95 deletions(-) delete mode 100644 examples/chef/chef_config.py create mode 100644 examples/chef/nrfconnect/Kconfig diff --git a/examples/chef/.gitignore b/examples/chef/.gitignore index 79d65e24f32dbb..faa1ea61cbba31 100644 --- a/examples/chef/.gitignore +++ b/examples/chef/.gitignore @@ -1,4 +1,4 @@ -zap-generated +config.yaml project_include.cmake linux/args.gni linux/sample.gni diff --git a/examples/chef/README.md b/examples/chef/README.md index b5a7372a40502f..0ccd51193bae73 100644 --- a/examples/chef/README.md +++ b/examples/chef/README.md @@ -20,10 +20,32 @@ Run `chef.py -h` to see the available commands ## Building your first sample 1. Make sure you have the toolchain installed for your desired target -2. Update your SoC SDK paths on `chef_config.py` and flip the `configured` - variable to True -3. Run `$ chef.py -u` to update zap and the toolchain (on selected platforms) -4. Run `$ chef.py -gzbf -t -d lighting`. This command will run the +2. Run `chef.py` the first time to create a `config.yaml` configuration file. If + you already have SDK environment variables such as IDF_PATH (esp32) and + ZEPHYR_BASE (nrfconnect) it will use those values as default. +3. Update your the SDK paths on `config.yaml`. TTY is the path used by the + platform to enumerate its device as a serial port. Typical values are: + +``` + # ESP32 macOS + + TTY: /dev/tty.usbmodemXXXXXXX + + # ESP32 Linux + + TTY: /dev/ttyACM0 + + # NRFCONNECT macOS + + TTY: /dev/tty.usbserial-XXXXX + + # NRFCONNECT Linux + + TTY: /dev/ttyUSB0 +``` + +4. Run `$ chef.py -u` to update zap and the toolchain (on selected platforms) +5. Run `$ chef.py -gzbf -t -d lighting`. This command will run the ZAP GUI opening the `devices/lighting.zap` file and will allow editing. It will then generate the zap artifacts, place them on the `zap-generated` folder, run a build and flash the binary in your target diff --git a/examples/chef/chef.py b/examples/chef/chef.py index 12c2ad77e213e9..05cf43fedf08a3 100755 --- a/examples/chef/chef.py +++ b/examples/chef/chef.py @@ -19,8 +19,8 @@ import os import subprocess from pathlib import Path -import chef_config as config from sys import platform +import yaml global commandQueue commandQueue = "" @@ -50,13 +50,39 @@ def printc(strInput): print(color + strInput + TermColors.STRRESET) +def loadConfig(paths): + config = dict() + config["nrfconnect"] = dict() + config["esp32"] = dict() + + configFile = paths["scriptFolder"] + "/config.yaml" + if (os.path.exists(configFile)): + configStream = open(configFile, 'r') + config = yaml.load(configStream, Loader=yaml.SafeLoader) + configStream.close() + else: + print("Running for the first time and configuring config.yaml. " + + "Change this configuration file to include correct configuration " + + "for the vendor's SDK") + configStream = open(configFile, 'w') + config["nrfconnect"]["ZEPHYR_BASE"] = os.environ.get('ZEPHYR_BASE') + config["nrfconnect"]["TTY"] = None + config["esp32"]["IDF_PATH"] = os.environ.get('IDF_PATH') + config["esp32"]["TTY"] = None + print(yaml.dump(config)) + yaml.dump(config, configStream) + configStream.close() + + return config + + def definePaths(): paths = dict() paths["scriptFolder"] = os.path.abspath(os.path.dirname(__file__)) paths["matterFolder"] = paths["scriptFolder"] + "/../../" paths["rootSampleFolder"] = paths["scriptFolder"] - paths["genFolder"] = paths["rootSampleFolder"] + "/zap-generated" paths["devices"] = [] + for filepath in Path(f"{paths['rootSampleFolder']}/devices").rglob('*.zap'): paths["devices"].append( str(os.path.splitext(os.path.basename(filepath))[0])) @@ -108,6 +134,8 @@ def hexInputToInt(valIn): def main(argv): checkPythonVersion() paths = definePaths() + config = loadConfig(paths) + global myEnv myEnv = os.environ.copy() @@ -124,13 +152,6 @@ def main(argv): print('Windows is currently not supported. Use Linux or MacOS platforms') exit(1) - # - # Checks if user has configured its custom settings - # - if not config.configured: - print('Please edit chef_config.py file and change the flag to True') - exit(1) - # # Arguments parser # @@ -140,7 +161,7 @@ def main(argv): usage = f'''usage: chef.py [options] Platforms: - nrf52840dk_nrf52840 + nrfconnect esp32 linux @@ -179,7 +200,7 @@ def main(argv): action='store', dest="buildTarget", help="specifies target platform. Default is esp32. See info below for currently supported target platforms", - choices=['nrf52840dk_nrf52840', 'esp32', 'linux', ], + choices=['nrfconnect', 'esp32', 'linux', ], metavar="TARGET", default="esp32") parser.add_option("-r", "--rpc", help="enables Pigweed RPC interface. Enabling RPC disables the shell interface. Your sdkconfig configurations will be reverted to default. Default is PW RPC off. When enabling or disabling this flag, on the first build force a clean build with -c", action="store_true", dest="doRPC") @@ -189,6 +210,8 @@ def main(argv): help="specifies the Product ID. Default is 0x8000", metavar="PID", default=0x8000) parser.add_option("", "--rpc_console", help="Opens PW RPC Console", action="store_true", dest="doRPC_CONSOLE") + parser.add_option("-y", "--tty", help="Enumerated USB tty/serial interface enumerated for your physical device. E.g.: /dev/ACM0", + dest="tty", metavar="TTY", default=None) options, _ = parser.parse_args(argv) @@ -199,15 +222,23 @@ def main(argv): # queuePrint(f"Target is set to {options.sampleDeviceTypeName}") + paths["genFolder"] = paths["rootSampleFolder"] + f"/out/{options.sampleDeviceTypeName}/zap-generated/" + queuePrint("Setting up environment...") if options.buildTarget == "esp32": + if config['esp32']['IDF_PATH'] is None: + print('Path for esp32 SDK was not found. Make sure esp32.IDF_PATH is set on your config.yaml file') + exit(1) paths["platFolder"] = os.path.normpath( paths["rootSampleFolder"] + "/esp32") - queueCommand(f"source {config.esp32Folder}/export.sh") - elif options.buildTarget == "nrf52840dk_nrf52840": + queueCommand(f'source {config["esp32"]["IDF_PATH"]}/export.sh') + elif options.buildTarget == "nrfconnect": + if config['nrfconnect']['ZEPHYR_BASE'] is None: + print('Path for nrfconnect SDK was not found. Make sure nrfconnect.ZEPHYR_BASE is set on your config.yaml file') + exit(1) paths["platFolder"] = os.path.normpath( paths["rootSampleFolder"] + "/nrfconnect") - queueCommand(f"source {config.nrfconnectFolder}/zephyr/zephyr-env.sh") + queueCommand(f'source {config["nrfconnect"]["ZEPHYR_BASE"]}/zephyr-env.sh') queueCommand("export ZEPHYR_TOOLCHAIN_VARIANT=gnuarmemb") elif options.buildTarget == "linux": pass @@ -223,7 +254,7 @@ def main(argv): if options.doUpdateToolchain: if options.buildTarget == "esp32": queuePrint("ESP32 toolchain update not supported. Skipping") - elif options.buildTarget == "nrf52840dk_nrf52840": + elif options.buildTarget == "nrfconnect": queuePrint("Updating toolchain") queueCommand( f"cd {paths['matterFolder']} && python3 scripts/setup/nrfconnect/update_ncs.py --update") @@ -264,7 +295,7 @@ def main(argv): queueCommand(f"rm {paths['genFolder']}/*") queueCommand( f"{paths['matterFolder']}/scripts/tools/zap/generate.py {paths['rootSampleFolder']}/devices/{options.sampleDeviceTypeName}.zap -o {paths['genFolder']}") - # sometimes af-gen-event.h is not generated + # af-gen-event.h is not generated queueCommand(f"touch {paths['genFolder']}/af-gen-event.h") # @@ -275,7 +306,7 @@ def main(argv): if options.buildTarget == "esp32": queueCommand(f"cd {paths['rootSampleFolder']}/esp32") queueCommand("idf.py menuconfig") - elif options.buildTarget == "nrf52840dk_nrf52840": + elif options.buildTarget == "nrfconnect": queueCommand(f"cd {paths['rootSampleFolder']}/nrfconnect") queueCommand("west build -t menuconfig") elif options.buildTarget == "linux": @@ -301,7 +332,7 @@ def main(argv): f"Product ID 0x{options.pid:02X} / Vendor ID 0x{options.vid:02X}") queueCommand(f"cd {paths['rootSampleFolder']}") - if (options.buildTarget == "esp32") or (options.buildTarget == "nrf52840dk_nrf52840"): + if (options.buildTarget == "esp32") or (options.buildTarget == "nrfconnect"): queueCommand(f''' cat > project_include.cmake < +#include #include #include #include @@ -35,35 +36,69 @@ using namespace chip; using namespace chip::Shell; +using namespace chip::DeviceLayer; -int main() +namespace { +constexpr int kExtDiscoveryTimeoutSecs = 20; +} + +CHIP_ERROR main() { - chip::Platform::MemoryInit(); - chip::DeviceLayer::PlatformMgr().InitChipStack(); - chip::DeviceLayer::PlatformMgr().StartEventLoopTask(); + CHIP_ERROR err = chip::Platform::MemoryInit(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "Platform::MemoryInit() failed"); + return err; + } + + err = PlatformMgr().InitChipStack(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "PlatformMgr().InitChipStack() failed"); + return err; + } // Network connectivity #if CHIP_DEVICE_CONFIG_ENABLE_WPA - chip::DeviceLayer::ConnectivityManagerImpl().StartWiFiManagement(); + ConnectivityManagerImpl().StartWiFiManagement(); #endif #if CHIP_ENABLE_OPENTHREAD - chip::DeviceLayer::ThreadStackMgr().InitThreadStack(); -#ifdef CONFIG_OPENTHREAD_MTD_SED - chip::DeviceLayer::ConnectivityMgr().SetThreadDeviceType( - chip::DeviceLayer::ConnectivityManager::kThreadDeviceType_SleepyEndDevice); + err = ThreadStackMgr().InitThreadStack(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "ThreadStackMgr().InitThreadStack() failed"); + return err; + } + +#ifdef CONFIG_OPENTHREAD_MTD + err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); #else - chip::DeviceLayer::ConnectivityMgr().SetThreadDeviceType( - chip::DeviceLayer::ConnectivityManager::kThreadDeviceType_MinimalEndDevice); -#endif /* CONFIG_OPENTHREAD_MTD_SED */ + err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_FullEndDevice); +#endif + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "ConnectivityMgr().SetThreadDeviceType() failed"); + return err; + } #endif /* CHIP_ENABLE_OPENTHREAD */ - // Start IM server - chip::Server::GetInstance().Init(); - // Device Attestation & Onboarding codes chip::Credentials::SetDeviceAttestationCredentialsProvider(chip::Credentials::Examples::GetExampleDACProvider()); + chip::app::DnssdServer::Instance().SetExtendedDiscoveryTimeoutSecs(kExtDiscoveryTimeoutSecs); + + // Start IM server + static chip::CommonCaseDeviceServerInitParams initParams; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); + chip::DeviceLayer::ConfigurationMgr().LogDeviceConfig(); + err = chip::DeviceLayer::PlatformMgr().StartEventLoopTask(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "PlatformMgr().StartEventLoopTask() failed"); + } + // When SoftAP support becomes available, it should be added here. #if CONFIG_NETWORK_LAYER_BLE PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kBLE)); @@ -74,18 +109,17 @@ int main() // Starts commissioning window automatically. Starts BLE advertising when BLE enabled if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) { - ChipLogError(Shell, "OpenBasicCommissioningWindow() failed"); + ChipLogError(AppServer, "OpenBasicCommissioningWindow() failed"); } - const int rc = Engine::Root().Init(); - +#if CONFIG_ENABLE_CHIP_SHELL || CONFIG_CHIP_LIB_SHELL + int rc = Engine::Root().Init(); if (rc != 0) { - ChipLogError(Shell, "Streamer initialization failed: %d", rc); - return rc; + ChipLogError(AppServer, "Streamer initialization failed: %d", rc); + return CHIP_ERROR_INTERNAL; } -#if CONFIG_ENABLE_CHIP_SHELL cmd_misc_init(); cmd_otcli_init(); cmd_ping_init(); @@ -96,9 +130,9 @@ int main() cmd_app_server_init(); #endif -#if CONFIG_ENABLE_CHIP_SHELL +#if CONFIG_ENABLE_CHIP_SHELL || CONFIG_CHIP_LIB_SHELL Engine::Root().RunMainLoop(); #endif - return 0; + return err; } diff --git a/examples/chef/nrfconnect/prj.conf b/examples/chef/nrfconnect/prj.conf index 2c47390feaa450..71679d01cbba43 100644 --- a/examples/chef/nrfconnect/prj.conf +++ b/examples/chef/nrfconnect/prj.conf @@ -1,5 +1,5 @@ # -# Copyright (c) 2020 Project CHIP Authors +# Copyright (c) 2022 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,29 +14,49 @@ # limitations under the License. # -# This sample uses sample-defaults.conf to set options common for all +CONFIG_CHIP=y +CONFIG_STD_CPP14=y + +# This sample uses Kconfig.defaults to set options common for all # samples. This file should contain only options specific for this sample # or overrides of default values. # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y +CONFIG_PWM=y # OpenThread configs +CONFIG_OPENTHREAD_THREAD_VERSION_1_2=y CONFIG_OPENTHREAD_NORDIC_LIBRARY_FTD=y -# Configure CHIP shell -CONFIG_CHIP_LIB_SHELL=y -CONFIG_OPENTHREAD_SHELL=n +# Default OpenThread network settings +CONFIG_OPENTHREAD_PANID=4660 +CONFIG_OPENTHREAD_CHANNEL=15 +CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread" +CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" -# Some shell commands require OpenThread FTD configuration -CONFIG_OPENTHREAD_MTD=n -CONFIG_OPENTHREAD_FTD=y +# Bluetooth overrides +CONFIG_BT_DEVICE_NAME="MatterLight" # Additional configs for debbugging experience. CONFIG_THREAD_NAME=y CONFIG_MPU_STACK_GUARD=y CONFIG_RESET_ON_FATAL_ERROR=n +# Disable Matter OTA DFU +CONFIG_CHIP_OTA_REQUESTOR=n + +# Disable QSPI NOR +CONFIG_CHIP_QSPI_NOR=n + # CHIP configuration CONFIG_CHIP_PROJECT_CONFIG="CHIPProjectConfig.h" -CONFIG_CHIP_NFC_COMMISSIONING=n +# 32773 == 0x8005 (example lighting-app) +CONFIG_CHIP_DEVICE_PRODUCT_ID=32773 + +# Enable CHIP pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Configure CHIP shell +CONFIG_CHIP_LIB_SHELL=y +CONFIG_OPENTHREAD_SHELL=n