|
6 | 6 |
|
7 | 7 | #include <zephyr/ztest.h> |
8 | 8 | #include <zephyr/kernel.h> |
| 9 | +#include <zephyr/fs/fs.h> |
| 10 | +#if defined(CONFIG_FILE_SYSTEM_LITTLEFS) |
| 11 | +#include <zephyr/fs/littlefs.h> |
| 12 | +#endif |
9 | 13 | #include <zephyr/llext/llext.h> |
10 | 14 | #include <zephyr/llext/symbol.h> |
11 | 15 | #include <zephyr/llext/buf_loader.h> |
| 16 | +#include <zephyr/llext/fs_loader.h> |
12 | 17 | #include <zephyr/logging/log.h> |
| 18 | +#include <zephyr/storage/flash_map.h> |
13 | 19 | #include <zephyr/sys/libc-hooks.h> |
14 | 20 | #include "syscalls_ext.h" |
15 | 21 | #include "threads_kernel_objects_ext.h" |
@@ -323,6 +329,57 @@ ZTEST(llext, test_find_section) |
323 | 329 | } |
324 | 330 | #endif |
325 | 331 |
|
| 332 | +#if defined(CONFIG_FILE_SYSTEM) |
| 333 | +#define LLEXT_FILE "hello_world.llext" |
| 334 | + |
| 335 | +FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(storage); |
| 336 | +static struct fs_mount_t mp = { |
| 337 | + .type = FS_LITTLEFS, |
| 338 | + .fs_data = &storage, |
| 339 | + .storage_dev = (void *)FIXED_PARTITION_ID(storage_partition), |
| 340 | + .mnt_point = "/lfs", |
| 341 | +}; |
| 342 | + |
| 343 | +ZTEST(llext, test_fs_loader) |
| 344 | +{ |
| 345 | + int res; |
| 346 | + char path[UINT8_MAX]; |
| 347 | + struct fs_file_t fd; |
| 348 | + |
| 349 | + /* File system should be mounted before the testcase. If not mount it now. */ |
| 350 | + if (!(mp.flags & FS_MOUNT_FLAG_AUTOMOUNT)) { |
| 351 | + zassert_ok(fs_mount(&mp), "Filesystem should be mounted"); |
| 352 | + } |
| 353 | + |
| 354 | + snprintf(path, sizeof(path), "%s/%s", mp.mnt_point, LLEXT_FILE); |
| 355 | + fs_file_t_init(&fd); |
| 356 | + |
| 357 | + zassert_ok(fs_open(&fd, path, FS_O_CREATE | FS_O_TRUNC | FS_O_WRITE), |
| 358 | + "Failed opening file"); |
| 359 | + |
| 360 | + zassert_equal(fs_write(&fd, hello_world_ext, ARRAY_SIZE(hello_world_ext)), |
| 361 | + ARRAY_SIZE(hello_world_ext), |
| 362 | + "Full content of the buffer holding ext should be written"); |
| 363 | + |
| 364 | + zassert_ok(fs_close(&fd), "Failed closing file"); |
| 365 | + |
| 366 | + struct llext_fs_loader fs_loader = LLEXT_FS_LOADER(path); |
| 367 | + struct llext_loader *loader = &fs_loader.loader; |
| 368 | + struct llext_load_param ldr_parm = LLEXT_LOAD_PARAM_DEFAULT; |
| 369 | + struct llext *ext = NULL; |
| 370 | + |
| 371 | + res = llext_load(loader, "hello_world", &ext, &ldr_parm); |
| 372 | + zassert_ok(res, "load should succeed"); |
| 373 | + |
| 374 | + void (*test_entry_fn)() = llext_find_sym(&ext->exp_tab, "test_entry"); |
| 375 | + |
| 376 | + zassert_not_null(test_entry_fn, "test_entry should be an exported symbol"); |
| 377 | + |
| 378 | + llext_unload(&ext); |
| 379 | + fs_unmount(&mp); |
| 380 | +} |
| 381 | +#endif |
| 382 | + |
326 | 383 | /* |
327 | 384 | * Ensure that EXPORT_SYMBOL does indeed provide a symbol and a valid address |
328 | 385 | * to it. |
|
0 commit comments