SB-VFS integration working in the demo.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15280 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
aac3849aa4
commit
6751fc38ee
|
@ -22,8 +22,42 @@
|
||||||
#include "rt_test_root.h"
|
#include "rt_test_root.h"
|
||||||
#include "oslib_test_root.h"
|
#include "oslib_test_root.h"
|
||||||
|
|
||||||
|
#include "nullstreams.h"
|
||||||
|
|
||||||
#include "startup_defs.h"
|
#include "startup_defs.h"
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* VFS-related. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if VFS_CFG_ENABLE_DRV_FATFS == TRUE
|
||||||
|
/* VFS FatFS driver object representing the root directory.*/
|
||||||
|
static vfs_fatfs_driver_c root_driver;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* VFS overlay driver object representing the root directory.*/
|
||||||
|
static vfs_overlay_driver_c root_overlay_driver;
|
||||||
|
|
||||||
|
/* VFS streams driver object representing the /dev directory.*/
|
||||||
|
static vfs_streams_driver_c dev_driver;
|
||||||
|
|
||||||
|
/* VFS API will use this object as implicit root, defining this
|
||||||
|
symbol is expected.*/
|
||||||
|
vfs_driver_c *vfs_root = (vfs_driver_c *)&root_overlay_driver;
|
||||||
|
|
||||||
|
static NullStream nullstream;
|
||||||
|
|
||||||
|
/* Stream to be exposed under /dev as files.*/
|
||||||
|
static const drv_streams_element_t streams[] = {
|
||||||
|
{"VSD1", (BaseSequentialStream *)&LPSD1},
|
||||||
|
{"null", (BaseSequentialStream *)&nullstream},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* SB-related. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/* Sandbox 1 configuration.*/
|
/* Sandbox 1 configuration.*/
|
||||||
static const sb_config_t sb_config1 = {
|
static const sb_config_t sb_config1 = {
|
||||||
.code_region = 0U,
|
.code_region = 0U,
|
||||||
|
@ -52,9 +86,6 @@ static const sb_config_t sb_config1 = {
|
||||||
MPU_RASR_ENABLE
|
MPU_RASR_ENABLE
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.stdin_stream = (SandboxStream *)&LPSD1,
|
|
||||||
.stdout_stream = (SandboxStream *)&LPSD1,
|
|
||||||
.stderr_stream = (SandboxStream *)&LPSD1
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Sandbox 2 configuration.*/
|
/* Sandbox 2 configuration.*/
|
||||||
|
@ -85,16 +116,17 @@ static const sb_config_t sb_config2 = {
|
||||||
MPU_RASR_ENABLE
|
MPU_RASR_ENABLE
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.stdin_stream = (SandboxStream *)&LPSD1,
|
|
||||||
.stdout_stream = (SandboxStream *)&LPSD1,
|
|
||||||
.stderr_stream = (SandboxStream *)&LPSD1
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Sandbox objects.*/
|
/* Sandbox objects.*/
|
||||||
sb_class_t sbx1, sbx2;
|
sb_class_t sbx1, sbx2;
|
||||||
|
|
||||||
static THD_WORKING_AREA(waUnprivileged1, 256);
|
static THD_WORKING_AREA(waUnprivileged1, 512);
|
||||||
static THD_WORKING_AREA(waUnprivileged2, 256);
|
static THD_WORKING_AREA(waUnprivileged2, 512);
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Main and generic code. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Green LED blinker thread, times are in milliseconds.
|
* Green LED blinker thread, times are in milliseconds.
|
||||||
|
@ -118,6 +150,8 @@ int main(void) {
|
||||||
unsigned i = 1U;
|
unsigned i = 1U;
|
||||||
thread_t *utp1, *utp2;
|
thread_t *utp1, *utp2;
|
||||||
event_listener_t el1;
|
event_listener_t el1;
|
||||||
|
vfs_file_node_c *fnp;
|
||||||
|
msg_t ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* System initializations.
|
* System initializations.
|
||||||
|
@ -125,29 +159,61 @@ int main(void) {
|
||||||
* and performs the board-specific initializations.
|
* and performs the board-specific initializations.
|
||||||
* - Kernel initialization, the main() function becomes a thread and the
|
* - Kernel initialization, the main() function becomes a thread and the
|
||||||
* RTOS is active.
|
* RTOS is active.
|
||||||
|
* - Virtual File System initialization.
|
||||||
* - SandBox manager initialization.
|
* - SandBox manager initialization.
|
||||||
*/
|
*/
|
||||||
halInit();
|
halInit();
|
||||||
chSysInit();
|
chSysInit();
|
||||||
|
vfsInit();
|
||||||
sbHostInit();
|
sbHostInit();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Listening to sandbox events.
|
* Starting a serial port for I/O, initializing other streams too.
|
||||||
*/
|
|
||||||
chEvtRegister(&sb.termination_es, &el1, (eventid_t)0);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Activates the Serial driver using the default configuration.
|
|
||||||
*/
|
*/
|
||||||
sdStart(&LPSD1, NULL);
|
sdStart(&LPSD1, NULL);
|
||||||
|
nullObjectInit(&nullstream);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Creates the blinker thread.
|
* Creating a blinker thread.
|
||||||
*/
|
*/
|
||||||
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO+10, Thread1, NULL);
|
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO+10, Thread1, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initializing an overlay VFS object as a root, no overlaid driver,
|
||||||
|
* registering a streams VFS driver on the VFS overlay root as "/dev".
|
||||||
|
*/
|
||||||
|
drvOverlayObjectInit(&root_overlay_driver, NULL, NULL);
|
||||||
|
ret = drvOverlayRegisterDriver(&root_overlay_driver,
|
||||||
|
drvStreamsObjectInit(&dev_driver, &streams[0]),
|
||||||
|
"dev");
|
||||||
|
if (CH_RET_IS_ERROR(ret)) {
|
||||||
|
chSysHalt("VFS");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sandbox objects initialization.
|
||||||
|
*/
|
||||||
|
sbObjectInit(&sbx1, &sb_config1);
|
||||||
|
sbObjectInit(&sbx2, &sb_config2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Associating standard input, output and error to sandboxes. Both sandboxes
|
||||||
|
* use the same serial port in this setup.
|
||||||
|
*/
|
||||||
|
ret = vfsOpenFile("/dev/VSD1", 0, &fnp);
|
||||||
|
if (CH_RET_IS_ERROR(ret)) {
|
||||||
|
chSysHalt("VFS");
|
||||||
|
}
|
||||||
|
sbPosixRegisterFileDescriptor(&sbx1, STDIN_FILENO, (vfs_file_node_c *)roAddRef(fnp));
|
||||||
|
sbPosixRegisterFileDescriptor(&sbx1, STDOUT_FILENO, (vfs_file_node_c *)roAddRef(fnp));
|
||||||
|
sbPosixRegisterFileDescriptor(&sbx1, STDERR_FILENO, (vfs_file_node_c *)roAddRef(fnp));
|
||||||
|
sbPosixRegisterFileDescriptor(&sbx2, STDIN_FILENO, (vfs_file_node_c *)roAddRef(fnp));
|
||||||
|
sbPosixRegisterFileDescriptor(&sbx2, STDOUT_FILENO, (vfs_file_node_c *)roAddRef(fnp));
|
||||||
|
sbPosixRegisterFileDescriptor(&sbx2, STDERR_FILENO, (vfs_file_node_c *)roAddRef(fnp));
|
||||||
|
vfsCloseFile(fnp);
|
||||||
|
|
||||||
/* Starting sandboxed thread 1.*/
|
/* Starting sandboxed thread 1.*/
|
||||||
utp1 = sbStartThread(&sbx1, &sb_config1, "sbx1",
|
utp1 = sbStartThread(&sbx1, "sbx1",
|
||||||
waUnprivileged1, sizeof (waUnprivileged1),
|
waUnprivileged1, sizeof (waUnprivileged1),
|
||||||
NORMALPRIO - 1);
|
NORMALPRIO - 1);
|
||||||
if (utp1 == NULL) {
|
if (utp1 == NULL) {
|
||||||
|
@ -155,7 +221,7 @@ int main(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Starting sandboxed thread 2.*/
|
/* Starting sandboxed thread 2.*/
|
||||||
utp2 = sbStartThread(&sbx2, &sb_config2, "sbx2",
|
utp2 = sbStartThread(&sbx2, "sbx2",
|
||||||
waUnprivileged2, sizeof (waUnprivileged2),
|
waUnprivileged2, sizeof (waUnprivileged2),
|
||||||
NORMALPRIO - 1);
|
NORMALPRIO - 1);
|
||||||
if (utp1 == NULL) {
|
if (utp1 == NULL) {
|
||||||
|
@ -163,7 +229,12 @@ int main(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Normal main() thread activity, in this demo it monitos the user button
|
* Listening to sandbox events.
|
||||||
|
*/
|
||||||
|
chEvtRegister(&sb.termination_es, &el1, (eventid_t)0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Normal main() thread activity, in this demo it monitors the user button
|
||||||
* and checks for sandboxes state.
|
* and checks for sandboxes state.
|
||||||
*/
|
*/
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -199,4 +270,3 @@ int main(void) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,42 @@
|
||||||
#include "rt_test_root.h"
|
#include "rt_test_root.h"
|
||||||
#include "oslib_test_root.h"
|
#include "oslib_test_root.h"
|
||||||
|
|
||||||
|
#include "nullstreams.h"
|
||||||
|
|
||||||
#include "startup_defs.h"
|
#include "startup_defs.h"
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* VFS-related. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if VFS_CFG_ENABLE_DRV_FATFS == TRUE
|
||||||
|
/* VFS FatFS driver object representing the root directory.*/
|
||||||
|
static vfs_fatfs_driver_c root_driver;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* VFS overlay driver object representing the root directory.*/
|
||||||
|
static vfs_overlay_driver_c root_overlay_driver;
|
||||||
|
|
||||||
|
/* VFS streams driver object representing the /dev directory.*/
|
||||||
|
static vfs_streams_driver_c dev_driver;
|
||||||
|
|
||||||
|
/* VFS API will use this object as implicit root, defining this
|
||||||
|
symbol is expected.*/
|
||||||
|
vfs_driver_c *vfs_root = (vfs_driver_c *)&root_overlay_driver;
|
||||||
|
|
||||||
|
static NullStream nullstream;
|
||||||
|
|
||||||
|
/* Stream to be exposed under /dev as files.*/
|
||||||
|
static const drv_streams_element_t streams[] = {
|
||||||
|
{"VSD1", (BaseSequentialStream *)&LPSD1},
|
||||||
|
{"null", (BaseSequentialStream *)&nullstream},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* SB-related. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/* Sandbox 1 configuration.*/
|
/* Sandbox 1 configuration.*/
|
||||||
static const sb_config_t sb_config1 = {
|
static const sb_config_t sb_config1 = {
|
||||||
.code_region = 0U,
|
.code_region = 0U,
|
||||||
|
@ -38,9 +72,7 @@ static const sb_config_t sb_config1 = {
|
||||||
.writeable = true
|
.writeable = true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.stdin_stream = (SandboxStream *)&LPSD1,
|
.vfs_driver = (vfs_driver_c *)&root_overlay_driver
|
||||||
.stdout_stream = (SandboxStream *)&LPSD1,
|
|
||||||
.stderr_stream = (SandboxStream *)&LPSD1
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Sandbox 2 configuration.*/
|
/* Sandbox 2 configuration.*/
|
||||||
|
@ -57,16 +89,18 @@ static const sb_config_t sb_config2 = {
|
||||||
.writeable = true
|
.writeable = true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.stdin_stream = (SandboxStream *)&LPSD1,
|
.vfs_driver = (vfs_driver_c *)&root_overlay_driver
|
||||||
.stdout_stream = (SandboxStream *)&LPSD1,
|
|
||||||
.stderr_stream = (SandboxStream *)&LPSD1
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Sandbox objects.*/
|
/* Sandbox objects.*/
|
||||||
sb_class_t sbx1, sbx2;
|
sb_class_t sbx1, sbx2;
|
||||||
|
|
||||||
static THD_WORKING_AREA(waUnprivileged1, 256);
|
static THD_WORKING_AREA(waUnprivileged1, 512);
|
||||||
static THD_WORKING_AREA(waUnprivileged2, 256);
|
static THD_WORKING_AREA(waUnprivileged2, 512);
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Main and generic code. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Green LED blinker thread, times are in milliseconds.
|
* Green LED blinker thread, times are in milliseconds.
|
||||||
|
@ -90,6 +124,8 @@ int main(void) {
|
||||||
unsigned i = 1U;
|
unsigned i = 1U;
|
||||||
thread_t *utp1, *utp2;
|
thread_t *utp1, *utp2;
|
||||||
event_listener_t el1;
|
event_listener_t el1;
|
||||||
|
vfs_file_node_c *fnp;
|
||||||
|
msg_t ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* System initializations.
|
* System initializations.
|
||||||
|
@ -97,27 +133,59 @@ int main(void) {
|
||||||
* and performs the board-specific initializations.
|
* and performs the board-specific initializations.
|
||||||
* - Kernel initialization, the main() function becomes a thread and the
|
* - Kernel initialization, the main() function becomes a thread and the
|
||||||
* RTOS is active.
|
* RTOS is active.
|
||||||
|
* - Virtual File System initialization.
|
||||||
* - SandBox manager initialization.
|
* - SandBox manager initialization.
|
||||||
*/
|
*/
|
||||||
halInit();
|
halInit();
|
||||||
chSysInit();
|
chSysInit();
|
||||||
|
vfsInit();
|
||||||
sbHostInit();
|
sbHostInit();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Listening to sandbox events.
|
* Starting a serial port for I/O, initializing other streams too.
|
||||||
*/
|
|
||||||
chEvtRegister(&sb.termination_es, &el1, (eventid_t)0);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Activates the Serial driver using the default configuration.
|
|
||||||
*/
|
*/
|
||||||
sdStart(&LPSD1, NULL);
|
sdStart(&LPSD1, NULL);
|
||||||
|
nullObjectInit(&nullstream);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Creates the blinker thread.
|
* Creating a blinker thread.
|
||||||
*/
|
*/
|
||||||
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO+10, Thread1, NULL);
|
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO+10, Thread1, NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initializing an overlay VFS object as a root, no overlaid driver,
|
||||||
|
* registering a streams VFS driver on the VFS overlay root as "/dev".
|
||||||
|
*/
|
||||||
|
drvOverlayObjectInit(&root_overlay_driver, NULL, NULL);
|
||||||
|
ret = drvOverlayRegisterDriver(&root_overlay_driver,
|
||||||
|
drvStreamsObjectInit(&dev_driver, &streams[0]),
|
||||||
|
"dev");
|
||||||
|
if (CH_RET_IS_ERROR(ret)) {
|
||||||
|
chSysHalt("VFS");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sandbox objects initialization.
|
||||||
|
*/
|
||||||
|
sbObjectInit(&sbx1, &sb_config1);
|
||||||
|
sbObjectInit(&sbx2, &sb_config2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Associating standard input, output and error to sandboxes. Both sandboxes
|
||||||
|
* use the same serial port in this setup.
|
||||||
|
*/
|
||||||
|
ret = vfsOpenFile("/dev/VSD1", 0, &fnp);
|
||||||
|
if (CH_RET_IS_ERROR(ret)) {
|
||||||
|
chSysHalt("VFS");
|
||||||
|
}
|
||||||
|
sbPosixRegisterFileDescriptor(&sbx1, STDIN_FILENO, (vfs_file_node_c *)roAddRef(fnp));
|
||||||
|
sbPosixRegisterFileDescriptor(&sbx1, STDOUT_FILENO, (vfs_file_node_c *)roAddRef(fnp));
|
||||||
|
sbPosixRegisterFileDescriptor(&sbx1, STDERR_FILENO, (vfs_file_node_c *)roAddRef(fnp));
|
||||||
|
sbPosixRegisterFileDescriptor(&sbx2, STDIN_FILENO, (vfs_file_node_c *)roAddRef(fnp));
|
||||||
|
sbPosixRegisterFileDescriptor(&sbx2, STDOUT_FILENO, (vfs_file_node_c *)roAddRef(fnp));
|
||||||
|
sbPosixRegisterFileDescriptor(&sbx2, STDERR_FILENO, (vfs_file_node_c *)roAddRef(fnp));
|
||||||
|
vfsCloseFile(fnp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Creating **static** boxes using MPU.
|
* Creating **static** boxes using MPU.
|
||||||
* Note: The two regions cover both sandbox 1 and 2, there is no
|
* Note: The two regions cover both sandbox 1 and 2, there is no
|
||||||
|
@ -137,7 +205,7 @@ int main(void) {
|
||||||
MPU_RASR_ENABLE);
|
MPU_RASR_ENABLE);
|
||||||
|
|
||||||
/* Starting sandboxed thread 1.*/
|
/* Starting sandboxed thread 1.*/
|
||||||
utp1 = sbStartThread(&sbx1, &sb_config1, "sbx1",
|
utp1 = sbStartThread(&sbx1, "sbx1",
|
||||||
waUnprivileged1, sizeof (waUnprivileged1),
|
waUnprivileged1, sizeof (waUnprivileged1),
|
||||||
NORMALPRIO - 1);
|
NORMALPRIO - 1);
|
||||||
if (utp1 == NULL) {
|
if (utp1 == NULL) {
|
||||||
|
@ -145,7 +213,7 @@ int main(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Starting sandboxed thread 2.*/
|
/* Starting sandboxed thread 2.*/
|
||||||
utp2 = sbStartThread(&sbx2, &sb_config2, "sbx2",
|
utp2 = sbStartThread(&sbx2, "sbx2",
|
||||||
waUnprivileged2, sizeof (waUnprivileged2),
|
waUnprivileged2, sizeof (waUnprivileged2),
|
||||||
NORMALPRIO - 1);
|
NORMALPRIO - 1);
|
||||||
if (utp1 == NULL) {
|
if (utp1 == NULL) {
|
||||||
|
@ -153,7 +221,12 @@ int main(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Normal main() thread activity, in this demo it monitos the user button
|
* Listening to sandbox events.
|
||||||
|
*/
|
||||||
|
chEvtRegister(&sb.termination_es, &el1, (eventid_t)0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Normal main() thread activity, in this demo it monitors the user button
|
||||||
* and checks for sandboxes state.
|
* and checks for sandboxes state.
|
||||||
*/
|
*/
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -189,4 +262,3 @@ int main(void) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -153,24 +153,26 @@ static inline void __referenced_object_release_impl(void *ip) {
|
||||||
/**
|
/**
|
||||||
* @brief New reference creation.
|
* @brief New reference creation.
|
||||||
*
|
*
|
||||||
* @param[in] rop A reference to the object.
|
* @param[in] ip A reference to the object.
|
||||||
* @return A new reference to the object.
|
* @return A new reference to the object.
|
||||||
*/
|
*/
|
||||||
CC_FORCE_INLINE
|
CC_FORCE_INLINE
|
||||||
static inline referenced_object_c *roAddRef(referenced_object_c *rop) {
|
static inline referenced_object_c *roAddRef(void *ip) {
|
||||||
|
referenced_object_c *objp = (referenced_object_c *)ip;
|
||||||
|
|
||||||
return (referenced_object_c *)rop->vmt->addref((void *)rop);
|
return objp->vmt->addref(ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reference release.
|
* @brief Reference release.
|
||||||
*
|
*
|
||||||
* @param[in] rop A reference to the object.
|
* @param[in] ip A reference to the object.
|
||||||
*/
|
*/
|
||||||
CC_FORCE_INLINE
|
CC_FORCE_INLINE
|
||||||
static inline void roRelease(referenced_object_c *rop) {
|
static inline void roRelease(void *ip) {
|
||||||
|
referenced_object_c *objp = (referenced_object_c *)ip;
|
||||||
|
|
||||||
return rop->vmt->release((void *)rop);
|
return objp->vmt->release(ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* OOP_REFERENCED_OBJECT_H */
|
#endif /* OOP_REFERENCED_OBJECT_H */
|
||||||
|
|
139
os/sb/host/sb.h
139
os/sb/host/sb.h
|
@ -28,6 +28,10 @@
|
||||||
#ifndef SB_H
|
#ifndef SB_H
|
||||||
#define SB_H
|
#define SB_H
|
||||||
|
|
||||||
|
#include "hal.h"
|
||||||
|
#include "vfs.h"
|
||||||
|
#include "errcodes.h"
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Module constants. */
|
/* Module constants. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -146,6 +150,138 @@
|
||||||
/* Module data structures and types. */
|
/* Module data structures and types. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of a sandbox manager global structure.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief Event source for sandbox termination.
|
||||||
|
*/
|
||||||
|
event_source_t termination_es;
|
||||||
|
#endif
|
||||||
|
} sb_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of a sandbox memory region.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* @brief Associated memory area.
|
||||||
|
*/
|
||||||
|
memory_area_t area;
|
||||||
|
/**
|
||||||
|
* @brief Writable memory range.
|
||||||
|
*/
|
||||||
|
bool writeable;
|
||||||
|
} sb_memory_region_t;
|
||||||
|
|
||||||
|
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief Type of a sandbox I/O structure.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* @brief VFS nodes associated to file descriptors.
|
||||||
|
*/
|
||||||
|
vfs_node_c *vfs_nodes[SB_CFG_FD_NUM];
|
||||||
|
/**
|
||||||
|
* @brief Extra attributes added to the VFS nodes.
|
||||||
|
*/
|
||||||
|
uint8_t attributes[SB_CFG_FD_NUM];
|
||||||
|
} sb_ioblock_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of a sandbox configuration structure.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* @brief Memory region for code.
|
||||||
|
* @note It is used to locate the startup header.
|
||||||
|
*/
|
||||||
|
uint32_t code_region;
|
||||||
|
/**
|
||||||
|
* @brief Memory region for data and stack.
|
||||||
|
* @note It is used for initial PSP placement.
|
||||||
|
*/
|
||||||
|
uint32_t data_region;
|
||||||
|
/**
|
||||||
|
* @brief SandBox regions.
|
||||||
|
* @note The following memory regions are used only for pointers
|
||||||
|
* validation, not for MPU setup.
|
||||||
|
*/
|
||||||
|
sb_memory_region_t regions[SB_CFG_NUM_REGIONS];
|
||||||
|
#if (PORT_SWITCHED_REGIONS_NUMBER == SB_CFG_NUM_REGIONS) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief MPU regions initialization values.
|
||||||
|
* @note Regions initialization values must be chosen to be
|
||||||
|
* consistent with the values in the "regions" field.
|
||||||
|
*/
|
||||||
|
mpureg_t mpuregs[SB_CFG_NUM_REGIONS];
|
||||||
|
#endif
|
||||||
|
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief VFS driver associated to the sandbox as root.
|
||||||
|
*/
|
||||||
|
vfs_driver_c *vfs_driver;
|
||||||
|
#else
|
||||||
|
/**
|
||||||
|
* @brief Sandbox STDIN stream.
|
||||||
|
* @note Set this to @p NULL if standard I/O is not needed.
|
||||||
|
* @note By design you can use HAL streams here, you need to use
|
||||||
|
* a cast however.
|
||||||
|
*/
|
||||||
|
SandboxStream *stdin_stream;
|
||||||
|
/**
|
||||||
|
* @brief Sandbox STDOUT stream.
|
||||||
|
* @note Set this to @p NULL if standard I/O is not needed.
|
||||||
|
* @note By design you can use HAL streams here, you need to use
|
||||||
|
* a cast however.
|
||||||
|
*/
|
||||||
|
SandboxStream *stdout_stream;
|
||||||
|
/**
|
||||||
|
* @brief Sandbox STDERR stream.
|
||||||
|
* @note Set this to @p NULL if standard I/O is not needed.
|
||||||
|
* @note By design you can use HAL streams here, you need to use
|
||||||
|
* a cast however.
|
||||||
|
*/
|
||||||
|
SandboxStream *stderr_stream;
|
||||||
|
#endif
|
||||||
|
} sb_config_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of a sandbox object.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/**
|
||||||
|
* @brief Pointer to the sandbox configuration data.
|
||||||
|
*/
|
||||||
|
const sb_config_t *config;
|
||||||
|
/**
|
||||||
|
* @brief Thread running in the sandbox.
|
||||||
|
*/
|
||||||
|
thread_t *tp;
|
||||||
|
#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief Thread sending a message to the sandbox.
|
||||||
|
*/
|
||||||
|
thread_t *msg_tp;
|
||||||
|
#endif
|
||||||
|
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief Sandbox events source.
|
||||||
|
*/
|
||||||
|
event_source_t es;
|
||||||
|
#endif
|
||||||
|
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief VFS bindings for Posix API.
|
||||||
|
*/
|
||||||
|
sb_ioblock_t io;
|
||||||
|
#endif
|
||||||
|
} sb_class_t;
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Module macros. */
|
/* Module macros. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -166,9 +302,6 @@ extern "C" {
|
||||||
/* Module inline functions. */
|
/* Module inline functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
#include "errcodes.h"
|
|
||||||
|
|
||||||
#include "sbsysc.h"
|
#include "sbsysc.h"
|
||||||
#include "sbposix.h"
|
#include "sbposix.h"
|
||||||
#include "sbapi.h"
|
#include "sbapi.h"
|
||||||
|
|
|
@ -100,12 +100,13 @@ bool sb_is_valid_string_range(sb_class_t *sbcp, const char *s, size_t n) {
|
||||||
* @brief Sandbox object initialization.
|
* @brief Sandbox object initialization.
|
||||||
*
|
*
|
||||||
* @param[out] sbcp pointer to the sandbox object
|
* @param[out] sbcp pointer to the sandbox object
|
||||||
|
* @param[in] config pointer to the sandbox configuration
|
||||||
*
|
*
|
||||||
* @init
|
* @init
|
||||||
*/
|
*/
|
||||||
void sbObjectInit(sb_class_t *sbcp) {
|
void sbObjectInit(sb_class_t *sbcp, const sb_config_t *config) {
|
||||||
|
|
||||||
sbcp->config = NULL;
|
sbcp->config = config;
|
||||||
sbcp->tp = NULL;
|
sbcp->tp = NULL;
|
||||||
#if CH_CFG_USE_MESSAGES == TRUE
|
#if CH_CFG_USE_MESSAGES == TRUE
|
||||||
sbcp->msg_tp = NULL;
|
sbcp->msg_tp = NULL;
|
||||||
|
@ -118,16 +119,20 @@ void sbObjectInit(sb_class_t *sbcp) {
|
||||||
/**
|
/**
|
||||||
* @brief Starts a sandboxed thread.
|
* @brief Starts a sandboxed thread.
|
||||||
*
|
*
|
||||||
* @param[out] sbcp pointer to the sandbox object
|
* @param[in] sbcp pointer to a @p sb_class_t structure
|
||||||
* @param[in] config pointer to the sandbox configuration
|
* @param[in] name name to be assigned to the thread
|
||||||
|
* @param[out] wsp pointer to a working area dedicated to the thread stack
|
||||||
|
* @param[in] size size of the working area
|
||||||
|
* @param[in] prio the priority level for the new thread
|
||||||
* @return The thread pointer.
|
* @return The thread pointer.
|
||||||
* @retval NULL if the sandbox thread creation failed.
|
* @retval NULL if the sandbox thread creation failed.
|
||||||
*/
|
*/
|
||||||
thread_t *sbStartThread(sb_class_t *sbcp, const sb_config_t *config,
|
thread_t *sbStartThread(sb_class_t *sbcp, const char *name,
|
||||||
const char *name, void *wsp, size_t size,
|
void *wsp, size_t size,
|
||||||
tprio_t prio) {
|
tprio_t prio) {
|
||||||
thread_t *utp;
|
thread_t *utp;
|
||||||
const sb_header_t *sbhp;
|
const sb_header_t *sbhp;
|
||||||
|
const sb_config_t *config = sbcp->config;
|
||||||
|
|
||||||
/* Header location.*/
|
/* Header location.*/
|
||||||
sbhp = (const sb_header_t *)(void *)config->regions[config->code_region].area.base;
|
sbhp = (const sb_header_t *)(void *)config->regions[config->code_region].area.base;
|
||||||
|
@ -142,9 +147,6 @@ thread_t *sbStartThread(sb_class_t *sbcp, const sb_config_t *config,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Linking configuration information.*/
|
|
||||||
sbcp->config = config;
|
|
||||||
|
|
||||||
unprivileged_thread_descriptor_t utd = {
|
unprivileged_thread_descriptor_t utd = {
|
||||||
.name = name,
|
.name = name,
|
||||||
.wbase = (stkalign_t *)wsp,
|
.wbase = (stkalign_t *)wsp,
|
||||||
|
@ -166,12 +168,6 @@ thread_t *sbStartThread(sb_class_t *sbcp, const sb_config_t *config,
|
||||||
|
|
||||||
/* For messages exchange.*/
|
/* For messages exchange.*/
|
||||||
sbcp->tp = utp;
|
sbcp->tp = utp;
|
||||||
#if CH_CFG_USE_MESSAGES == TRUE
|
|
||||||
sbcp->msg_tp = NULL;
|
|
||||||
#endif
|
|
||||||
#if CH_CFG_USE_EVENTS == TRUE
|
|
||||||
chEvtObjectInit(&sbcp->es);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return utp;
|
return utp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,115 +52,6 @@
|
||||||
/* Module data structures and types. */
|
/* Module data structures and types. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Type of a sandbox manager global structure.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
|
|
||||||
/**
|
|
||||||
* @brief Event source for sandbox termination.
|
|
||||||
*/
|
|
||||||
event_source_t termination_es;
|
|
||||||
#endif
|
|
||||||
} sb_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Type of a sandbox memory region.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
/**
|
|
||||||
* @brief Associated memory area.
|
|
||||||
*/
|
|
||||||
memory_area_t area;
|
|
||||||
/**
|
|
||||||
* @brief Writable memory range.
|
|
||||||
*/
|
|
||||||
bool writeable;
|
|
||||||
} sb_memory_region_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Type of a sandbox configuration structure.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
/**
|
|
||||||
* @brief Memory region for code.
|
|
||||||
* @note It is used to locate the startup header.
|
|
||||||
*/
|
|
||||||
uint32_t code_region;
|
|
||||||
/**
|
|
||||||
* @brief Memory region for data and stack.
|
|
||||||
* @note It is used for initial PSP placement.
|
|
||||||
*/
|
|
||||||
uint32_t data_region;
|
|
||||||
/**
|
|
||||||
* @brief SandBox regions.
|
|
||||||
* @note The following memory regions are used only for pointers
|
|
||||||
* validation, not for MPU setup.
|
|
||||||
*/
|
|
||||||
sb_memory_region_t regions[SB_CFG_NUM_REGIONS];
|
|
||||||
#if (PORT_SWITCHED_REGIONS_NUMBER == SB_CFG_NUM_REGIONS) || defined(__DOXYGEN__)
|
|
||||||
/**
|
|
||||||
* @brief MPU regions initialization values.
|
|
||||||
* @note Regions initialization values must be chosen to be
|
|
||||||
* consistent with the values in the "regions" field.
|
|
||||||
*/
|
|
||||||
mpureg_t mpuregs[SB_CFG_NUM_REGIONS];
|
|
||||||
#endif
|
|
||||||
/**
|
|
||||||
* @brief Sandbox STDIN stream.
|
|
||||||
* @note Set this to @p NULL if standard I/O is not needed.
|
|
||||||
* @note By design you can use HAL streams here, you need to use
|
|
||||||
* a cast however.
|
|
||||||
*/
|
|
||||||
SandboxStream *stdin_stream;
|
|
||||||
/**
|
|
||||||
* @brief Sandbox STDOUT stream.
|
|
||||||
* @note Set this to @p NULL if standard I/O is not needed.
|
|
||||||
* @note By design you can use HAL streams here, you need to use
|
|
||||||
* a cast however.
|
|
||||||
*/
|
|
||||||
SandboxStream *stdout_stream;
|
|
||||||
/**
|
|
||||||
* @brief Sandbox STDERR stream.
|
|
||||||
* @note Set this to @p NULL if standard I/O is not needed.
|
|
||||||
* @note By design you can use HAL streams here, you need to use
|
|
||||||
* a cast however.
|
|
||||||
*/
|
|
||||||
SandboxStream *stderr_stream;
|
|
||||||
} sb_config_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Type of a sandbox object.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
/**
|
|
||||||
* @brief Pointer to the sandbox configuration data.
|
|
||||||
*/
|
|
||||||
const sb_config_t *config;
|
|
||||||
/**
|
|
||||||
* @brief Thread running in the sandbox.
|
|
||||||
*/
|
|
||||||
thread_t *tp;
|
|
||||||
#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
|
|
||||||
/**
|
|
||||||
* @brief Thread sending a message to the sandbox.
|
|
||||||
*/
|
|
||||||
thread_t *msg_tp;
|
|
||||||
#endif
|
|
||||||
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
|
|
||||||
/**
|
|
||||||
* @brief Sandbox events source.
|
|
||||||
*/
|
|
||||||
event_source_t es;
|
|
||||||
#endif
|
|
||||||
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
|
|
||||||
/**
|
|
||||||
* @brief VFS bindings for Posix API.
|
|
||||||
*/
|
|
||||||
sb_ioblock_t io;
|
|
||||||
#endif
|
|
||||||
} sb_class_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type of a sandbox binary image header.
|
* @brief Type of a sandbox binary image header.
|
||||||
*/
|
*/
|
||||||
|
@ -200,10 +91,9 @@ extern "C" {
|
||||||
bool sb_is_valid_read_range(sb_class_t *sbcp, const void *start, size_t size);
|
bool sb_is_valid_read_range(sb_class_t *sbcp, const void *start, size_t size);
|
||||||
bool sb_is_valid_write_range(sb_class_t *sbcp, void *start, size_t size);
|
bool sb_is_valid_write_range(sb_class_t *sbcp, void *start, size_t size);
|
||||||
bool sb_is_valid_string_range(sb_class_t *sbcp, const char *s, size_t n);
|
bool sb_is_valid_string_range(sb_class_t *sbcp, const char *s, size_t n);
|
||||||
void sbObjectInit(sb_class_t *sbcp);
|
void sbObjectInit(sb_class_t *sbcp, const sb_config_t *config);
|
||||||
void sbStart(sb_class_t *sbcp, const sb_config_t *config);
|
thread_t *sbStartThread(sb_class_t *sbcp, const char *name,
|
||||||
thread_t *sbStartThread(sb_class_t *sbcp, const sb_config_t *config,
|
void *wsp, size_t size,
|
||||||
const char *name, void *wsp, size_t size,
|
|
||||||
tprio_t prio);
|
tprio_t prio);
|
||||||
msg_t sbSendMessageTimeout(sb_class_t *sbcp,
|
msg_t sbSendMessageTimeout(sb_class_t *sbcp,
|
||||||
msg_t msg,
|
msg_t msg,
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
/* Module local functions. */
|
/* Module local functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
|
||||||
static msg_t create_descriptor(sb_ioblock_t *iop,
|
static msg_t create_descriptor(sb_ioblock_t *iop,
|
||||||
vfs_node_c *np,
|
vfs_node_c *np,
|
||||||
uint8_t attributes) {
|
uint8_t attributes) {
|
||||||
|
@ -69,6 +70,7 @@ static bool is_valid_descriptor(sb_ioblock_t *iop, int fd) {
|
||||||
|
|
||||||
return (fd >= 0) && (fd < SB_CFG_FD_NUM) && (iop->vfs_nodes[fd] != NULL);
|
return (fd >= 0) && (fd < SB_CFG_FD_NUM) && (iop->vfs_nodes[fd] != NULL);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Module exported functions. */
|
/* Module exported functions. */
|
||||||
|
@ -85,7 +87,8 @@ int sb_posix_open(const char *path, int flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = vfsDrvOpenFile(sbp->io.vfs_driver, path, (unsigned)flags, &fnp);
|
ret = vfsDrvOpenFile(sbp->config->vfs_driver, path,
|
||||||
|
(unsigned)flags, &fnp);
|
||||||
CH_BREAK_ON_ERROR(ret);
|
CH_BREAK_ON_ERROR(ret);
|
||||||
|
|
||||||
ret = create_descriptor(&sbp->io, (vfs_node_c *)fnp, 0);
|
ret = create_descriptor(&sbp->io, (vfs_node_c *)fnp, 0);
|
||||||
|
@ -122,7 +125,7 @@ int sb_posix_close(int fd) {
|
||||||
ssize_t sb_posix_read(int fd, void *buf, size_t count) {
|
ssize_t sb_posix_read(int fd, void *buf, size_t count) {
|
||||||
sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
|
sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
|
||||||
|
|
||||||
if (!sb_is_valid_read_range(sbp, (void *)buf, count)) {
|
if (!sb_is_valid_write_range(sbp, (void *)buf, count)) {
|
||||||
return CH_RET_EFAULT;
|
return CH_RET_EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +143,7 @@ ssize_t sb_posix_read(int fd, void *buf, size_t count) {
|
||||||
ssize_t sb_posix_write(int fd, const void *buf, size_t count) {
|
ssize_t sb_posix_write(int fd, const void *buf, size_t count) {
|
||||||
sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
|
sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
|
||||||
|
|
||||||
if (!sb_is_valid_write_range(sbp, (void *)buf, count)) {
|
if (!sb_is_valid_read_range(sbp, (void *)buf, count)) {
|
||||||
return CH_RET_EFAULT;
|
return CH_RET_EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,6 +171,18 @@ off_t sb_posix_lseek(int fd, off_t offset, int whence) {
|
||||||
return CH_RET_EBADF;
|
return CH_RET_EBADF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sbPosixRegisterFileDescriptor(sb_class_t *sbp,
|
||||||
|
int fd,
|
||||||
|
vfs_file_node_c *fnp) {
|
||||||
|
|
||||||
|
chDbgAssert(is_valid_descriptor(&sbp->io, fd) &&
|
||||||
|
sbp->io.vfs_nodes[fd] == NULL,
|
||||||
|
"invalid file descriptor");
|
||||||
|
|
||||||
|
sbp->io.vfs_nodes[fd] = (vfs_node_c *)fnp;
|
||||||
|
sbp->io.attributes[fd] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
#else /* Fallbacks for when there is no VFS.*/
|
#else /* Fallbacks for when there is no VFS.*/
|
||||||
uint32_t sb_posix_open(const char *pathname, uint32_t flags) {
|
uint32_t sb_posix_open(const char *pathname, uint32_t flags) {
|
||||||
|
|
||||||
|
|
|
@ -48,26 +48,6 @@
|
||||||
/* Module data structures and types. */
|
/* Module data structures and types. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
#if (SB_CFG_ENABLE_VFS == TRUE) || defined(__DOXYGEN__)
|
|
||||||
/**
|
|
||||||
* @brief Type of a sandbox I/O structure.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
/**
|
|
||||||
* @brief VFS driver associated to the sandbox as root.
|
|
||||||
*/
|
|
||||||
vfs_driver_c *vfs_driver;
|
|
||||||
/**
|
|
||||||
* @brief VFS nodes associated to file descriptors.
|
|
||||||
*/
|
|
||||||
vfs_node_c *vfs_nodes[SB_CFG_FD_NUM];
|
|
||||||
/**
|
|
||||||
* @brief Extra attributes added to the VFS nodes.
|
|
||||||
*/
|
|
||||||
uint8_t attributes[SB_CFG_FD_NUM];
|
|
||||||
} sb_ioblock_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Module macros. */
|
/* Module macros. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -84,6 +64,11 @@ extern "C" {
|
||||||
ssize_t sb_posix_read(int fd, void *buf, size_t count);
|
ssize_t sb_posix_read(int fd, void *buf, size_t count);
|
||||||
ssize_t sb_posix_write(int fd, const void *buf, size_t count);
|
ssize_t sb_posix_write(int fd, const void *buf, size_t count);
|
||||||
off_t sb_posix_lseek(int fd, off_t offset, int whence);
|
off_t sb_posix_lseek(int fd, off_t offset, int whence);
|
||||||
|
#if SB_CFG_ENABLE_VFS == TRUE
|
||||||
|
void sbPosixRegisterFileDescriptor(sb_class_t *sbp,
|
||||||
|
int fd,
|
||||||
|
vfs_file_node_c *fnp);
|
||||||
|
#endif
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,9 +23,23 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "errcodes.h"
|
||||||
#include "sbuser.h"
|
#include "sbuser.h"
|
||||||
|
|
||||||
#define MAKERR(e) (-(int)(e))
|
__attribute__((used))
|
||||||
|
int _open_r(struct _reent *r, const char *p, int oflag, int mode) {
|
||||||
|
uint32_t err;
|
||||||
|
|
||||||
|
(void)mode;
|
||||||
|
|
||||||
|
err = sbFileOpen(p, oflag);
|
||||||
|
if (CH_RET_IS_ERROR(err)) {
|
||||||
|
__errno_r(r) = CH_DECODE_ERROR(err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
__attribute__((used))
|
__attribute__((used))
|
||||||
int _close_r(struct _reent *r, int file) {
|
int _close_r(struct _reent *r, int file) {
|
||||||
|
@ -33,7 +47,7 @@ int _close_r(struct _reent *r, int file) {
|
||||||
|
|
||||||
err = sbFileClose((uint32_t)file);
|
err = sbFileClose((uint32_t)file);
|
||||||
if (CH_RET_IS_ERROR(err)) {
|
if (CH_RET_IS_ERROR(err)) {
|
||||||
__errno_r(r) = MAKERR(err);
|
__errno_r(r) = CH_DECODE_ERROR(err);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +60,7 @@ int _write_r(struct _reent *r, int file, char * ptr, int len) {
|
||||||
|
|
||||||
err = sbFileWrite((uint32_t)file, (const uint8_t *)ptr, (size_t)len);
|
err = sbFileWrite((uint32_t)file, (const uint8_t *)ptr, (size_t)len);
|
||||||
if (CH_RET_IS_ERROR(err)) {
|
if (CH_RET_IS_ERROR(err)) {
|
||||||
__errno_r(r) = MAKERR(err);
|
__errno_r(r) = CH_DECODE_ERROR(err);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +73,7 @@ int _read_r(struct _reent *r, int file, char * ptr, int len) {
|
||||||
|
|
||||||
err = sbFileRead((uint32_t)file, (uint8_t *)ptr, (size_t)len);
|
err = sbFileRead((uint32_t)file, (uint8_t *)ptr, (size_t)len);
|
||||||
if (CH_RET_IS_ERROR(err)) {
|
if (CH_RET_IS_ERROR(err)) {
|
||||||
__errno_r(r) = MAKERR(err);
|
__errno_r(r) = CH_DECODE_ERROR(err);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +86,7 @@ int _lseek_r(struct _reent *r, int file, int ptr, int dir) {
|
||||||
|
|
||||||
err = sbFileSeek((uint32_t)file, (uint32_t)ptr, (uint32_t)dir);
|
err = sbFileSeek((uint32_t)file, (uint32_t)ptr, (uint32_t)dir);
|
||||||
if (CH_RET_IS_ERROR(err)) {
|
if (CH_RET_IS_ERROR(err)) {
|
||||||
__errno_r(r) = MAKERR(err);
|
__errno_r(r) = CH_DECODE_ERROR(err);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue