Skip to content

Commit 695273d

Browse files
committed
main: add support of llext modules
1 parent 0ac79c5 commit 695273d

File tree

2 files changed

+115
-1
lines changed

2 files changed

+115
-1
lines changed

prj.conf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,11 @@ CONFIG_NVS_LOG_LEVEL_ERR=y
9797
# Logging
9898
CONFIG_LOG=y
9999
CONFIG_LOG_MODE_IMMEDIATE=y
100+
101+
# LLEXT
102+
CONFIG_LLEXT=y
103+
CONFIG_LLEXT_HEAP_SIZE=16
104+
CONFIG_LLEXT_LOG_LEVEL_ERR=y
105+
CONFIG_LLEXT_SHELL=y
106+
CONFIG_ARM_MPU=n
107+
CONFIG_HW_STACK_PROTECTION=n

src/main.c

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ LOG_MODULE_REGISTER(mender_stm32l4a6_zephyr_example, LOG_LEVEL_INF);
3636
#include <zephyr/net/net_mgmt.h>
3737
#include <zephyr/sys/reboot.h>
3838

39+
#ifdef CONFIG_LLEXT
40+
#include <zephyr/llext/llext.h>
41+
#include <zephyr/llext/buf_loader.h>
42+
#endif /* CONFIG_LLEXT */
43+
3944
/*
4045
* Amazon Root CA 1 certificate, retrieved from https://www.amazontrust.com/repository in DER format.
4146
* It is converted to include file in application CMakeLists.txt.
@@ -70,6 +75,16 @@ static K_EVENT_DEFINE(mender_client_events);
7075
*/
7176
static struct net_mgmt_event_callback mgmt_cb;
7277

78+
#ifdef CONFIG_LLEXT
79+
80+
/**
81+
* @brief Hello-world module data and size
82+
*/
83+
static void * hello_world_module_data = NULL;
84+
static size_t hello_world_module_size = 0;
85+
86+
#endif /* CONFIG_LLEXT */
87+
7388
/**
7489
* @brief print DHCPv4 address information
7590
* @param iface Interface
@@ -211,10 +226,60 @@ authentication_failure_cb(void) {
211226
static mender_err_t
212227
deployment_status_cb(mender_deployment_status_t status, char *desc) {
213228

229+
mender_err_t ret = MENDER_OK;
230+
214231
/* We can do something else if required */
215232
LOG_INF("Deployment status is '%s'", desc);
216233

217-
return MENDER_OK;
234+
#ifdef CONFIG_LLEXT
235+
236+
/* Management of hello-world module */
237+
if ((NULL != hello_world_module_data) && (0 != hello_world_module_size)) {
238+
239+
/* Treatment depending ofthe status */
240+
if (MENDER_DEPLOYMENT_STATUS_INSTALLING == status) {
241+
242+
/* Load hello-world module */
243+
struct llext_buf_loader buf_loader = LLEXT_BUF_LOADER(hello_world_module_data, hello_world_module_size);
244+
struct llext_loader * ldr = &buf_loader.loader;
245+
struct llext_load_param ldr_parm = LLEXT_LOAD_PARAM_DEFAULT;
246+
struct llext * ext;
247+
if (0 != llext_load(ldr, "hello-world", &ext, &ldr_parm)) {
248+
LOG_ERR("Unable to load module");
249+
ret = MENDER_FAIL;
250+
} else {
251+
252+
/* Call hello_world function */
253+
void (*hello_world_fn)() = llext_find_sym(&ext->exp_tab, "hello_world");
254+
if (NULL != hello_world_fn) {
255+
hello_world_fn();
256+
}
257+
258+
/* Unload module */
259+
llext_unload(&ext);
260+
}
261+
262+
/* Release memory */
263+
if (NULL != hello_world_module_data) {
264+
free(hello_world_module_data);
265+
hello_world_module_data = NULL;
266+
}
267+
hello_world_module_size = 0;
268+
269+
} else if (MENDER_DEPLOYMENT_STATUS_FAILURE == status) {
270+
271+
/* Release memory */
272+
if (NULL != hello_world_module_data) {
273+
free(hello_world_module_data);
274+
hello_world_module_data = NULL;
275+
}
276+
hello_world_module_size = 0;
277+
}
278+
}
279+
280+
#endif /* CONFIG_LLEXT */
281+
282+
return ret;
218283
}
219284

220285
/**
@@ -258,6 +323,41 @@ config_updated_cb(mender_keystore_t *configuration) {
258323
#endif /* CONFIG_MENDER_CLIENT_CONFIGURE_STORAGE */
259324
#endif /* CONFIG_MENDER_CLIENT_ADD_ON_CONFIGURE */
260325

326+
#ifdef CONFIG_LLEXT
327+
328+
static mender_err_t
329+
hello_world_module_cb(char *id, char *artifact_name, char *type, cJSON *meta_data, char *filename, size_t size, void *data, size_t index, size_t length) {
330+
331+
(void)id;
332+
(void)artifact_name;
333+
(void)type;
334+
(void)meta_data;
335+
(void)filename;
336+
(void)size;
337+
(void)index;
338+
void *tmp;
339+
340+
/* Add data to the hello-world module data buffer */
341+
if (NULL != data) {
342+
if (NULL == (tmp = realloc(hello_world_module_data, hello_world_module_size + length))) {
343+
LOG_ERR("Unable to allocate memory");
344+
if (NULL != hello_world_module_data) {
345+
free(hello_world_module_data);
346+
hello_world_module_data = NULL;
347+
}
348+
hello_world_module_size = 0;
349+
return MENDER_FAIL;
350+
}
351+
hello_world_module_data = tmp;
352+
memcpy((void *)(((uint8_t *)hello_world_module_data) + hello_world_module_size), data, length);
353+
hello_world_module_size += length;
354+
}
355+
356+
return MENDER_OK;
357+
}
358+
359+
#endif /* CONFIG_LLEXT */
360+
261361
/**
262362
* @brief Main function
263363
* @return Always returns 0
@@ -324,6 +424,12 @@ main(void) {
324424
assert(MENDER_OK == mender_client_init(&mender_client_config, &mender_client_callbacks));
325425
LOG_INF("Mender client initialized");
326426

427+
#ifdef CONFIG_LLEXT
428+
/* Register LLEXT hello-world module, no reboot after installing the module, no verification of artifact name to check the version of the module */
429+
assert(MENDER_OK == mender_client_register_artifact_type("hello-world", &hello_world_module_cb, false, NULL));
430+
LOG_INF("Mender client registered hello-world module");
431+
#endif /* CONFIG_LLEXT */
432+
327433
/* Initialize mender add-ons */
328434
#ifdef CONFIG_MENDER_CLIENT_ADD_ON_CONFIGURE
329435
mender_configure_config_t mender_configure_config = { .refresh_interval = 0 };

0 commit comments

Comments
 (0)