aboutsummaryrefslogtreecommitdiff
path: root/nuttx/binfmt
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-01-17 14:43:55 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-01-17 14:43:55 +0000
commite9d0885500d437cc6c89370d8131913bd1e7310b (patch)
treed9cf39f88361f174a2350d354ffb5584d43e2fc4 /nuttx/binfmt
parentcaeef71797019505fd450b1a0ae573ac5e490c6e (diff)
downloadpx4-firmware-e9d0885500d437cc6c89370d8131913bd1e7310b.tar.gz
px4-firmware-e9d0885500d437cc6c89370d8131913bd1e7310b.tar.bz2
px4-firmware-e9d0885500d437cc6c89370d8131913bd1e7310b.zip
Add logic to automatically unload module on exit; Several patches from Mike Smith
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5528 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/binfmt')
-rw-r--r--nuttx/binfmt/Makefile4
-rw-r--r--nuttx/binfmt/binfmt_exec.c69
-rw-r--r--nuttx/binfmt/builtin.c8
-rw-r--r--nuttx/binfmt/libbuiltin/libbuiltin_getname.c14
-rw-r--r--nuttx/binfmt/libbuiltin/libbuiltin_isavail.c7
5 files changed, 89 insertions, 13 deletions
diff --git a/nuttx/binfmt/Makefile b/nuttx/binfmt/Makefile
index 49dcd3d32..2f692beb1 100644
--- a/nuttx/binfmt/Makefile
+++ b/nuttx/binfmt/Makefile
@@ -52,6 +52,10 @@ ifeq ($(CONFIG_BINFMT_EXEPATH),y)
BINFMT_CSRCS += binfmt_exepath.c
endif
+ifeq ($(CONFIG_SCHED_HAVE_PARENT),y)
+BINFMT_CSRCS += binfmt_schedunload.c
+endif
+
# Symbol table source files
BINFMT_CSRCS += symtab_findbyname.c symtab_findbyvalue.c
diff --git a/nuttx/binfmt/binfmt_exec.c b/nuttx/binfmt/binfmt_exec.c
index d878c8cc5..1cead4384 100644
--- a/nuttx/binfmt/binfmt_exec.c
+++ b/nuttx/binfmt/binfmt_exec.c
@@ -74,7 +74,9 @@
*
* Description:
* This is a convenience function that wraps load_ and exec_module into
- * one call.
+ * one call. If CONFIG_SCHED_ONEXIT is also defined, this function will
+ * automatically call schedule_unload() to unload the module when task
+ * exits.
*
* Input Parameter:
* filename - Fulll path to the binary to be loaded
@@ -84,7 +86,7 @@
*
* Returned Value:
* This is an end-user function, so it follows the normal convention:
- * Returns the PID of the exec'ed module. On failure, it.returns
+ * It returns the PID of the exec'ed module. On failure, it returns
* -1 (ERROR) and sets errno appropriately.
*
****************************************************************************/
@@ -92,6 +94,66 @@
int exec(FAR const char *filename, FAR const char **argv,
FAR const struct symtab_s *exports, int nexports)
{
+#ifdef CONFIG_SCHED_ONEXIT
+ FAR struct binary_s *bin;
+ int errorcode;
+ int ret;
+
+ /* Allocate the load information */
+
+ bin = (FAR struct binary_s *)kzalloc(sizeof(struct binary_s));
+ if (!bin)
+ {
+ set_errno(ENOMEM);
+ return ERROR;
+ }
+
+ /* Load the module into memory */
+
+ bin->filename = filename;
+ bin->exports = exports;
+ bin->nexports = nexports;
+
+ ret = load_module(bin);
+ if (ret < 0)
+ {
+ bdbg("ERROR: Failed to load program '%s'\n", filename);
+ kfree(bin);
+ return ERROR;
+ }
+
+ /* Disable pre-emption so that the executed module does
+ * not return until we get a chance to connect the on_exit
+ * handler.
+ */
+
+ sched_lock();
+
+ /* Then start the module */
+
+ ret = exec_module(bin);
+ if (ret < 0)
+ {
+ bdbg("ERROR: Failed to execute program '%s'\n", filename);
+ sched_unlock();
+ unload_module(bin);
+ kfree(bin);
+ return ERROR;
+ }
+
+ /* Set up to unload the module (and free the binary_s structure)
+ * when the task exists.
+ */
+
+ ret = schedul_unload(ret, bin);
+ if (ret < 0)
+ {
+ bdbg("ERROR: Failed to schedul unload '%s'\n", filename);
+ }
+
+ sched_unlock();
+ return ret;
+#else
struct binary_s bin;
int ret;
@@ -119,7 +181,10 @@ int exec(FAR const char *filename, FAR const char **argv,
return ERROR;
}
+ /* TODO: How does the module get unloaded in this case? */
+
return ret;
+#endif
}
#endif /* CONFIG_BINFMT_DISABLE */
diff --git a/nuttx/binfmt/builtin.c b/nuttx/binfmt/builtin.c
index d36cb6326..d80d9f5d8 100644
--- a/nuttx/binfmt/builtin.c
+++ b/nuttx/binfmt/builtin.c
@@ -89,6 +89,7 @@ static struct binfmt_s g_builtin_binfmt =
static int builtin_loadbinary(struct binary_s *binp)
{
FAR const char *filename;
+ FAR const struct builtin_s *b;
int fd;
int index;
int ret;
@@ -134,9 +135,10 @@ static int builtin_loadbinary(struct binary_s *binp)
* the priority. That is a bug and needs to be fixed.
*/
- binp->entrypt = g_builtins[index].main;
- binp->stacksize = g_builtins[index].stacksize;
- binp->priority = g_builtins[index].priority;
+ b = builtin_for_index(index);
+ binp->entrypt = b->main;
+ binp->stacksize = b->stacksize;
+ binp->priority = b->priority;
return OK;
}
diff --git a/nuttx/binfmt/libbuiltin/libbuiltin_getname.c b/nuttx/binfmt/libbuiltin/libbuiltin_getname.c
index 01ac024f7..9da2bac29 100644
--- a/nuttx/binfmt/libbuiltin/libbuiltin_getname.c
+++ b/nuttx/binfmt/libbuiltin/libbuiltin_getname.c
@@ -83,10 +83,14 @@
FAR const char *builtin_getname(int index)
{
- if (index < 0 || index >= number_builtins())
- {
- return NULL;
- }
+ struct builtin_s *b;
- return g_builtins[index].name;
+ b = builtin_for_index(index);
+
+ if (b != NULL)
+ {
+ return b->name;
+ }
+
+ return NULL;
}
diff --git a/nuttx/binfmt/libbuiltin/libbuiltin_isavail.c b/nuttx/binfmt/libbuiltin/libbuiltin_isavail.c
index f99a4b81d..b1d55ff21 100644
--- a/nuttx/binfmt/libbuiltin/libbuiltin_isavail.c
+++ b/nuttx/binfmt/libbuiltin/libbuiltin_isavail.c
@@ -80,18 +80,19 @@
* Name: builtin_isavail
*
* Description:
- * Return the index into the table of applications for the applicaiton with
+ * Return the index into the table of applications for the application with
* the name 'appname'.
*
****************************************************************************/
int builtin_isavail(FAR const char *appname)
{
+ FAR const char *n;
int i;
- for (i = 0; g_builtins[i].name; i++)
+ for (i = 0; n = builtin_getname(i); i++)
{
- if (!strncmp(g_builtins[i].name, appname, NAME_MAX))
+ if (!strncmp(n, appname, NAME_MAX))
{
return i;
}