llext: Add filesystem based extension loader
Added loader allowing to load extensions stored in a filesystem. Signed-off-by: Adam Wojasinski <awojasinski@baylibre.com>
This commit is contained in:
parent
93ffeced6a
commit
fc114e85dd
3 changed files with 139 additions and 0 deletions
73
include/zephyr/llext/fs_loader.h
Normal file
73
include/zephyr/llext/fs_loader.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2024 BayLibre SAS
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_LLEXT_FS_LOADER_H
|
||||
#define ZEPHYR_LLEXT_FS_LOADER_H
|
||||
|
||||
#include <zephyr/llext/loader.h>
|
||||
#include <zephyr/fs/fs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief LLEXT filesystem loader implementation.
|
||||
*
|
||||
* @addtogroup llext_loader_apis
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Implementation of @ref llext_loader that reads from a filesystem.
|
||||
*/
|
||||
struct llext_fs_loader {
|
||||
/** Extension loader */
|
||||
struct llext_loader loader;
|
||||
|
||||
/** @cond ignore */
|
||||
bool is_open;
|
||||
const char *name;
|
||||
struct fs_file_t file;
|
||||
/** @endcond */
|
||||
};
|
||||
|
||||
/** @cond ignore */
|
||||
int llext_fs_prepare(struct llext_loader *ldr);
|
||||
int llext_fs_read(struct llext_loader *ldr, void *buf, size_t len);
|
||||
int llext_fs_seek(struct llext_loader *ldr, size_t pos);
|
||||
void llext_fs_finalize(struct llext_loader *ldr);
|
||||
/** @endcond */
|
||||
|
||||
/**
|
||||
* @brief Initializer for an llext_fs_loader structure
|
||||
*
|
||||
* @param _filename Absolute path to the extension file.
|
||||
*/
|
||||
#define LLEXT_FS_LOADER(_filename) \
|
||||
{ \
|
||||
.loader = \
|
||||
{ \
|
||||
.prepare = llext_fs_prepare, \
|
||||
.read = llext_fs_read, \
|
||||
.seek = llext_fs_seek, \
|
||||
.peek = NULL, \
|
||||
.finalize = llext_fs_finalize, \
|
||||
}, \
|
||||
.is_open = false, \
|
||||
.name = (_filename), \
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_LLEXT_FS_LOADER_H */
|
||||
|
|
@ -11,6 +11,7 @@ if(CONFIG_LLEXT)
|
|||
llext_link.c
|
||||
llext_export.c
|
||||
buf_loader.c
|
||||
fs_loader.c
|
||||
)
|
||||
zephyr_library_sources_ifdef(CONFIG_LLEXT_SHELL shell.c)
|
||||
endif()
|
||||
|
|
|
|||
65
subsys/llext/fs_loader.c
Normal file
65
subsys/llext/fs_loader.c
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2024 BayLibre SAS
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
*/
|
||||
|
||||
#include <zephyr/llext/fs_loader.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(llext_fs_loader, CONFIG_LLEXT_LOG_LEVEL);
|
||||
|
||||
int llext_fs_prepare(struct llext_loader *l)
|
||||
{
|
||||
int ret = 0;
|
||||
struct llext_fs_loader *fs_l = CONTAINER_OF(l, struct llext_fs_loader, loader);
|
||||
|
||||
fs_file_t_init(&fs_l->file);
|
||||
|
||||
ret = fs_open(&fs_l->file, fs_l->name, FS_O_READ);
|
||||
if (ret != 0) {
|
||||
LOG_DBG("Failed opening a file: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fs_l->is_open = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int llext_fs_read(struct llext_loader *l, void *buf, size_t len)
|
||||
{
|
||||
int ret = 0;
|
||||
struct llext_fs_loader *fs_l = CONTAINER_OF(l, struct llext_fs_loader, loader);
|
||||
|
||||
if (fs_l->is_open) {
|
||||
ret = fs_read(&fs_l->file, buf, len);
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret == len ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
int llext_fs_seek(struct llext_loader *l, size_t pos)
|
||||
{
|
||||
struct llext_fs_loader *fs_l = CONTAINER_OF(l, struct llext_fs_loader, loader);
|
||||
|
||||
if (fs_l->is_open) {
|
||||
return fs_seek(&fs_l->file, pos, FS_SEEK_SET);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
void llext_fs_finalize(struct llext_loader *l)
|
||||
{
|
||||
struct llext_fs_loader *fs_l = CONTAINER_OF(l, struct llext_fs_loader, loader);
|
||||
|
||||
if (fs_l->is_open) {
|
||||
fs_close(&fs_l->file);
|
||||
fs_l->is_open = false;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue