From 9350b977fa99fc209222f04ce1e691d8e68d9a75 Mon Sep 17 00:00:00 2001 From: Chun-Chieh Li Date: Thu, 26 Dec 2024 17:36:14 +0800 Subject: [PATCH] Migrate to Mbed CE 1. Common change for migration to Mbed CE from Mbed CLI 1/2 (1) Remove *.lib originally for library import. Replace with git submodule. (2) Rename mbed_app.json/mbed_lib.json to mbed_app.json5/mbed_lib.json5 (3) Add/update CMakeLists.txt (4) Remove .mbedignore originally for Mbed CLI 1 (5) Update document 2. Support VS Code development 3. Temporary fix to build profile inconsistent with mbed-lora library build See: https://github.com/mbed-ce/mbed-os/issues/407 --- .gitignore | 4 + .vscode/settings.json | 5 + CMakeLists.txt | 65 +++++++++++++ Jenkinsfile | 158 -------------------------------- README.md | 102 ++++++++++++++------- cmake-variants.yaml | 73 +++++++++++++++ mbed-os.lib | 1 - mbed_app.json => mbed_app.json5 | 20 ---- 8 files changed, 215 insertions(+), 213 deletions(-) create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 CMakeLists.txt delete mode 100644 Jenkinsfile create mode 100644 cmake-variants.yaml delete mode 100644 mbed-os.lib rename mbed_app.json => mbed_app.json5 (85%) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57974bd --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.build +.mbed +projectfiles +*.py* diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..169f42e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cmake.buildDirectory": "${workspaceFolder}/build", + "cmake.generator": "Ninja", + "cmake.configureOnOpen": false +} diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..1dec65f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,65 @@ +# Copyright (c) 2022 ARM Limited. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.19) +cmake_policy(VERSION 3.19) + +set(MBED_OS_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mbed-os CACHE INTERNAL "") + +# Set default path for mbed_app.json5 (no force-write for override) +set(MBED_APP_JSON_PATH mbed_app.json5 CACHE INTERNAL "") + +# Set default path for custom_targets.json5 (no force-write for override) +set(CUSTOM_TARGETS_PATH custom_targets CACHE INTERNAL "") +set(CUSTOM_TARGETS_JSON_PATH ${CUSTOM_TARGETS_PATH}/custom_targets.json5 CACHE INTERNAL "") + +# Load Mbed CE toolchain file and basic build system +include(${MBED_OS_PATH}/tools/cmake/app.cmake) + +set(APP_PROJECT NUMAKER_MBED_CE_LORAWAN_EXAMPLE) +set(APP_TARGET NuMaker-mbed-ce-lorawan-example) + +# Set up project name +project(${APP_PROJECT}) + +# Add Nuvoton CMake list files to CMake default module path +# +# Normally, this is added in ${MBED_OS_PATH}, but ${CUSTOM_TARGETS_PATH} +# is in front and needs it. +list(APPEND CMAKE_MODULE_PATH + ${MBED_OS_PATH}/targets/TARGET_NUVOTON/scripts +) + +# Add Mbed OS library +add_subdirectory(${MBED_OS_PATH}) + +# User-provided MBEDTLS_USER_CONFIG_FILE for mbedtls +target_include_directories(mbed-mbedtls + PUBLIC + . +) + +add_executable(${APP_TARGET}) + +target_include_directories(${APP_TARGET} + PRIVATE + . +) + +target_sources(${APP_TARGET} + PRIVATE + main.cpp + trace_helper.cpp +) + +target_link_libraries(${APP_TARGET} + PRIVATE + mbed-os + mbed-lorawan +) + +# Must call this for each target to set up bin file creation, code upload, etc +mbed_set_post_build(${APP_TARGET}) + +# Make sure this is the last line of the top-level build script +mbed_finalize_build() diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index b7b8588..0000000 --- a/Jenkinsfile +++ /dev/null @@ -1,158 +0,0 @@ -properties ([[$class: 'ParametersDefinitionProperty', parameterDefinitions: [ - [$class: 'StringParameterDefinition', name: 'mbed_os_revision', defaultValue: '', description: 'Revision of mbed-os to build. To access mbed-os PR use format "pull/PR number/head"'], - [$class: 'BooleanParameterDefinition', name: 'regions_build_test', defaultValue: true, description: 'Test build all available regions'] - ]]]) - -library 'mbed-lib' - -if (env.MBED_OS_REVISION == null) { - echo 'First run in this branch, using default parameter values' - env.MBED_OS_REVISION = '' -} -if (env.MBED_OS_REVISION == '') { - echo 'Using mbed OS revision from mbed-os.lib' -} else { - echo "Using given mbed OS revision: ${env.MBED_OS_REVISION}" - if (env.MBED_OS_REVISION.matches('pull/\\d+/head')) { - echo "Revision is a Pull Request" - } -} - -// All available regions -def regions = [ - "\"0\"", "\"1\"", "\"2\"", "\"3\"", "\"4\"", "\"5\"", "\"6\"", "\"7\"", "\"8\"", - "\"EU868\"", "\"AS923\"", "\"AU915\"", "\"CN470\"", "\"CN779\"", "\"EU433\"", - "\"IN865\"", "\"KR920\"", "\"US915\"" -] - -// Supported targets -def targets = [ - "K64F", - "MTS_MDOT_F411RE", - "DISCO_L072CZ_LRWAN1" -] - -// Supported toolchains -def toolchains = [ - "ARM", - "GCC_ARM" -] - -def stepsForParallel = [:] - -// Jenkins pipeline does not support map.each, we need to use oldschool for loop -for (int i = 0; i < targets.size(); i++) { - for(int j = 0; j < toolchains.size(); j++) { - def target = targets.get(i) - def toolchain = toolchains.get(j) - - // Skip unwanted combination - if (target == "DISCO_L072CZ_LRWAN1" && toolchain == "GCC_ARM") { - continue - } - - def stepName = "${target} ${toolchain}" - - stepsForParallel[stepName] = buildStep(target, toolchain) - } -} - -def stepsForRegional = [:] - -if (params.regions_build_test == true) { - stepsForRegional["REGION BUILDER"] = build_regions(regions) -} - -timestamps { - parallel stepsForParallel - parallel stepsForRegional -} - -def buildStep(target, toolchain) { - return { - stage ("${target}_${toolchain}") { - node ("all-in-one-build-slave") { - deleteDir() - dir("mbed-os-example-lorawan") { - checkout scm - - // A workaround for mbed-cli caching issues - try { - execute("mbed deploy --protocol ssh") - } catch (err) { - echo "mbed deploy failed - retrying after 10s" - sleep(10) - execute("mbed deploy --protocol ssh") - } - - // Set mbed-os to revision received as parameter - if (env.MBED_OS_REVISION != '') { - dir("mbed-os") { - if (env.MBED_OS_REVISION.matches('pull/\\d+/head')) { - // Use mbed-os PR and switch to branch created - execute("git fetch origin ${env.MBED_OS_REVISION}:_PR_") - execute("git checkout _PR_") - } else { - execute("git checkout ${env.MBED_OS_REVISION}") - } - } - } - - // Adjust stack size and crystal values - if ("${target}" == "DISCO_L072CZ_LRWAN1") { - execute("sed -i 's/#define RCC_HSICALIBRATION_DEFAULT ((uint32_t)0x10)/#define RCC_HSICALIBRATION_DEFAULT ((uint32_t)0x13)/' \ - mbed-os/targets/TARGET_STM/TARGET_STM32L0/device/stm32l0xx_hal_rcc.h") - } - - execute("mbed compile --build out/${target}_${toolchain}/ -m ${target} -t ${toolchain} -c") - } - stash name: "${target}_${toolchain}", includes: '**/mbed-os-example-lorawan.bin' - archive '**/mbed-os-example-lorawan.bin' - step([$class: 'WsCleanup']) - } - } - } -} - -def build_regions(regions) { - return { - stage ("region_builder_K64F_GCC_ARM") { - node ("all-in-one-build-slave") { - deleteDir() - dir("mbed-os-example-lorawan") { - checkout scm - - // A workaround for mbed-cli caching issues - try { - execute("mbed deploy --protocol ssh") - } catch (err) { - echo "mbed deploy failed - retrying after 10s" - sleep(10) - execute("mbed deploy --protocol ssh") - } - - if (env.MBED_OS_REVISION != '') { - dir("mbed-os") { - if (env.MBED_OS_REVISION.matches('pull/\\d+/head')) { - execute("git fetch origin ${env.MBED_OS_REVISION}:_PR_") - execute("git checkout _PR_") - } else { - execute("git checkout ${env.MBED_OS_REVISION}") - } - } - } - //Initial sed to string format for find & replacing - execute("sed -i 's/\"lora.phy\": 0,/\"lora.phy\": \"0\",/' mbed_app.json") - //lora.phy 0 build tested above already - for (int i = 1; i < regions.size(); i++) { - def curr_region = regions.get(i) - def prev_region = regions.get(i-1) - execute("sed -i 's/\"lora.phy\": ${prev_region},/\"lora.phy\": ${curr_region},/' mbed_app.json") - echo "Building region: ${curr_region}" - execute("mbed compile -t GCC_ARM -m K64F") - } - } - } - } - } -} diff --git a/README.md b/README.md index c3e8d19..7709cbd 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,12 @@ ![](./resources/official_armmbed_example_badge.png) -# Example LoRaWAN application for Mbed-OS +# Example for LoRaWAN on Nuvoton's Mbed CE enabled boards -This is an example application based on `Mbed-OS` LoRaWAN protocol APIs. The Mbed-OS LoRaWAN stack implementation is compliant with LoRaWAN v1.0.2 specification. See this [link](https://os.mbed.com/blog/entry/Introducing-LoRaWAN-11-support/) for information on support for other LoRaWAN spec versions. This application can work with any Network Server if you have correct credentials for the said Network Server. +This is an example application based on `Mbed-OS` LoRaWAN protocol APIs. +The Mbed-OS LoRaWAN stack implementation is compliant with LoRaWAN v1.0.2 specification. +See this [link](https://os.mbed.com/blog/entry/Introducing-LoRaWAN-11-support/) for information on support for other LoRaWAN spec versions. This application can work with any Network Server if you have correct credentials for the said Network Server. + +Check out [Mbed CE](https://github.com/mbed-ce) +for details on Mbed OS community edition. ## Getting Started @@ -15,43 +20,46 @@ OR [Mbed Enabled LoRa Module](#module-support) -### Import the example application -For [Mbed Online Compiler](https://ide.mbed.com/compiler/) users: -- Select "Import", then search for "mbed-os-example-lorawan" from "Team mbed-os-examples". Or simply, import this repo by URL. +## Support development tools -- NOTE: Do NOT select "Update all libraries to latest revision" as this may cause breakage with a new lib version we have not tested. +Use cmake-based build system. +Check out [hello world example](https://github.com/mbed-ce/mbed-ce-hello-world) for getting started. -For [mbed-cli](https://github.com/ARMmbed/mbed-cli) users: -```sh -$ mbed import mbed-os-example-lorawan -$ cd mbed-os-example-lorawan +> **⚠️ Warning** +> +> Legacy development tools below are not supported anymore. +> - [Arm's Mbed Studio](https://os.mbed.com/docs/mbed-os/v6.15/build-tools/mbed-studio.html) +> - [Arm's Mbed CLI 2](https://os.mbed.com/docs/mbed-os/v6.15/build-tools/mbed-cli-2.html) +> - [Arm's Mbed CLI 1](https://os.mbed.com/docs/mbed-os/v6.15/tools/developing-mbed-cli.html) -#OR +For [VS Code development](https://github.com/mbed-ce/mbed-os/wiki/Project-Setup:-VS-Code) +or [OpenOCD as upload method](https://github.com/mbed-ce/mbed-os/wiki/Upload-Methods#openocd), +install below additionally: + +- [NuEclipse](https://github.com/OpenNuvoton/Nuvoton_Tools#numicro-software-development-tools): Nuvoton's fork of Eclipse +- Nuvoton forked OpenOCD: Shipped with NuEclipse installation package above. + Checking openocd version `openocd --version`, it should fix to `0.10.022`. -$ git clone git@github.com:ARMmbed/mbed-os-example-lorawan.git -$ cd mbed-os-example-lorawan -$ mbed deploy -``` ### Example configuration and radio selection Because of the pin differences between the SX126x and SX127x radios, example application configuration files are provided with the correct pin sets in the `config/` dir of this project. Please start by selecting the correct example configuration for your radio: -- For [Mbed Online Compiler](https://ide.mbed.com/compiler/) users, this can be done by simply replacing the contents of the `mbed_app.json` at the root of the project with the content of the correct example configuration in `config/` dir. +- For [Mbed Online Compiler](https://ide.mbed.com/compiler/) users, this can be done by simply replacing the contents of the `mbed_app.json5` at the root of the project with the content of the correct example configuration in `config/` dir. - For [mbed-cli](https://github.com/ARMmbed/mbed-cli) users, the config file can be specifed on the command line with the `--app-config` option (ie `--app-config config/SX12xx_example_config.json`) With the correct config file selected, the user can then provide a pin set for their target board in the `NC` fields at the top if it is different from the default targets listed. If your device is one of the LoRa modules supported by Mbed-OS, the pin set is already provided for the modules in the `target-overrides` field of the config file. For more information on supported modules, please refer to the [module support section](#module-support) ### Add network credentials -Open the file `mbed_app.json` in the root directory of your application. This file contains all the user specific configurations your application and the Mbed OS LoRaWAN stack need. Network credentials are typically provided by LoRa network provider. +Open the file `mbed_app.json5` in the root directory of your application. This file contains all the user specific configurations your application and the Mbed OS LoRaWAN stack need. Network credentials are typically provided by LoRa network provider. #### For OTAA Please add `Device EUI`, `Application EUI` and `Application Key` needed for Over-the-air-activation(OTAA). For example: -```json +```json5 "lora.device-eui": "{ YOUR_DEVICE_EUI }", "lora.application-eui": "{ YOUR_APPLICATION_EUI }", "lora.application-key": "{ YOUR_APPLICATION_KEY }" @@ -59,15 +67,15 @@ Please add `Device EUI`, `Application EUI` and `Application Key` needed for Over #### For ABP -For Activation-By-Personalization (ABP) connection method, modify the `mbed_app.json` to enable ABP. You can do it by simply turning off OTAA. For example: +For Activation-By-Personalization (ABP) connection method, modify the `mbed_app.json5` to enable ABP. You can do it by simply turning off OTAA. For example: -```json +```json5 "lora.over-the-air-activation": false, ``` In addition to that, you need to provide `Application Session Key`, `Network Session Key` and `Device Address`. For example: -```json +```json5 "lora.appskey": "{ YOUR_APPLICATION_SESSION_KEY }", "lora.nwkskey": "{ YOUR_NETWORK_SESSION_KEY }", "lora.device-address": " YOUR_DEVICE_ADDRESS_IN_HEX " @@ -118,22 +126,48 @@ Here is a list of boards and modules that have been tested by the community: - IMST iM880B (SX1272) - Embedded Planet Agora (SX1276) -## Compiling the application +## Developer guide -Use Mbed CLI commands to generate a binary for the application. -For example: +In the following, we take **NuMaker-IoT-M252** board as an example for Mbed CE support. -```sh -$ mbed compile -m YOUR_TARGET -t ARM -``` +### Hardware requirements + +- NuMaker-IoT-M252 board +- Host OS: Windows or others + +### Build the example + +1. Clone the example and navigate into it + ``` + $ git clone https://github.com/mbed-nuvoton/NuMaker-mbed-ce-lorawan-example + $ cd NuMaker-mbed-ce-lorawan-example + $ git checkout -f master + ``` + +1. Deploy necessary libraries + ``` + $ git submodule update --init + ``` + Or for fast install: + ``` + $ git submodule update --init --filter=blob:none + ``` + +1. Compile with cmake/ninja + ``` + $ mkdir build; cd build + $ cmake .. -GNinja -DCMAKE_BUILD_TYPE=Develop -DMBED_TARGET=NUMAKER_IOT_M252 + $ ninja + $ cd .. + ``` -## Running the application +### Flash the image -Drag and drop the application binary from `BUILD/YOUR_TARGET/ARM/mbed-os-example-lora.bin` to your Mbed enabled target hardware, which appears as a USB device on your host machine. +Flash by drag-n-drop built image `NuMaker-mbed-ce-lorawan-example.bin` or `NuMaker-mbed-ce-lorawan-example.hex` onto **NuMaker-IoT-M252** board -Attach a serial console emulator of your choice (for example, PuTTY, Minicom or screen) to your USB device. Set the baudrate to 115200 bit/s, and reset your board by pressing the reset button. +### Verify the result -You should see an output similar to this: +On host terminal (115200/8-N-1), you should see an output similar to this: ``` Mbed LoRaWANStack initialized @@ -155,9 +189,9 @@ Mbed LoRaWANStack initialized ``` ## [Optional] Adding trace library -To enable Mbed trace, add to your `mbed_app.json` the following fields: +To enable Mbed trace, add to your `mbed_app.json5` the following fields: -```json +```json5 "target_overrides": { "*": { "mbed-trace.enable": true @@ -172,7 +206,7 @@ The trace is disabled by default to save RAM and reduce main stack usage (see ch Using `Arm CC compiler` instead of `GCC` reduces `3K` of RAM. Currently the application takes about `15K` of static RAM with Arm CC, which spills over for the platforms with `20K` of RAM because you need to leave space, about `5K`, for dynamic allocation. So if you reduce the application stack size, you can barely fit into the 20K platforms. -For example, add the following into `config` section in your `mbed_app.json`: +For example, add the following into `config` section in your `mbed_app.json5`: ``` "main_stack_size": { diff --git a/cmake-variants.yaml b/cmake-variants.yaml new file mode 100644 index 0000000..3599b02 --- /dev/null +++ b/cmake-variants.yaml @@ -0,0 +1,73 @@ +buildType: + default: Develop + choices: + Develop: + short: Develop + long: Emit debug information but also optimize + buildType: Develop + Debug: + short: Debug + long: Emit debug information and don't optimize + buildType: Debug + Release: + short: Release + long: Optimize generated code + buildType: Release +board: + default: NUMAKER_IOT_M467 + choices: + NUMAKER_PFM_NANO130: + short: NUMAKER_PFM_NANO130 + settings: + MBED_TARGET: NUMAKER_PFM_NANO130 + UPLOAD_METHOD: OPENOCD + NUMAKER_PFM_NUC472: + short: NUMAKER_PFM_NUC472 + settings: + MBED_TARGET: NUMAKER_PFM_NUC472 + UPLOAD_METHOD: OPENOCD + NUMAKER_PFM_M453: + short: NUMAKER_PFM_M453 + settings: + MBED_TARGET: NUMAKER_PFM_M453 + UPLOAD_METHOD: OPENOCD + NUMAKER_PFM_M487: + short: NUMAKER_PFM_M487 + settings: + MBED_TARGET: NUMAKER_PFM_M487 + UPLOAD_METHOD: OPENOCD + NUMAKER_IOT_M487: + short: NUMAKER_IOT_M487 + settings: + MBED_TARGET: NUMAKER_IOT_M487 + UPLOAD_METHOD: OPENOCD + NUMAKER_M483KG: + short: NUMAKER_M483KG + settings: + MBED_TARGET: NUMAKER_M483KG + UPLOAD_METHOD: OPENOCD + NUMAKER_IOT_M467: + short: NUMAKER_IOT_M467 + settings: + MBED_TARGET: NUMAKER_IOT_M467 + UPLOAD_METHOD: OPENOCD + NUMAKER_IOT_M252: + short: NUMAKER_IOT_M252 + settings: + MBED_TARGET: NUMAKER_IOT_M252 + UPLOAD_METHOD: OPENOCD + NUMAKER_IOT_M263A: + short: NUMAKER_IOT_M263A + settings: + MBED_TARGET: NUMAKER_IOT_M263A + UPLOAD_METHOD: OPENOCD + NU_M2354: + short: NU_M2354 + settings: + MBED_TARGET: NU_M2354 + UPLOAD_METHOD: OPENOCD + NU_IOT_M2354: + short: NU_IOT_M2354 + settings: + MBED_TARGET: NU_IOT_M2354 + UPLOAD_METHOD: OPENOCD \ No newline at end of file diff --git a/mbed-os.lib b/mbed-os.lib deleted file mode 100644 index 2dd8afb..0000000 --- a/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os/#17dc3dc2e6e2817a8bd3df62f38583319f0e4fed \ No newline at end of file diff --git a/mbed_app.json b/mbed_app.json5 similarity index 85% rename from mbed_app.json rename to mbed_app.json5 index bbbd10b..a37ad18 100644 --- a/mbed_app.json +++ b/mbed_app.json5 @@ -103,26 +103,6 @@ "lora-ant-switch": "NC", "lora-pwr-amp-ctl": "NC", "lora-tcxo": "NC" - }, - "K64F": { - "lora-spi-mosi": "D11", - "lora-spi-miso": "D12", - "lora-spi-sclk": "D13", - "lora-cs": "D10", - "lora-reset": "A0", - "lora-dio0": "D2", - "lora-dio1": "D3", - "lora-dio2": "D4", - "lora-dio3": "D5", - "lora-dio4": "D8", - "lora-dio5": "D9", - "lora-rf-switch-ctl1": "NC", - "lora-rf-switch-ctl2": "NC", - "lora-txctl": "NC", - "lora-rxctl": "NC", - "lora-ant-switch": "A4", - "lora-pwr-amp-ctl": "NC", - "lora-tcxo": "NC" } }, "macros": ["MBEDTLS_USER_CONFIG_FILE=\"mbedtls_lora_config.h\""]