diff --git a/.github/workflows/build_zephyr.yml b/.github/workflows/build_zephyr.yml index f8781c2..b2bc91e 100644 --- a/.github/workflows/build_zephyr.yml +++ b/.github/workflows/build_zephyr.yml @@ -49,6 +49,15 @@ jobs: uses: actions/checkout@v4 with: path: app + + - name: Process Board name + id: nicename + shell: bash + run: | + BOARD_NICENAME=${{ inputs.BOARD }} + BOARD_NICENAME=${BOARD_NICENAME//\//_} + echo "BOARD_NICENAME=${BOARD_NICENAME}" >> $GITHUB_OUTPUT + - name: Setup West workspace run: | west init -l app @@ -60,23 +69,24 @@ jobs: - name: Build with West run: | - west build -p -b ${{ inputs.BOARD }} app + west build -p -b ${{ inputs.BOARD }} --sysbuild app - name: Prepare artifacts + shell: bash if: inputs.ARTIFACT == true && inputs.TAG != '' run: | - cd build/zephyr + cd build mkdir -p artifacts - mv merged.hex ./artifacts/golioth-${{ github.event.repository.name }}_${{ inputs.TAG }}_${{ inputs.BOARD }}_full.hex - mv app_update.bin ./artifacts/golioth-${{ github.event.repository.name }}_${{ inputs.TAG }}_${{ inputs.BOARD }}_update.bin - mv zephyr.elf ./artifacts/golioth-${{ github.event.repository.name }}_${{ inputs.TAG }}_${{ inputs.BOARD }}.elf + mv merged.hex ./artifacts/air-quality_${{ inputs.TAG }}_${{ steps.nicename.outputs.BOARD_NICENAME }}_full.hex + mv app/zephyr/zephyr.signed.bin ./artifacts/air-quality_${{ inputs.TAG }}_${{ steps.nicename.outputs.BOARD_NICENAME }}_update.bin + mv app/zephyr/zephyr.elf ./artifacts/air-quality_${{ inputs.TAG }}_${{ steps.nicename.outputs.BOARD_NICENAME }}.elf # Run IDs are unique per repo but are reused on re-runs - name: Save artifact if: inputs.ARTIFACT == true - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: build_artifacts_${{ github.run_id }} + name: build_artifacts_${{ github.run_id }}_${{ steps.nicename.outputs.BOARD_NICENAME }} path: | - build/zephyr/artifacts/* + build/artifacts/* diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ea9ce0d..7e3db5a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: ZEPHYR_SDK: [0.16.3] - BOARD: ["nrf9160dk_nrf9160_ns","aludel_mini_v1_sparkfun9160_ns"] + BOARD: ["nrf9160dk/nrf9160/ns","aludel_mini/nrf9160/ns","aludel_elixir/nrf9160/ns"] uses: ./.github/workflows/build_zephyr.yml with: @@ -36,10 +36,11 @@ jobs: uses: actions/checkout@v4 - name: Download artifact - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: - name: build_artifacts_${{ github.run_id }} + pattern: build_artifacts_* path: ~/artifacts + merge-multiple: true - name: Create Release manually with GH CLI run: gh release create --title ${{ inputs.version }} --draft ${{ inputs.version }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 788335a..b41af92 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,17 +1,30 @@ # Copyright (c) 2023 Golioth, Inc. # SPDX-License-Identifier: Apache-2.0 -name: Test firmware +name: Test firmware on: pull_request: push: + branches: [ main ] jobs: - test_build: + test_build_nrf9160dk: uses: ./.github/workflows/build_zephyr.yml with: ZEPHYR_SDK: 0.16.3 - BOARD: aludel_mini_v1_sparkfun9160_ns - ARTIFACT: false \ No newline at end of file + BOARD: nrf9160dk/nrf9160/ns + ARTIFACT: false + test_build_aludel_elixir: + uses: ./.github/workflows/build_zephyr.yml + with: + ZEPHYR_SDK: 0.16.3 + BOARD: aludel_elixir/nrf9160/ns + ARTIFACT: false + test_build_aludel_mini: + uses: ./.github/workflows/build_zephyr.yml + with: + ZEPHYR_SDK: 0.16.3 + BOARD: aludel_mini/nrf9160/ns + ARTIFACT: false diff --git a/README.rst b/README.rst index 377f3b9..1012b96 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ .. - Copyright (c) 2022-2023 Golioth, Inc. + Copyright (c) 2024 Golioth, Inc. SPDX-License-Identifier: Apache-2.0 Air Quality Monitor Reference Design @@ -80,14 +80,95 @@ Specifically, the following environmental parameters can be monitored: * 🌡️ Temperature (°C) * 💨 Pressure (kPa) -The sensor values are uploaded to the LightDB stream database in the Golioth -Cloud. The sensor sampling frequency and other sensor parameters are remotely -configurable via the Golioth Settings service. +Local set up +************ + +.. pull-quote:: + [!IMPORTANT] + + Do not clone this repo using git. Zephyr's ``west`` meta tool should be used to + set up your local workspace. + +Install the Python virtual environment (recommended) +==================================================== + +.. code-block:: shell + + cd ~ + mkdir golioth-reference-design-air-quality + python -m venv golioth-reference-design-air-quality/.venv + source golioth-reference-design-air-quality/.venv/bin/activate + pip install wheel west + +Use ``west`` to initialize and install +====================================== + +.. code-block:: shell + + cd ~/golioth-reference-design-air-quality + west init -m git@github.com:golioth/reference-design-air-quality.git . + west update + west zephyr-export + pip install -r deps/zephyr/scripts/requirements.txt + +Building the application +************************ + +Build the Zephyr sample application for the `Nordic nRF9160 DK`_ +(``nrf9160dk_nrf9160_ns``) from the top level of your project. After a +successful build you will see a new ``build`` directory. Note that any changes +(and git commits) to the project itself will be inside the ``app`` folder. The +``build`` and ``deps`` directories being one level higher prevents the repo from +cataloging all of the changes to the dependencies and the build (so no +``.gitignore`` is needed). + +Prior to building, update ``VERSION`` file to reflect the firmware version number you want to assign +to this build. Then run the following commands to build and program the firmware onto the device. -Supported Golioth Zephyr SDK Features -===================================== -This firmware implements the following features from the Golioth Zephyr SDK: +.. pull-quote:: + [!IMPORTANT] + + You must perform a pristine build (use ``-p`` or remove the ``build`` directory) + after changing the firmware version number in the ``VERSION`` file for the change to take effect. + +.. code-block:: text + + $ (.venv) west build -p -b nrf9160dk/nrf9160/ns --sysbuild app + $ (.venv) west flash + +Configure PSK-ID and PSK using the device shell based on your Golioth +credentials and reboot: + +.. code-block:: text + + uart:~$ settings set golioth/psk-id + uart:~$ settings set golioth/psk + uart:~$ kernel reboot cold + +Add Pipeline to Golioth +*********************** + +Golioth uses `Pipelines`_ to route stream data. This gives you flexibility to change your data +routing without requiring updated device firmware. + +Whenever sending stream data, you must enable a pipeline in your Golioth project to configure how +that data is handled. Add the contents of ``pipelines/cbor-to-lightdb.yml`` as a new pipeline as +follows (note that this is the default pipeline for new projects and may already be present): + + 1. Navigate to your project on the Golioth web console. + 2. Select ``Pipelines`` from the left sidebar and click the ``Create`` button. + 3. Give your new pipeline a name and paste the pipeline configuration into the editor. + 4. Click the toggle in the bottom right to enable the pipeline and then click ``Create``. + +All data streamed to Golioth in CBOR format will now be routed to LightDB Stream and may be viewed +using the web console. You may change this behavior at any time without updating firmware simply by +editing this pipeline entry. + +Golioth Features +**************** + +This app implements: - `Device Settings Service `_ - `LightDB State Client `_ @@ -96,8 +177,8 @@ This firmware implements the following features from the Golioth Zephyr SDK: - `Over-the-Air (OTA) Firmware Upgrade `_ - `Remote Procedure Call (RPC) `_ -Device Settings Service ------------------------ +Settings Service +================ The following settings can be set in the Device Settings menu of the `Golioth Console`_. @@ -141,7 +222,7 @@ Console`_. Default value is ``604800`` seconds (168 hours or 1 week). LightDB Stream Service ----------------------- +====================== Sensor data is periodically sent to the following ``sensor/*`` endpoints of the LightDB Stream service: @@ -168,7 +249,7 @@ level readings are periodically sent to the following ``battery/*`` endpoints: * ``battery/batt_lvl``: Battery Level (%) LightDB State Service ---------------------- +===================== The concept of Digital Twin is demonstrated with the LightDB State ``example_int0`` and ``example_int1`` variables that are members of the @@ -184,7 +265,7 @@ The concept of Digital Twin is demonstrated with the LightDB State the ``state`` endpoints. Remote Procedure Call (RPC) Service ------------------------------------ +=================================== The following RPCs can be initiated in the Remote Procedure Call menu of the `Golioth Console`_. @@ -214,111 +295,54 @@ The following RPCs can be initiated in the Remote Procedure Call menu of the ``reset_pm_sensor`` Reset the SPS30 particulate matter sensor. -Building the firmware -********************* - -The firmware build instructions below assume you have already set up a Zephyr -development environment and have some basic familiarity with building firmware -using the Zephyr Real Time Operating System (RTOS). +Hardware Variations +******************* -If you're brand new to building firmware with Zephyr, you will need to follow -the `Zephyr Getting Started Guide`_ to install the Zephyr SDK and related -dependencies. +This reference design may be built for a variety of different boards. -We also provide free online `Developer Training`_ for Zephyr at: +Prior to building, update ``VERSION`` file to reflect the firmware version number you want to assign +to this build. Then run the following commands to build and program the firmware onto the device. -https://training.golioth.io/docs/zephyr-training - -.. pull-quote:: - [!IMPORTANT] +Golioth Aludel Mini +=================== - Do not clone this repo using git. Zephyr's ``west`` meta-tool should be used - to set up your local workspace. - -Create a Python virtual environment (recommended) -================================================= - -.. code-block:: shell - - cd ~ - mkdir golioth-reference-design-air-quality - python -m venv golioth-reference-design-air-quality/.venv - source golioth-reference-design-air-quality/.venv/bin/activate - -Install ``west`` meta-tool -========================== - -.. code-block:: shell - - pip install wheel west - -Use ``west`` to initialize the workspace and install dependencies -================================================================= - -.. code-block:: shell - - cd ~/golioth-reference-design-air-quality - west init -m git@github.com:golioth/reference-design-air-quality.git . - west update - west zephyr-export - pip install -r deps/zephyr/scripts/requirements.txt - -Build the firmware -================== - -Build the Zephyr firmware from the top-level workspace of your project. After a -successful build you will see a new ``build/`` directory. - -Note that this git repository was cloned into the ``app`` folder, so any changes -you make to the application itself should be committed inside this repository. -The ``build`` and ``deps`` directories in the root of the workspace are managed -outside of this git repository by the ``west`` meta-tool. - -Prior to building, update ``CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION`` in the -``prj.conf`` file to reflect the firmware version number you want to assign to -this build. - -.. pull-quote:: - [!IMPORTANT] - - When running the commands below, make sure to replace the placeholder - ```` with the actual Zephyr board from the table above - that matches your follow-along hardware. +This reference design may be built for the Golioth Aludel Mini board. .. code-block:: text - $ (.venv) west build -p -b app + $ (.venv) west build -p -b aludel_mini/nrf9160/ns --sysbuild app + $ (.venv) west flash + +Golioth Aludel Elixir +===================== -For example, to build firmware for the `Nordic nRF9160 DK`_-based follow-along -hardware: +This reference design may be built for the Golioth Aludel Elixir board. By default this will build +for the latest hardware revision of this board. .. code-block:: text - $ (.venv) west build -p -b nrf9160dk_nrf9160_ns app + $ (.venv) west build -p -b aludel_elixir/nrf9160/ns --sysbuild app + $ (.venv) west flash -Flash the firmware -================== +To build for a specific board revision (e.g. Rev A) add the revision suffix ``@``. .. code-block:: text + $ (.venv) west build -p -b aludel_elixir@A/nrf9160/ns --sysbuild app $ (.venv) west flash -Provision the device -==================== - -In order for the device to securely authenticate with the Golioth Cloud, we need -to provision the device with a pre-shared key (PSK). This key will persist -across reboots and only needs to be set once after the device firmware has been -programmed. In addition, flashing new firmware images with ``west flash`` should -not erase these stored settings unless the entire device flash is erased. +OTA Firmware Update +******************* -Configure the PSK-ID and PSK using the device UART shell and reboot the device: +This application includes the ability to perform Over-the-Air (OTA) firmware updates: -.. code-block:: text +1. Update the version number in the `VERSION` file and perform a pristine (important) build to + incorporate the version change. +2. Upload the `build/app/zephyr/zephyr.signed.bin` file as an artifact for your Golioth project + using `main` as the package name. +3. Create and roll out a release based on this artifact. - uart:~$ settings set golioth/psk-id - uart:~$ settings set golioth/psk - uart:~$ kernel reboot cold +Visit `the Golioth Docs OTA Firmware Upgrade page`_ for more info. External Libraries ****************** @@ -334,40 +358,10 @@ from ``west.yml`` and remove the includes/function calls from the C code. * `zephyr-network-info`_ is a helper library for querying, formatting, and returning network connection information via Zephyr log or Golioth RPC -Pulling in updates from the Reference Design Template -***************************************************** - -This reference design was forked from the `Reference Design Template`_ repo. We -recommend the following workflow to pull in future changes: - -* Setup - - * Create a ``template`` remote based on the Reference Design Template - repository - -* Merge in template changes - - * Fetch template changes and tags - * Merge template release tag into your ``main`` (or other branch) - * Resolve merge conflicts (if any) and commit to your repository - -.. code-block:: shell - - # Setup - git remote add template https://github.com/golioth/reference-design-template.git - git fetch template --tags - - # Merge in template changes - git fetch template --tags - git checkout your_local_branch - git merge template_v1.0.0 - - # Resolve merge conflicts if necessary - git add resolved_files - git commit - .. _Golioth Console: https://console.golioth.io .. _Nordic nRF9160 DK: https://www.nordicsemi.com/Products/Development-hardware/nrf9160-dk +.. _Pipelines: https://docs.golioth.io/data-routing +.. _the Golioth Docs OTA Firmware Upgrade page: https://docs.golioth.io/firmware/golioth-firmware-sdk/firmware-upgrade/firmware-upgrade .. _golioth-zephyr-boards: https://github.com/golioth/golioth-zephyr-boards .. _libostentus: https://github.com/golioth/libostentus .. _MikroE Arduino UNO click shield: https://www.mikroe.com/arduino-uno-click-shield @@ -380,4 +374,5 @@ recommend the following workflow to pull in future changes: .. _Zephyr Getting Started Guide: https://docs.zephyrproject.org/latest/develop/getting_started/ .. _Developer Training: https://training.golioth.io .. _SemVer: https://semver.org +.. _the Golioth Docs OTA Firmware Upgrade page: https://docs.golioth.io/firmware/golioth-firmware-sdk/firmware-upgrade/firmware-upgrade .. _zephyr-network-info: https://github.com/golioth/zephyr-network-info diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..b0f6f99 --- /dev/null +++ b/VERSION @@ -0,0 +1,5 @@ +VERSION_MAJOR = 2 +VERSION_MINOR = 4 +PATCHLEVEL = 1 +VERSION_TWEAK = 0 +EXTRAVERSION = diff --git a/boards/aludel_elixir_ns.conf b/boards/aludel_elixir_ns.conf index bf0db0d..3e404f6 100644 --- a/boards/aludel_elixir_ns.conf +++ b/boards/aludel_elixir_ns.conf @@ -18,11 +18,11 @@ CONFIG_NET_SOCKETS_TLS_PRIORITY=35 # Modem library CONFIG_NRF_MODEM_LIB=y -CONFIG_NRF_MODEM_LIB_ON_FAULT_APPLICATION_SPECIFIC=y # LTE connectivity with network connection manager -CONFIG_LTE_CONNECTIVITY=y -CONFIG_LTE_CONNECTIVITY_AUTO_CONNECT=n +CONFIG_NRF_MODEM_LIB_NET_IF=y +CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_START=y +CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_CONNECT=n CONFIG_NET_CONNECTION_MANAGER=y CONFIG_NET_CONNECTION_MANAGER_MONITOR_STACK_SIZE=1024 @@ -41,3 +41,5 @@ CONFIG_BOOTLOADER_MCUBOOT=y # Use Golioth Ostentus Faceplate CONFIG_LIB_OSTENTUS=y + +CONFIG_REGULATOR=y diff --git a/boards/aludel_elixir_ns.overlay b/boards/aludel_elixir_ns.overlay index 1d016e8..034dd2f 100644 --- a/boards/aludel_elixir_ns.overlay +++ b/boards/aludel_elixir_ns.overlay @@ -1,21 +1,18 @@ -/* - * Copyright (c) 2024 Golioth, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - / { aliases { sensirion-hal-i2c = &mikrobus_i2c; }; }; -&qwiic_i2c { - status = "okay"; -}; - &mikrobus_i2c { - status = "okay"; + /* Needed for I2C writes used by libostentus */ + zephyr,concat-buf-size = <48>; + + ostentus@12 { + status = "okay"; + compatible = "golioth,ostentus"; + reg = <0x12>; + }; /* SPS30 max clock frequency is 100 kbit/s */ clock-frequency = ; diff --git a/boards/aludel_mini_v1_sparkfun9160_ns.conf b/boards/aludel_mini_nrf9160_ns.conf similarity index 84% rename from boards/aludel_mini_v1_sparkfun9160_ns.conf rename to boards/aludel_mini_nrf9160_ns.conf index 103a7bd..a835f79 100644 --- a/boards/aludel_mini_v1_sparkfun9160_ns.conf +++ b/boards/aludel_mini_nrf9160_ns.conf @@ -17,11 +17,11 @@ CONFIG_NET_SOCKETS_TLS_PRIORITY=35 # Modem library CONFIG_NRF_MODEM_LIB=y -CONFIG_NRF_MODEM_LIB_ON_FAULT_APPLICATION_SPECIFIC=y # LTE connectivity with network connection manager -CONFIG_LTE_CONNECTIVITY=y -CONFIG_LTE_CONNECTIVITY_AUTO_CONNECT=n +CONFIG_NRF_MODEM_LIB_NET_IF=y +CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_START=y +CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_CONNECT=n CONFIG_NET_CONNECTION_MANAGER=y CONFIG_NET_CONNECTION_MANAGER_MONITOR_STACK_SIZE=1024 @@ -40,6 +40,3 @@ CONFIG_MODEM_INFO=y # Generate MCUboot compatible images CONFIG_BOOTLOADER_MCUBOOT=y - -# Use Golioth Ostentus Faceplate -CONFIG_LIB_OSTENTUS=y diff --git a/boards/aludel_mini_v1_sparkfun9160_ns.overlay b/boards/aludel_mini_nrf9160_ns.overlay similarity index 58% rename from boards/aludel_mini_v1_sparkfun9160_ns.overlay rename to boards/aludel_mini_nrf9160_ns.overlay index 0c2b6d6..034dd2f 100644 --- a/boards/aludel_mini_v1_sparkfun9160_ns.overlay +++ b/boards/aludel_mini_nrf9160_ns.overlay @@ -1,9 +1,3 @@ -/* - * Copyright (c) 2023 Golioth, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - / { aliases { sensirion-hal-i2c = &mikrobus_i2c; @@ -11,7 +5,14 @@ }; &mikrobus_i2c { - status = "okay"; + /* Needed for I2C writes used by libostentus */ + zephyr,concat-buf-size = <48>; + + ostentus@12 { + status = "okay"; + compatible = "golioth,ostentus"; + reg = <0x12>; + }; /* SPS30 max clock frequency is 100 kbit/s */ clock-frequency = ; diff --git a/boards/nrf9160dk_nrf9160_ns.conf b/boards/nrf9160dk_nrf9160_ns.conf index 4c3c4da..9398b57 100644 --- a/boards/nrf9160dk_nrf9160_ns.conf +++ b/boards/nrf9160dk_nrf9160_ns.conf @@ -17,11 +17,11 @@ CONFIG_NET_SOCKETS_TLS_PRIORITY=35 # Modem library CONFIG_NRF_MODEM_LIB=y -CONFIG_NRF_MODEM_LIB_ON_FAULT_APPLICATION_SPECIFIC=y # LTE connectivity with network connection manager -CONFIG_LTE_CONNECTIVITY=y -CONFIG_LTE_CONNECTIVITY_AUTO_CONNECT=n +CONFIG_NRF_MODEM_LIB_NET_IF=y +CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_START=y +CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_CONNECT=n CONFIG_NET_CONNECTION_MANAGER=y CONFIG_NET_CONNECTION_MANAGER_MONITOR_STACK_SIZE=1024 @@ -32,6 +32,12 @@ CONFIG_GOLIOTH_SAMPLE_NRF91_LTE_MONITOR=y CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED=n CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED=n +# MbedTLS configuration to support p-384 curve. These options +# enable using the MbedTLS built-in support for operations not +# supported by the default nRF Oberon crypto backend +CONFIG_NORDIC_SECURITY_BACKEND=n +CONFIG_MBEDTLS_LEGACY_CRYPTO_C=y + # Add Network Info Support CONFIG_MODEM_INFO=y diff --git a/boards/nrf9160dk_nrf9160_ns.overlay b/boards/nrf9160dk_nrf9160_ns.overlay index 69d7fe8..d456472 100644 --- a/boards/nrf9160dk_nrf9160_ns.overlay +++ b/boards/nrf9160dk_nrf9160_ns.overlay @@ -7,13 +7,11 @@ / { aliases { golioth-led = &led2; - sensirion-hal-i2c = &mikrobus_i2c; + sensirion-hal-i2c = &arduino_i2c; }; }; -&mikrobus_i2c { - status = "okay"; - +&arduino_i2c { /* SPS30 max clock frequency is 100 kbit/s */ clock-frequency = ; diff --git a/pipelines/cbor-to-lightdb.yml b/pipelines/cbor-to-lightdb.yml new file mode 100644 index 0000000..6279576 --- /dev/null +++ b/pipelines/cbor-to-lightdb.yml @@ -0,0 +1,11 @@ +filter: + path: "*" + content_type: application/cbor +steps: + - name: step-0 + transformer: + type: cbor-to-json + version: v1 + destination: + type: lightdb-stream + version: v1 diff --git a/pm_static.yml b/pm_static.yml new file mode 100644 index 0000000..86793bb --- /dev/null +++ b/pm_static.yml @@ -0,0 +1,214 @@ +EMPTY_0: + address: 0xc000 + end_address: 0x10000 + placement: + before: + - mcuboot_pad + region: flash_primary + size: 0x4000 +EMPTY_1: + address: 0xfa000 + end_address: 0x100000 + placement: + after: + - settings_storage + region: flash_primary + size: 0x6000 +EMPTY_2: + address: 0xf0000 + end_address: 0xf8000 + placement: + after: + - mcuboot_secondary + region: flash_primary + size: 0x8000 +app: + address: 0x18000 + end_address: 0x80000 + region: flash_primary + size: 0x68000 +mcuboot: + address: 0x0 + end_address: 0xc000 + placement: + before: + - mcuboot_primary + region: flash_primary + size: 0xc000 +mcuboot_pad: + address: 0x10000 + end_address: 0x10200 + placement: + align: + start: 0x8000 + before: + - mcuboot_primary_app + region: flash_primary + size: 0x200 +mcuboot_primary: + address: 0x10000 + end_address: 0x80000 + orig_span: &id001 + - app + - tfm + - mcuboot_pad + region: flash_primary + sharers: 0x1 + size: 0x70000 + span: *id001 +mcuboot_primary_app: + address: 0x10200 + end_address: 0x80000 + orig_span: &id002 + - app + - tfm + region: flash_primary + size: 0x6fe00 + span: *id002 +mcuboot_secondary: + address: 0x80000 + end_address: 0xf0000 + placement: + after: + - mcuboot_primary + align: + start: 0x8000 + region: flash_primary + share_size: + - mcuboot_primary + size: 0x70000 +mcuboot_sram: + address: 0x20000000 + end_address: 0x20008000 + orig_span: &id003 + - tfm_sram + region: sram_primary + size: 0x8000 + span: *id003 +nonsecure_storage: + address: 0xf8000 + end_address: 0xfa000 + orig_span: &id004 + - settings_storage + region: flash_primary + size: 0x2000 + span: *id004 +nrf_modem_lib_ctrl: + address: 0x20008000 + end_address: 0x200084e8 + inside: + - sram_nonsecure + placement: + after: + - tfm_sram + - start + region: sram_primary + size: 0x4e8 +nrf_modem_lib_rx: + address: 0x2000a568 + end_address: 0x2000c568 + inside: + - sram_nonsecure + placement: + after: + - nrf_modem_lib_tx + region: sram_primary + size: 0x2000 +nrf_modem_lib_sram: + address: 0x20008000 + end_address: 0x2000c568 + orig_span: &id005 + - nrf_modem_lib_ctrl + - nrf_modem_lib_tx + - nrf_modem_lib_rx + region: sram_primary + size: 0x4568 + span: *id005 +nrf_modem_lib_tx: + address: 0x200084e8 + end_address: 0x2000a568 + inside: + - sram_nonsecure + placement: + after: + - nrf_modem_lib_ctrl + region: sram_primary + size: 0x2080 +otp: + address: 0xff8108 + end_address: 0xff83fc + region: otp + size: 0x2f4 +settings_storage: + address: 0xf8000 + end_address: 0xfa000 + inside: + - nonsecure_storage + placement: + align: + start: 0x8000 + before: + - end + region: flash_primary + size: 0x2000 +sram_nonsecure: + address: 0x20008000 + end_address: 0x20040000 + orig_span: &id006 + - sram_primary + - nrf_modem_lib_ctrl + - nrf_modem_lib_tx + - nrf_modem_lib_rx + region: sram_primary + size: 0x38000 + span: *id006 +sram_primary: + address: 0x2000c568 + end_address: 0x20040000 + region: sram_primary + size: 0x33a98 +sram_secure: + address: 0x20000000 + end_address: 0x20008000 + orig_span: &id007 + - tfm_sram + region: sram_primary + size: 0x8000 + span: *id007 +tfm: + address: 0x10200 + end_address: 0x18000 + inside: + - mcuboot_primary_app + placement: + before: + - app + region: flash_primary + size: 0x7e00 +tfm_nonsecure: + address: 0x18000 + end_address: 0x80000 + orig_span: &id008 + - app + region: flash_primary + size: 0x68000 + span: *id008 +tfm_secure: + address: 0x10000 + end_address: 0x18000 + orig_span: &id009 + - mcuboot_pad + - tfm + region: flash_primary + size: 0x8000 + span: *id009 +tfm_sram: + address: 0x20000000 + end_address: 0x20008000 + inside: + - sram_secure + placement: + after: + - start + region: sram_primary + size: 0x8000 diff --git a/prj.conf b/prj.conf index 93a2ea9..9c505ac 100644 --- a/prj.conf +++ b/prj.conf @@ -53,7 +53,7 @@ CONFIG_REBOOT=y # The rest of the runtime credentials config CONFIG_SETTINGS=y CONFIG_SETTINGS_RUNTIME=y -CONFIG_GOLIOTH_SAMPLE_PSK_SETTINGS=y +CONFIG_GOLIOTH_SAMPLE_SETTINGS=y CONFIG_GOLIOTH_SAMPLE_SETTINGS_AUTOLOAD=y CONFIG_GOLIOTH_SAMPLE_SETTINGS_SHELL=y @@ -64,6 +64,3 @@ CONFIG_NETWORK_INFO=y CONFIG_GOLIOTH_RPC_MAX_RESPONSE_LEN=512 CONFIG_I2C=y CONFIG_SENSOR=y - -# Firmware version used in DFU process -CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION="1.2.0" diff --git a/src/app_rpc.c b/src/app_rpc.c index 0e66b7c..25afe8e 100644 --- a/src/app_rpc.c +++ b/src/app_rpc.c @@ -5,7 +5,6 @@ */ #include -#include LOG_MODULE_REGISTER(app_rpc, LOG_LEVEL_DBG); #include diff --git a/src/app_sensors.c b/src/app_sensors.c index 6d21221..75c8e74 100644 --- a/src/app_sensors.c +++ b/src/app_sensors.c @@ -9,6 +9,7 @@ LOG_MODULE_REGISTER(app_sensors, LOG_LEVEL_DBG); #include #include +#include #include #include #include @@ -20,6 +21,7 @@ LOG_MODULE_REGISTER(app_sensors, LOG_LEVEL_DBG); #ifdef CONFIG_LIB_OSTENTUS #include +static const struct device *o_dev = DEVICE_DT_GET_ANY(golioth_ostentus); #endif #ifdef CONFIG_ALUDEL_BATTERY_MONITOR #include "battery_monitor/battery.h" @@ -84,11 +86,18 @@ void app_sensors_read_and_stream(void) LOG_DBG("Collecting battery measurements..."); + /* Golioth custom hardware for demos */ IF_ENABLED(CONFIG_ALUDEL_BATTERY_MONITOR, ( read_and_report_battery(client); IF_ENABLED(CONFIG_LIB_OSTENTUS, ( - slide_set(BATTERY_V, get_batt_v_str(), strlen(get_batt_v_str())); - slide_set(BATTERY_LVL, get_batt_lvl_str(), strlen(get_batt_lvl_str())); + ostentus_slide_set(o_dev, + BATTERY_V, + get_batt_v_str(), + strlen(get_batt_v_str())); + ostentus_slide_set(o_dev, + BATTERY_LVL, + get_batt_lvl_str(), + strlen(get_batt_lvl_str())); )); )); @@ -150,28 +159,29 @@ void app_sensors_read_and_stream(void) LOG_WRN("Device is not connected to Golioth, unable to send sensor data"); } + /* Golioth custom hardware for demos */ IF_ENABLED(CONFIG_LIB_OSTENTUS, ( /* Update slide values on Ostentus * -values should be sent as strings * -use the enum from app_sensors.h for slide key values */ snprintk(json_buf, sizeof(json_buf), "%.2f °C", sensor_value_to_double(&bme280_sm.temperature)); - slide_set(TEMPERATURE, json_buf, strlen(json_buf)); + ostentus_slide_set(o_dev, TEMPERATURE, json_buf, strlen(json_buf)); snprintk(json_buf, sizeof(json_buf), "%.2f kPa", sensor_value_to_double(&bme280_sm.pressure)); - slide_set(PRESSURE, json_buf, strlen(json_buf)); + ostentus_slide_set(o_dev, PRESSURE, json_buf, strlen(json_buf)); snprintk(json_buf, sizeof(json_buf), "%.2f %%RH", sensor_value_to_double(&bme280_sm.humidity)); - slide_set(HUMIDITY, json_buf, strlen(json_buf)); + ostentus_slide_set(o_dev, HUMIDITY, json_buf, strlen(json_buf)); snprintk(json_buf, sizeof(json_buf), "%u ppm", scd4x_sm.co2); - slide_set(CO2, json_buf, strlen(json_buf)); + ostentus_slide_set(o_dev, CO2, json_buf, strlen(json_buf)); snprintk(json_buf, sizeof(json_buf), "%d ug/m^3", sps30_sm.mc_2p5.val1); - slide_set(PM2P5, json_buf, strlen(json_buf)); + ostentus_slide_set(o_dev, PM2P5, json_buf, strlen(json_buf)); snprintk(json_buf, sizeof(json_buf), "%d ug/m^3", sps30_sm.mc_10p0.val1); - slide_set(PM10P0, json_buf, strlen(json_buf)); + ostentus_slide_set(o_dev, PM10P0, json_buf, strlen(json_buf)); )); } diff --git a/src/app_state.c b/src/app_state.c index 2a64b36..33b236a 100644 --- a/src/app_state.c +++ b/src/app_state.c @@ -171,8 +171,11 @@ int app_state_observe(struct golioth_client *state_client) client = state_client; - err = golioth_lightdb_observe_async(client, APP_STATE_DESIRED_ENDP, - app_state_desired_handler, NULL); + err = golioth_lightdb_observe_async(client, + APP_STATE_DESIRED_ENDP, + GOLIOTH_CONTENT_TYPE_JSON, + app_state_desired_handler, + NULL); if (err) { LOG_WRN("failed to observe lightdb path: %d", err); return err; diff --git a/src/main.c b/src/main.c index f09135e..aa6d519 100644 --- a/src/main.c +++ b/src/main.c @@ -8,6 +8,7 @@ #include LOG_MODULE_REGISTER(golioth_air_quality, LOG_LEVEL_DBG); +#include #include "app_rpc.h" #include "app_settings.h" #include "app_state.h" @@ -25,6 +26,8 @@ LOG_MODULE_REGISTER(golioth_air_quality, LOG_LEVEL_DBG); #endif #ifdef CONFIG_LIB_OSTENTUS #include +#include +static const struct device *o_dev = DEVICE_DT_GET_ANY(golioth_ostentus); #endif #ifdef CONFIG_ALUDEL_BATTERY_MONITOR #include "battery_monitor/battery.h" @@ -36,8 +39,9 @@ LOG_MODULE_REGISTER(golioth_air_quality, LOG_LEVEL_DBG); #include #endif -/* Current firmware version; update in prj.conf or via build argument */ -static const char *_current_version = CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION; +/* Current firmware version; update in VERSION */ +static const char *_current_version = + STRINGIFY(APP_VERSION_MAJOR) "." STRINGIFY(APP_VERSION_MINOR) "." STRINGIFY(APP_PATCHLEVEL); static struct golioth_client *client; K_SEM_DEFINE(connected, 0, 1); @@ -109,7 +113,7 @@ static void lte_handler(const struct lte_lc_evt *const evt) (evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_ROAMING)) { /* Change the state of the Internet LED on Ostentus */ - IF_ENABLED(CONFIG_LIB_OSTENTUS, (led_internet_set(1);)); + IF_ENABLED(CONFIG_LIB_OSTENTUS, (ostentus_led_internet_set(o_dev, 1);)); if (!client) { /* Create and start a Golioth Client */ @@ -157,7 +161,7 @@ void golioth_connection_led_set(uint8_t state) gpio_pin_set_dt(&golioth_led, pin_state); #endif /* DT_NODE_EXISTS(DT_ALIAS(golioth_led)) */ /* Change the state of the Golioth LED on Ostentus */ - IF_ENABLED(CONFIG_LIB_OSTENTUS, (led_golioth_set(pin_state);)); + IF_ENABLED(CONFIG_LIB_OSTENTUS, (ostentus_led_golioth_set(o_dev, pin_state);)); } int main(void) @@ -169,16 +173,26 @@ int main(void) LOG_DBG("Started air quality monitor app"); - LOG_INF("Firmware version: %s", CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION); + LOG_INF("Firmware version: %s", _current_version); IF_ENABLED(CONFIG_MODEM_INFO, (log_modem_firmware_version();)); IF_ENABLED(CONFIG_LIB_OSTENTUS, ( - /* Clear Ostentus memory */ - clear_memory(); + /* Reset Ostentus and pause for reboot */ + ostentus_reset(o_dev); + k_msleep(300); + + /* Read firmware version from faceplate */ + char *o_version = (char *)calloc(32, sizeof(char)); + + ostentus_version_get(o_dev, o_version, 32); + LOG_INF("Ostentus reports firmware version: %s", o_version); + free(o_version); + /* Update Ostentus LEDS using bitmask (Power On and Battery) */ - led_bitmask(LED_POW | LED_BAT); + ostentus_led_bitmask(o_dev, LED_POW | LED_BAT); + /* Show Golioth Logo on Ostentus ePaper screen */ - show_splash(); + ostentus_show_splash(o_dev); )); /* Get system thread id so loop delay change event can wake main */ @@ -201,7 +215,7 @@ int main(void) */ LOG_INF("Connecting to LTE, this may take some time..."); - lte_lc_init_and_connect_async(lte_handler); + lte_lc_connect_async(lte_handler); #else /* If nRF9160 is not used, start the Golioth Client and block until connected */ @@ -242,29 +256,38 @@ int main(void) * - use the enum in app_sensors.h to add new keys * - values are updated using these keys (see app_sensors.c) */ - slide_add(CO2, LABEL_CO2, strlen(LABEL_CO2)); - slide_add(PM2P5, LABEL_PM2P5, strlen(LABEL_PM2P5)); - slide_add(PM10P0, LABEL_PM10P0, strlen(LABEL_PM10P0)); - slide_add(TEMPERATURE, LABEL_TEMPERATURE, strlen(LABEL_TEMPERATURE)); - slide_add(PRESSURE, LABEL_PRESSURE, strlen(LABEL_PRESSURE)); - slide_add(HUMIDITY, LABEL_HUMIDITY, strlen(LABEL_HUMIDITY)); + ostentus_slide_add(o_dev, CO2, LABEL_CO2, strlen(LABEL_CO2)); + ostentus_slide_add(o_dev, PM2P5, LABEL_PM2P5, strlen(LABEL_PM2P5)); + ostentus_slide_add(o_dev, PM10P0, LABEL_PM10P0, strlen(LABEL_PM10P0)); + ostentus_slide_add(o_dev, + TEMPERATURE, + LABEL_TEMPERATURE, + strlen(LABEL_TEMPERATURE)); + ostentus_slide_add(o_dev, PRESSURE, LABEL_PRESSURE, strlen(LABEL_PRESSURE)); + ostentus_slide_add(o_dev, HUMIDITY, LABEL_HUMIDITY, strlen(LABEL_HUMIDITY)); IF_ENABLED(CONFIG_ALUDEL_BATTERY_MONITOR, ( - slide_add(BATTERY_V, LABEL_BATTERY, strlen(LABEL_BATTERY)); - slide_add(BATTERY_LVL, LABEL_BATTERY, strlen(LABEL_BATTERY)); + ostentus_slide_add(o_dev, + BATTERY_V, + LABEL_BATTERY, + strlen(LABEL_BATTERY)); + ostentus_slide_add(o_dev, + BATTERY_LVL, + LABEL_BATTERY, + strlen(LABEL_BATTERY)); )); - slide_add(FIRMWARE, LABEL_FIRMWARE, strlen(LABEL_FIRMWARE)); + ostentus_slide_add(o_dev, FIRMWARE, LABEL_FIRMWARE, strlen(LABEL_FIRMWARE)); /* Set the title of the Ostentus summary slide (optional) */ - summary_title(SUMMARY_TITLE, strlen(SUMMARY_TITLE)); + ostentus_summary_title(o_dev, SUMMARY_TITLE, strlen(SUMMARY_TITLE)); /* Update the Firmware slide with the firmware version */ - slide_set(FIRMWARE, CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION, - strlen(CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION)); + ostentus_slide_set(o_dev, FIRMWARE, (char *)_current_version, + strlen(_current_version)); /* Start Ostentus slideshow with 30 second delay between slides */ - slideshow(30000); + ostentus_slideshow(o_dev, 30000); )); while (true) { diff --git a/sysbuild.conf b/sysbuild.conf new file mode 100644 index 0000000..47f00ff --- /dev/null +++ b/sysbuild.conf @@ -0,0 +1 @@ +SB_CONFIG_BOOTLOADER_MCUBOOT=y diff --git a/west.yml b/west.yml index 3760f17..9d31568 100644 --- a/west.yml +++ b/west.yml @@ -7,7 +7,7 @@ manifest: projects: - name: golioth path: modules/lib/golioth-firmware-sdk - revision: v0.12.2 + revision: v0.15.0 url: https://github.com/golioth/golioth-firmware-sdk.git west-commands: scripts/west-commands.yml submodules: true @@ -24,8 +24,9 @@ manifest: - mcuboot - net-tools - nrfxlib - - segger + - oberon-psa-crypto - qcbor + - segger - tfm-mcuboot - tinycrypt - trusted-firmware-m @@ -33,17 +34,17 @@ manifest: - name: golioth-zephyr-boards path: deps/modules/lib/golioth-boards - revision: v1.1.1 + revision: v2.0.1 url: https://github.com/golioth/golioth-zephyr-boards - name: libostentus path: deps/modules/lib/libostentus - revision: v1.0.0 + revision: v2.0.0 url: https://github.com/golioth/libostentus - name: zephyr-network-info path: deps/modules/lib/network-info - revision: v1.1.1 + revision: v1.2.0 url: https://github.com/golioth/zephyr-network-info - name: sensirion-embedded-common