Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ cmake-build-*/

# samples private conf used to store secrets like wifi passwords and credential secrets
app/private.conf

# Binary file for config file
lfs.bin
61 changes: 61 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Install the required dependencies
```sh
west zephyr-export
west packages pip --install
west packages pip --install -- -r ./clea_cpu_monitoring_zephyr/scripts/requirements.txt
```

## Configure the application
Expand All @@ -49,7 +50,67 @@ You can now build the sample with the following command:
```sh
west build --sysbuild -p -b mimxrt1064_evk clea_cpu_monitoring_zephyr/app/
```
Or if choosing the FRDM-RW612 board:
```sh
west build --sysbuild -p -b frdm_rw612 clea_cpu_monitoring_zephyr/app -DEXTRA_CONF_FILE="prj-wifi.conf"
```

Then flash it with the command:
```sh
west flash --runner=linkserver
```

### Configuration from flash

Astarte devices are authenticated to the cloud instance using a credential secret and device ID
combination. For various reason it might be inconvenient and unsafe to store such information
within the binary file of your application.
This sample provides the users with two methods to handle sensitive information:
1. The user can provide all sensitive data through the kconfig options. Such data will be embedded
in the final application binary.
2. The user can embed all sensitive data within a separate partition, which can be flashed
independently. The sample will then read the sensitive data from the partition and the application
binary will not contain sensitive or device-specific information. Meaning it will be possible
to flash the same binary file on multiple separate devices.

The first method is very straight forward and enabled by default. The user should only change
the `CONFIG_ASTARTE_DEVICE_ID` and `CONFIG_ASTARTE_CREDENTIAL_SECRET` options in the `prj.conf`.

However, to use the flash partition a couple of extra steps will be required.
First, install the `littlefs-python` tool.
```bash
pip install littlefs-python
```
Next, update the json file `config_lfs/configuration.json` with your desired options and
create the new partition.
```bash
littlefs-python create app/config_lfs/ app/lfs.bin --block-size 4096 --block-count 6
```
Finally, flash the partition on your device using your debugger of choice. The produced `lfs.bin`
should be flashed at address `0xBE40000`.
For example using J-Link for the FRDM RW612 bard the following command will do the trick.
```bash
JLinkExe -Device RW612 -if SWD -Speed 4000
connect
LoadBin app/lfs.bin 0xBE40000
reset
exit
```
Now your device has permanently been flashed with the credentials. You can enable the
`CONFIG_GET_CONFIG_FROM_FLASH` option in the kconfig and flash your application as you would normally
do. The standard `west flash` command will only flash the application partition and not the
custom partition used for the credentials.

The WiFi SSID and password can also be flashed on the devie in this manner.

### Update WiFi configuration through UART

When WiFi credentials are stored in flash they can be updated through an UART shell command.
Open a shell with minicom.
```bash
minicom -D /dev/ttyACM0 -b 115200
```
Run the command to update the wifi config
```bash
wifi update-credentials -s ssid -p pwd
```
6 changes: 5 additions & 1 deletion README_NXP.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,17 @@ received from the device and plot it in a couple of graphs.
Navigate to the portal section and then under applications select create application.
Insert a name and slug of your choice. Add the two interfaces you installed in the previous step in
the required Astarte interfaces section. Then add a source URL where the application can be fetched.
We include the application JavaScript source file in this repository in the `portal/main.mjs`
We include the application JavaScript source file in this repository in the `portal/app.js`
folder. However, you will need to self host the file and make it available to the portal
application. It will need to be accessible through TLS and support Cross-origin resource sharing
(CORS).

![Application creation.](/doc/images/application_creation.png)

The application reported in this repo is a slightly modified and pre-compiled version of the
[CPU monitoring example](https://github.com/clea-platform/clea-examples/tree/master/cpu-monitoring-example)
that can be found in the Clea examples repo.

### 3.4 Creating an organization and accessing portal

We should now create an organization and invite at least one user. The invited user will then have
Expand Down
3 changes: 3 additions & 0 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ test_sysbuild()

# create source files list
FILE(GLOB app_common_sources ${CMAKE_CURRENT_LIST_DIR}/src/*.c)
if(NOT CONFIG_WIFI)
LIST(REMOVE_ITEM app_common_sources ${CMAKE_CURRENT_LIST_DIR}/src/wifi.c)
endif()
target_sources(app PRIVATE ${app_common_sources})
target_include_directories(app PRIVATE ${CMAKE_CURRENT_LIST_DIR}/include)

Expand Down
41 changes: 41 additions & 0 deletions app/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,55 @@ endmenu

menu "CPU metrics sample application"

config GET_CONFIG_FROM_FLASH
bool "Collect the configuration from flash"
help
Collect the configuration from a file in the dedicated flash partition.

config WIFI_SSID
string "WiFi SSID"
depends on WIFI
depends on !GET_CONFIG_FROM_FLASH
default ""
help
WiFi access point SSID.

config WIFI_PASSWORD
string "WiFi password"
depends on WIFI
depends on !GET_CONFIG_FROM_FLASH
default ""
help
WiFi access point password.

config ENABLE_TRANSMISSION
bool "Enable sensor readings transmission"
default n
help
Enable transmission of sensor readings to Astarte.

config CPU_TEMP_SENSOR
bool "CPU temperature sensor"
default n
help
Temperature sensor embedded within the CPU die.

config AMBIENT_TEMP_SENSOR
bool "Ambient temperature sensor"
default n
help
Temperature sensor embedded within the ambient.

config ASTARTE_DEVICE_ID
string "Astarte device ID"
depends on !GET_CONFIG_FROM_FLASH
default ""
help
Device ID to be used to connect to Astarte.

config ASTARTE_CREDENTIAL_SECRET
string "Astarte credential secret"
depends on !GET_CONFIG_FROM_FLASH
default ""
help
The credential secret to be used to connect to Astarte.
Expand Down
15 changes: 15 additions & 0 deletions app/boards/frdm_rw612.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# (C) Copyright 2025, SECO Mind Srl
#
# SPDX-License-Identifier: Apache-2.0

# Enable the WiFi
CONFIG_WIFI_NXP=y

# Use a large log buffer size
CONFIG_LOG_BUFFER_SIZE=32768

# Set the ambient temperature sensor in the demo
CONFIG_AMBIENT_TEMP_SENSOR=y

# This board by default will expect the configuration to be present in flash
CONFIG_GET_CONFIG_FROM_FLASH=y
39 changes: 39 additions & 0 deletions app/boards/frdm_rw612.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* (C) Copyright 2025, SECO Mind Srl
*
* SPDX-License-Identifier: Apache-2.0
*/

/ {
fstab {
compatible = "zephyr,fstab";
lfs1: lfs1 {
compatible = "zephyr,fstab,littlefs";
mount-point = "/lfs1";
partition = <&config_partition>;
automount;
read-size = <16>;
prog-size = <16>;
cache-size = <64>;
lookahead-size = <32>;
block-cycles = <512>;
};
};
};

&w25q512jvfiq {
partitions {
astarte_partition: partition@3E00000 {
label = "astarte";
reg = <0x03E00000 DT_SIZE_K(128)>;
};
edgehog_partition: partition@3E20000 {
label = "edgehog";
reg = <0x03E20000 DT_SIZE_K(128)>;
};
config_partition: partition@3E40000 {
label = "configuration";
reg = <0x03E40000 DT_SIZE_K(24)>;
};
};
};
2 changes: 2 additions & 0 deletions app/boards/mimxrt1064_evk.conf
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ CONFIG_EDGEHOG_DEVICE_USE_EDGEHOG_PARTITION=y

CONFIG_LOG_MODE_DEFERRED=y
CONFIG_LOG_BUFFER_SIZE=32768

CONFIG_CPU_TEMP_SENSOR=y
6 changes: 6 additions & 0 deletions app/config_lfs/configuration.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"deviceID": "xxxxxxx" ,
"credentialSecret": "xxxxxxx",
"wifiSsid": "xxxxxxx",
"wifiPassword": "xxxxxxx"
}
38 changes: 38 additions & 0 deletions app/include/sample_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* (C) Copyright 2025, SECO Mind Srl
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef SAMPLE_CONFIG_H
#define SAMPLE_CONFIG_H

#include <stdbool.h>
#include <stddef.h>

#include <astarte_device_sdk/device.h>

#if defined(CONFIG_WIFI)
#define SAMPLE_CONFIG_WIFI_MAX_STRINGS 255
#endif

struct sample_config
{
char device_id[ASTARTE_DEVICE_ID_LEN + 1];
#if !defined(CONFIG_DEVICE_REGISTRATION)
char credential_secret[ASTARTE_PAIRING_CRED_SECR_LEN + 1];
#endif
#if defined(CONFIG_WIFI)
char wifi_ssid[SAMPLE_CONFIG_WIFI_MAX_STRINGS];
char wifi_pwd[SAMPLE_CONFIG_WIFI_MAX_STRINGS];
#endif
};

int sample_config_get(struct sample_config *cfg);
#if defined(CONFIG_WIFI)
int sample_config_get_wifi_ssid(char output[static SAMPLE_CONFIG_WIFI_MAX_STRINGS]);
int sample_config_update_wifi_creds(char ssid[static SAMPLE_CONFIG_WIFI_MAX_STRINGS],
char pwd[static SAMPLE_CONFIG_WIFI_MAX_STRINGS]);
#endif

#endif /* SAMPLE_CONFIG_H */
22 changes: 22 additions & 0 deletions app/include/wifi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* (C) Copyright 2025, SECO Mind Srl
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef WIFI_H
#define WIFI_H

#include <zephyr/net/wifi.h>

/**
* @brief Initialize the wifi driver
*/
void app_wifi_init(void);

/**
* @brief Connect the wifi to an SSID
*/
int app_wifi_connect(const char *ssid, enum wifi_security_type sec, const char *psk);

#endif /* WIFI_H */
18 changes: 18 additions & 0 deletions app/interfaces/com.example.poc.AmbientTemp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"interface_name": "com.example.poc.AmbientTemp",
"version_major": 0,
"version_minor": 1,
"type": "datastream",
"ownership": "device",
"aggregation": "individual",
"mappings": [
{
"endpoint": "/temp",
"type": "double",
"database_retention_policy": "use_ttl",
"database_retention_ttl": 5184000,
"explicit_timestamp": true,
"description": "SOC temperature in °C"
}
]
}
22 changes: 22 additions & 0 deletions app/interfaces/generated_interfaces.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,28 @@
// Interface names should resemble as closely as possible their respective .json file names.
// NOLINTBEGIN(readability-identifier-naming)

static const astarte_mapping_t com_example_poc_AmbientTemp_mappings[1] = {

{
.endpoint = "/temp",
.type = ASTARTE_MAPPING_TYPE_DOUBLE,
.reliability = ASTARTE_MAPPING_RELIABILITY_UNRELIABLE,
.explicit_timestamp = true,
.allow_unset = false,
},
};

const astarte_interface_t com_example_poc_AmbientTemp = {
.name = "com.example.poc.AmbientTemp",
.major_version = 0,
.minor_version = 1,
.type = ASTARTE_INTERFACE_TYPE_DATASTREAM,
.ownership = ASTARTE_INTERFACE_OWNERSHIP_DEVICE,
.aggregation = ASTARTE_INTERFACE_AGGREGATION_INDIVIDUAL,
.mappings = com_example_poc_AmbientTemp_mappings,
.mappings_length = 1U,
};

static const astarte_mapping_t com_example_poc_CpuMetrics_mappings[1] = {

{
Expand Down
1 change: 1 addition & 0 deletions app/interfaces/generated_interfaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

// Interface names should resemble as closely as possible their respective .json file names.
// NOLINTBEGIN(readability-identifier-naming)
extern const astarte_interface_t com_example_poc_AmbientTemp;
extern const astarte_interface_t com_example_poc_CpuMetrics;
extern const astarte_interface_t com_example_poc_CpuTemp;
// NOLINTEND(readability-identifier-naming)
Expand Down
20 changes: 20 additions & 0 deletions app/prj-wifi.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# (C) Copyright 2025, SECO Mind Srl
#
# SPDX-License-Identifier: Apache-2.0
#
# This is a Kconfig fragment which can be used to enable debug-related options
# in the application. See the README for more details.

CONFIG_WIFI=y
CONFIG_ETH_DRIVER=n

CONFIG_NET_IPV6=n
CONFIG_NET_DHCPV6=n

# Increased stack size for network management
CONFIG_NET_MGMT_EVENT_STACK_SIZE=2048

# Large shell stack size used when configuring WiFi through shell
CONFIG_SHELL_STACK_SIZE=16384
CONFIG_SHELL_GETOPT=y
CONFIG_GETOPT_LONG=y
Loading