Skip to content
Draft
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
2 changes: 1 addition & 1 deletion app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ else()
set(creds "src/creds/ca.c" "src/creds/key.c" "src/creds/cert.c")
endif()

set(helpers "src/sensor.c" "src/modem.c" "src/aws.c")
set(helpers "src/sensor.c" "src/modem.c" "src/aws.c" "src/mender.c")

target_sources(app PRIVATE src/main.c ${helpers} ${creds})
30 changes: 29 additions & 1 deletion app/boards/mikroe_clicker_2.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,35 @@

chosen {
zephyr,modem-uart = &mikrobus_uart;
zephyr,code-partition = &flash0;
zephyr,code-partition = &slot0_partition;
};
};

&flash0 {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;

boot_partition: partition@0 {
label = "mcuboot";
reg = <0x00000000 0x00020000>;
};

slot0_partition: partition@20000 {
label = "image-0";
reg = <0x00020000 0x00060000>;
};

slot1_partition: partition@80000 {
label = "image-1";
reg = <0x00080000 0x00060000>;
};

mender_partition: partition@e0000 {
label = "mender";
reg = <0x000e0000 0x00020000>;
};
};
};

Expand Down
6 changes: 6 additions & 0 deletions app/boards/mikroe_clicker_2_mcuboot.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
CONFIG_BOOT_UPGRADE_ONLY=y
CONFIG_BOOT_SWAP_USING_OFFSET=n
CONFIG_BOOT_SWAP_USING_SCRATCH=n
CONFIG_MCUBOOT_LOG_LEVEL_DBG=y
CONFIG_MCUBOOT_LOG_LEVEL_INF=n
CONFIG_MCUBOOT_UTIL_LOG_LEVEL_DBG=y
39 changes: 39 additions & 0 deletions app/boards/mikroe_clicker_2_mcuboot.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* SPDX-FileCopyrightText: 2026 ID8 Engineering AB
*
* SPDX-License-Identifier: Apache-2.0
*/

/ {
chosen {
zephyr,code-partition = &boot_partition;
};
};

&flash0 {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;

boot_partition: partition@0 {
label = "mcuboot";
reg = <0x00000000 0x00020000>;
};

slot0_partition: partition@20000 {
label = "image-0";
reg = <0x00020000 0x00060000>;
};

slot1_partition: partition@80000 {
label = "image-1";
reg = <0x00080000 0x00060000>;
};

mender_partition: partition@e0000 {
label = "mender";
reg = <0x000e0000 0x00020000>;
};
};
};
16 changes: 16 additions & 0 deletions app/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ CONFIG_MBEDTLS_ENABLE_HEAP=y
CONFIG_MBEDTLS_HEAP_SIZE=32768
CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=4096
CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y
CONFIG_MBEDTLS_ECP_C=y
CONFIG_MBEDTLS_ECDSA_C=y
CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y
CONFIG_MBEDTLS_PEM_PARSE_C=y
CONFIG_MBEDTLS_PK_WRITE_C=y
CONFIG_MBEDTLS_SSL_SERVER_NAME_INDICATION=y
CONFIG_MBEDTLS_HAVE_TIME_DATE=y
CONFIG_MBEDTLS_SSL_ALPN=y
Expand Down Expand Up @@ -79,8 +83,20 @@ CONFIG_JSON_LIBRARY=y
# Logging
CONFIG_LOG=y
CONFIG_LOG_DEFAULT_LEVEL=3
CONFIG_LOG_OUTPUT_FORMAT_ISO8601_TIMESTAMP=y
CONFIG_MODEM_MODULES_LOG_LEVEL_INF=y

# Mender
CONFIG_BOOTLOADER_MCUBOOT=y
CONFIG_MCUBOOT_IMGTOOL_OVERWRITE_ONLY=y
CONFIG_MENDER_MCU_CLIENT=y
CONFIG_MENDER_SERVER_HOST_EU=y
CONFIG_MENDER_SERVER_TENANT_TOKEN="..."
CONFIG_MENDER_DEVICE_TYPE="mikroe-clicker-2"
CONFIG_MENDER_ZEPHYR_IMAGE_UPDATE_MODULE=y
CONFIG_MENDER_DEPLOYMENT_LOGS=n
CONFIG_MENDER_ARTIFACT_GENERATE=n

# App
CONFIG_SENSOR=y
CONFIG_UART_INTERRUPT_DRIVEN=y
Expand Down
6 changes: 6 additions & 0 deletions app/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <zephyr/net/sntp.h>

#include "aws.h"
#include "mender.h"
#include "modem.h"
#include "sensor.h"

Expand Down Expand Up @@ -71,6 +72,11 @@ int main(void)
LOG_ERR("sensor: device not ready");
return -ENODEV;
}
ret = mender_start();
if (ret < 0) {
LOG_ERR("Mender start failed: %d", ret);
return ret;
}
ret = aws_init();
if (ret < 0) {
LOG_ERR("AWS init failed: %d", ret);
Expand Down
118 changes: 118 additions & 0 deletions app/src/mender.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* SPDX-FileCopyrightText: 2026 ID8 Engineering AB
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/cellular.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/reboot.h>

#include <mender/client.h>
#include <mender/zephyr-image-update-module.h>

LOG_MODULE_REGISTER(mender_app, LOG_LEVEL_INF);

static char mender_identity_value[32];
static mender_identity_t mender_identity = {
.name = "imei",
.value = mender_identity_value,
};

static mender_err_t mender_network_connect_cb(void)
{
/* The application keeps the PPP link up continuously. */
return MENDER_OK;
}

static mender_err_t mender_network_release_cb(void)
{
/* The PPP link is shared with AWS and should remain connected. */
return MENDER_OK;
}

static mender_err_t mender_restart_cb(void)
{
LOG_INF("Mender requested restart");
sys_reboot(SYS_REBOOT_COLD);
return MENDER_OK;
}

static mender_err_t mender_deployment_status_cb(mender_deployment_status_t status,
const char *status_name)
{
ARG_UNUSED(status);
LOG_INF("Mender deployment status: %s", status_name);
return MENDER_OK;
}

static mender_err_t mender_get_identity_cb(const mender_identity_t **identity)
{
const struct device *modem = DEVICE_DT_GET(DT_ALIAS(modem));
int ret;

if (identity == NULL) {
return MENDER_FAIL;
}

if (mender_identity.value[0] == '\0') {
ret = cellular_get_modem_info(modem, CELLULAR_MODEM_INFO_IMEI, mender_identity_value,
sizeof(mender_identity_value));
if (ret < 0 || mender_identity_value[0] == '\0') {
LOG_ERR("Unable to read modem IMEI for Mender identity: %d", ret);
return MENDER_FAIL;
}
}

*identity = &mender_identity;
return MENDER_OK;
}

int mender_start(void)
{
mender_err_t ret;
mender_client_config_t config = {
.device_type = CONFIG_MENDER_DEVICE_TYPE,
.host = NULL,
.tenant_token = NULL,
.device_tier = CONFIG_MENDER_DEVICE_TIER,
.update_poll_interval = 0,
#ifndef CONFIG_MENDER_CLIENT_INVENTORY_DISABLE
.inventory_update_interval = 0,
#endif
.backoff_interval = 0,
.max_backoff_interval = 0,
.recommissioning = false,
};
mender_client_callbacks_t callbacks = {
.network_connect = mender_network_connect_cb,
.network_release = mender_network_release_cb,
.deployment_status = mender_deployment_status_cb,
.restart = mender_restart_cb,
.get_identity = mender_get_identity_cb,
.get_user_provided_keys = NULL,
};

ret = mender_client_init(&config, &callbacks);
if (ret != MENDER_OK) {
LOG_ERR("Mender init failed: %d", ret);
return -EINVAL;
}

ret = mender_zephyr_image_register_update_module();
if (ret != MENDER_OK) {
LOG_ERR("Mender update module registration failed: %d", ret);
return -EINVAL;
}

ret = mender_client_activate();
if (ret != MENDER_OK) {
LOG_ERR("Mender activation failed: %d", ret);
return -EINVAL;
}

LOG_INF("Mender activated");
return 0;
}
12 changes: 12 additions & 0 deletions app/src/mender.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* SPDX-FileCopyrightText: 2026 ID8 Engineering AB
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef MENDER_H_
#define MENDER_H_

int mender_start(void);

#endif /* MENDER_H_ */
7 changes: 7 additions & 0 deletions west.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ manifest:
- hal_st
- hal_stm32
- mbedtls
- mcuboot

- name: mender-mcu
url: https://github.com/mendersoftware/mender-mcu
revision: main
path: modules/mender-mcu
import: true

self:
path: seven-clicker-sample
Loading