apps/examples/module: Add a test harness for testing NuttX kernel modules

This commit is contained in:
Gregory Nutt 2015-12-12 09:43:32 -06:00
parent cfcd396861
commit d02295d1f2
15 changed files with 891 additions and 0 deletions

View File

@ -1498,4 +1498,6 @@
at /dev/telnetN (2015-12-07).
* netutils/ping: Unfinished implementation of ping/ping6 using raw
sockets (2015-12-11).
* examples/module: Add a test harness for verifying NuttX kernel
modules (2015-12-12).

View File

@ -33,6 +33,7 @@ source "$APPSDIR/examples/ltdc/Kconfig"
source "$APPSDIR/examples/media/Kconfig"
source "$APPSDIR/examples/mm/Kconfig"
source "$APPSDIR/examples/modbus/Kconfig"
source "$APPSDIR/examples/module/Kconfig"
source "$APPSDIR/examples/mount/Kconfig"
source "$APPSDIR/examples/mtdpart/Kconfig"
source "$APPSDIR/examples/mtdrwb/Kconfig"

View File

@ -738,6 +738,68 @@ examples/mm
This is a simple test of the memory manager.
examples/module
^^^^^^^^^^^^^^
This example builds a small loadable module test case. This includes on
character driver under examples/module/drivers. This driver is built using
the relocatable ELF format and installed in a ROMFS file system. At run time,
the driver module is loaded and exercises. Requires CONFIG_MODULE.
Other configuration options:
CONFIG_EXAMPLES_ELF_DEVMINOR - The minor device number of the ROMFS block
driver. For example, the N in /dev/ramN. Used for registering the RAM
block driver that will hold the ROMFS file system containing the ELF
executables to be tested. Default: 0
CONFIG_EXAMPLES_ELF_DEVPATH - The path to the ROMFS block driver device. This
must match EXAMPLES_ELF_DEVMINOR. Used for registering the RAM block driver
that will hold the ROMFS file system containing the ELF executables to be
tested. Default: "/dev/ram0"
NOTES:
1. CFLAGS should be provided in CELFFLAGS. RAM and FLASH memory regions
may require long allcs. For ARM, this might be:
CELFFLAGS = $(CFLAGS) -mlong-calls
Similarly for C++ flags which must be provided in CXXELFFLAGS.
2. Your top-level nuttx/Make.defs file must also include an approproate definition,
LDELFFLAGS, to generate a relocatable ELF object. With GNU LD, this should
include '-r' and '-e <entry point>'.
LDELFFLAGS = -r -e module_initialize
If you use GCC to link, you make also need to include '-nostdlib' or
'-nostartfiles' and '-nodefaultlibs'.
3. This example also requires genromfs. genromfs can be build as part of the
nuttx toolchain. Or can built from the genromfs sources that can be found
in the NuttX tools repository (genromfs-0.5.2.tar.gz). In any event, the
PATH variable must include the path to the genromfs executable.
4. ELF size: The ELF files in this example are, be default, quite large
because they include a lot of "build garbage". You can greatly reduce the
size of the ELF binaries are using the 'objcopy --strip-unneeded' command to
remove un-necessary information from the ELF files.
5. Simulator. You cannot use this example with the the NuttX simulator on
Cygwin. That is because the Cygwin GCC does not generate ELF file but
rather some Windows-native binary format.
If you really want to do this, you can create a NuttX x86 buildroot toolchain
and use that be build the ELF executables for the ROMFS file system.
6. Linker scripts. You might also want to use a linker scripts to combine
sections better. An example linker script is at nuttx/sched/module/gnu-elf.ld.
That example might have to be tuned for your particular linker output to
position additional sections correctly. The GNU LD LDELFFLAGS then might
be:
LDELFFLAGS = -r -e module_initialize -T$(TOPDIR)/sched/module/gnu-elf.ld
examples/modbus
^^^^^^^^^^^^^^^

3
examples/module/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/Make.dep
/.depend
/.built

45
examples/module/Kconfig Normal file
View File

@ -0,0 +1,45 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
config EXAMPLES_MODULE
bool "Module Example"
default n
---help---
Enable the module example
if EXAMPLES_MODULE
config EXAMPLES_MODULE_LIBC
bool "Link with LIBC"
default n
depends on !BUILD_KERNEL
---help---
Link with the C library (and also math library if it was built).
By default, all undefined symbols must be provided via a symbol
table. But if this option is selected, then each MODULE test program
will link with the SYSCALL library and will interface with the OS
system calls. You probably will NOT want this option, however,
because it will substantially increase the size of code. For
example, a separate copy of printf() would be linked with every
program greatly increasing the total code size. This option is
primarily intended only for testing.
config EXAMPLES_MODULE_DEVMINOR
int "ROMFS Minor Device Number"
default 0
---help---
The minor device number of the ROMFS block. For example, the N in /dev/ramN.
Used for registering the RAM block driver that will hold the ROMFS file system
containing the MODULE executables to be tested. Default: 0
config EXAMPLES_MODULE_DEVPATH
string "ROMFS Device Path"
default "/dev/ram0"
---help---
The path to the ROMFS block driver device. This must match EXAMPLES_MODULE_DEVMINOR.
Used for registering the RAM block driver that will hold the ROMFS file system
containing the MODULE executables to be tested. Default: "/dev/ram0"
endif

38
examples/module/Make.defs Normal file
View File

@ -0,0 +1,38 @@
############################################################################
# apps/examples/module/Make.defs
#
# Copyright (C) 2015 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
ifeq ($(CONFIG_EXAMPLES_MODULE),y)
CONFIGURED_APPS += examples/module
endif

151
examples/module/Makefile Normal file
View File

@ -0,0 +1,151 @@
############################################################################
# apps/examples/module/Makefile
#
# Copyright (C) 2015 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
-include $(TOPDIR)/.config
-include $(TOPDIR)/Make.defs
include $(APPDIR)/Make.defs
# Module example built-in application info
APPNAME = module
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = 2048
# Module Example
ASRCS =
CSRCS = symtab.c
MAINSRC = module_main.c
AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))
MAINOBJ = $(MAINSRC:.c=$(OBJEXT))
SRCS = $(ASRCS) $(CSRCS) $(MAINSRC)
OBJS = $(AOBJS) $(COBJS)
ifneq ($(CONFIG_BUILD_KERNEL),y)
OBJS += $(MAINOBJ)
endif
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
BIN = ..\..\libapps$(LIBEXT)
else
ifeq ($(WINTOOL),y)
BIN = ..\\..\\libapps$(LIBEXT)
else
BIN = ../../libapps$(LIBEXT)
endif
endif
ifeq ($(WINTOOL),y)
INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}"
else
INSTALL_DIR = $(BIN_DIR)
endif
CONFIG_XYZ_PROGNAME ?= discover$(EXEEXT)
PROGNAME = $(CONFIG_XYZ_PROGNAME)
ROOTDEPPATH = --dep-path . --dep-path drivers
# Build targets
VPATH = drivers
all: .built
.PHONY: really_build clean_drivers clean depend distclean
$(AOBJS): %$(OBJEXT): %.S
$(call ASSEMBLE, $<, $@)
$(COBJS) $(MAINOBJ): %$(OBJEXT): %.c
$(call COMPILE, $<, $@)
# This is a little messy. The build is broken into two pieces: (1) the
# drivers/ subdir build that auto-generates several files, and (2) the real
# build. This is done because we need a fresh build context after auto-
# generating the source files.
really_build: $(OBJS)
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
.built:
@$(MAKE) -C drivers TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV)
@$(MAKE) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" really_build
ifeq ($(CONFIG_BUILD_KERNEL),y)
$(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJS) $(MAINOBJ)
@echo "LD: $(PROGNAME)"
$(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS)
$(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME)
install: $(BIN_DIR)$(DELIM)$(PROGNAME)
else
install:
endif
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
else
context:
endif
# We can't make dependencies in this directory because the required
# header files may not yet exist.
.depend:
@touch $@
depend: .depend
clean_drivers:
@$(MAKE) -C drivers TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV) clean
clean: clean_drivers
$(call DELFILE, .built)
$(call CLEAN)
distclean: clean
$(call DELFILE, Make.dep)
$(call DELFILE, .depend)
-include Make.dep

6
examples/module/drivers/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
/romfs
/romfs.h
/romfs.img
/symtab.c
/varlist.tmp

View File

@ -0,0 +1,98 @@
############################################################################
# apps/examples/module/drivers/Makefile
#
# Copyright (C) 2015 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
-include $(TOPDIR)/.config
-include $(TOPDIR)/Make.defs
include $(APPDIR)/Make.defs
ALL_SUBDIRS = chardev
BUILD_SUBDIRS = chardev
MODULE_DIR = $(APPDIR)/examples/module
DRIVER_DIR = $(MODULE_DIR)/drivers
ROMFS_DIR = $(DRIVER_DIR)/romfs
ROMFS_IMG = $(DRIVER_DIR)/romfs.img
ROMFS_HDR = $(DRIVER_DIR)/romfs.h
SYMTAB_SRC = $(DRIVER_DIR)/symtab.c
define DIR_template
$(1)_$(2):
$(Q) $(MAKE) -C $(1) $(3) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)" CROSSDEV=$(CROSSDEV)
endef
all: $(ROMFS_HDR) $(DIRLIST_HDR) $(SYMTAB_SRC)
.PHONY: all build clean install populate
$(foreach DIR, $(BUILD_SUBDIRS), $(eval $(call DIR_template,$(DIR),build, all)))
$(foreach DIR, $(ALL_SUBDIRS), $(eval $(call DIR_template,$(DIR),clean,clean)))
$(foreach DIR, $(BUILD_SUBDIRS), $(eval $(call DIR_template,$(DIR),install,install)))
# Build program(s) in each sud-directory
build: $(foreach DIR, $(BUILD_SUBDIRS), $(DIR)_build)
# Install each program in the romfs directory
install: $(foreach DIR, $(BUILD_SUBDIRS), $(DIR)_install)
# Create the romfs directory
$(ROMFS_DIR):
$(Q) mkdir $(ROMFS_DIR)
# Populate the romfs directory
populate: $(ROMFS_DIR) build install
# Create the romfs.img file from the populated romfs directory
$(ROMFS_IMG): populate
$(Q) genromfs -f $@ -d $(ROMFS_DIR) -V "MODULETEST"
# Create the romfs.h header file from the romfs.img file
$(ROMFS_HDR) : $(ROMFS_IMG)
$(Q) (cd $(DRIVER_DIR); xxd -i romfs.img | sed -e "s/^unsigned/static const unsigned/g" >$@)
# Create the exported symbol table
$(SYMTAB_SRC): build
$(Q) $(DRIVER_DIR)/mksymtab.sh $(ROMFS_DIR) >$@
# Clean each subdirectory
clean: $(foreach DIR, $(ALL_SUBDIRS), $(DIR)_clean)
$(Q) rm -f $(ROMFS_HDR) $(DIRLIST_HDR) $(ROMFS_IMG) $(SYMTAB_SRC)
$(Q) rm -rf $(ROMFS_DIR)

View File

@ -0,0 +1,2 @@
hello

View File

@ -0,0 +1,81 @@
############################################################################
# examples/module/drivers/chardev/Makefile
#
# Copyright (C) 2015 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
-include $(TOPDIR)/Make.defs
ifeq ($(WINTOOL),y)
NUTTXLIB = "${shell cygpath -w $(TOPDIR)$(DELIM)lib}"
else
NUTTXLIB = "$(TOPDIR)$(DELIM)lib"
endif
KDEFINE = ${shell $(TOPDIR)/tools/define.sh "$(CC)" __KERNEL__}
CFLAGS += $(KDEFINE)
ifeq ($(CONFIG_EXAMPLES_MODULE_LIBC),y)
LDMODULEFLAGS += -Bstatic
LDLIBPATH += -L $(NUTTXLIB)
endif
ifeq ($(CONFIG_EXAMPLES_MODULE_LIBC),y)
ifeq ($(CONFIG_BUILD_PROTECTED),y)
LDLIBS += -luc
else
LDLIBS += -lc
endif
endif
BIN = chardev
SRCS = $(BIN).c
OBJS = $(SRCS:.c=$(OBJEXT))
all: $(BIN)
$(OBJS): %$(OBJEXT): %.c
@echo "CC: $<"
$(Q) $(CC) -c $(CMODULEFLAGS) $< -o $@
$(BIN): $(OBJS)
@echo "LD: $<"
$(Q) $(LD) $(LDMODULEFLAGS) $(LDLIBPATH) -o $@ $(ARCHCRT0OBJ) $^ $(LDLIBS)
clean:
$(call DMODULEILE, $(BIN))
$(call CLEAN)
install:
$(Q) mkdir -p $(ROMFS_DIR)
$(Q) install $(BIN) $(ROMFS_DIR)/$(BIN)

Binary file not shown.

View File

@ -0,0 +1,142 @@
/****************************************************************************
* apps/examples/module/drivers/chardev/chardev.c
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#include <syslog.h>
#include <debug.h>
#include <nuttx/fs/fs.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef MIN
# define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
/****************************************************************************
* Private data
****************************************************************************/
static const char g_read_string[] = "Hi there, apps/examples/module test\n";
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static ssize_t chardev_read(FAR struct file *filep, FAR char *buffer,
size_t buflen);
static ssize_t chardev_write(FAR struct file *filep, FAR const char *buffer,
size_t buflen);
/****************************************************************************
* Private Data
****************************************************************************/
static const struct file_operations chardev_fops =
{
0, /* open */
0, /* close */
chardev_read, /* read */
chardev_write, /* write */
0, /* seek */
0 /* ioctl */
#ifndef CONFIG_DISABLE_POLL
, 0 /* poll */
#endif
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
, 0 /* unlink */
#endif
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: chardev_read
****************************************************************************/
static ssize_t chardev_read(FAR struct file *filep, FAR char *buffer,
size_t len)
{
size_t rdlen = strlen(g_read_string);
ssize_t ret = MIN(len, rdlen);
memcpy(buffer, g_read_string, ret);
syslog(LOG_INFO, "chardev_read: Returning %d bytes\n", (int)ret);
lib_dumpbuffer("chardev_read: Returning", (FAR const uint8_t *)buffer, ret);
return ret;
}
/****************************************************************************
* Name: chardev_write
****************************************************************************/
static ssize_t chardev_write(FAR struct file *filep, FAR const char *buffer,
size_t len)
{
syslog(LOG_INFO, "chardev_write: Writing %d bytes\n", (int)len);
lib_dumpbuffer("chardev_write: Writing", (FAR const uint8_t *)buffer, len);
return len;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: module_initialize
*
* Description:
* Register /dev/zero
*
****************************************************************************/
void module_initialize(void)
{
(void)register_driver("/dev/chardev", &chardev_fops, 0666, NULL);
}

View File

@ -0,0 +1,51 @@
#!/bin/bash
usage="Usage: $0 <test-dir-path>"
# Check for the required ROMFS directory path
dir=$1
if [ -z "$dir" ]; then
echo "ERROR: Missing <test-dir-path>"
echo ""
echo $usage
exit 1
fi
if [ ! -d "$dir" ]; then
echo "ERROR: Directory $dir does not exist"
echo ""
echo $usage
exit 1
fi
# Extract all of the undefined symbols from the MODULE files and create a
# list of sorted, unique undefined variable names.
varlist=`find ${dir} -executable -type f | xargs nm | fgrep ' U ' | sed -e "s/^[ ]*//g" | cut -d' ' -f2 | sort | uniq`
# Now output the symbol table as a structure in a C source file. All
# undefined symbols are declared as void* types. If the toolchain does
# any kind of checking for function vs. data objects, then this could
# faile
echo "#include <nuttx/compiler.h>"
echo "#include <nuttx/binfmt/symtab.h>"
echo ""
for var in $varlist; do
echo "extern void *${var};"
done
echo ""
echo "const struct symtab_s exports[] = "
echo "{"
for var in $varlist; do
echo " {\"${var}\", &${var}},"
done
echo "};"
echo ""
echo "const int nexports = sizeof(exports) / sizeof(struct symtab_s);"

View File

@ -0,0 +1,209 @@
/****************************************************************************
* examples/module/module_main.c
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <sys/mount.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <syslog.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/fs/ramdisk.h>
#include <nuttx/module.h>
#include <nuttx/binfmt/symtab.h>
#include "drivers/romfs.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Check configuration. This is not all of the configuration settings that
* are required -- only the more obvious.
*/
#if CONFIG_NFILE_DESCRIPTORS < 1
# error "You must provide file descriptors via CONFIG_NFILE_DESCRIPTORS in your configuration file"
#endif
#ifndef CONFIG_MODULE
# error "You must select CONFIG_MODULE in your configuration file"
#endif
#ifndef CONFIG_FS_ROMFS
# error "You must select CONFIG_FS_ROMFS in your configuration file"
#endif
#ifdef CONFIG_DISABLE_MOUNTPOINT
# error "You must not disable mountpoints via CONFIG_DISABLE_MOUNTPOINT in your configuration file"
#endif
/* Describe the ROMFS file system */
#define SECTORSIZE 64
#define NSECTORS(b) (((b)+SECTORSIZE-1)/SECTORSIZE)
#define MOUNTPT "/mnt/romfs"
#ifndef CONFIG_EXAMPLES_MODULE_DEVMINOR
# define CONFIG_EXAMPLES_MODULE_DEVMINOR 0
#endif
#ifndef CONFIG_EXAMPLES_MODULE_DEVPATH
# define CONFIG_EXAMPLES_MODULE_DEVPATH "/dev/ram0"
#endif
/****************************************************************************
* Private data
****************************************************************************/
static const char g_write_string[] = "Hi there, installed driver\n";
/****************************************************************************
* Symbols from Auto-Generated Code
****************************************************************************/
extern const struct symtab_s exports[];
extern const int nexports;
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: module_main
****************************************************************************/
#ifdef CONFIG_BUILD_KERNEL
int main(int argc, FAR char *argv[])
#else
int module_main(int argc, char *argv[])
#endif
{
struct module_s module;
char buffer[128];
ssize_t nbytes;
int ret;
int fd;
/* Create a ROM disk for the ROMFS filesystem */
printf("Registering romdisk at /dev/ram%d\n", CONFIG_EXAMPLES_MODULE_DEVMINOR);
ret = romdisk_register(CONFIG_EXAMPLES_MODULE_DEVMINOR, (FAR uint8_t *)romfs_img,
NSECTORS(romfs_img_len), SECTORSIZE);
if (ret < 0)
{
fprintf(stderr, "ERROR: romdisk_register failed: %d\n", ret);
exit(EXIT_FAILURE);
}
/* Mount the file system */
printf("Mounting ROMFS filesystem at target=%s with source=%s\n",
MOUNTPT, CONFIG_EXAMPLES_MODULE_DEVPATH);
ret = mount(CONFIG_EXAMPLES_MODULE_DEVPATH, MOUNTPT, "romfs", MS_RDONLY, NULL);
if (ret < 0)
{
fprintf(stderr, "ERROR: mount(%s,%s,romfs) failed: %s\n",
CONFIG_EXAMPLES_MODULE_DEVPATH, MOUNTPT, errno);
exit(EXIT_FAILURE);
}
/* Install the character driver */
memset(&module, 0, sizeof(struct module_s));
module.filename = MOUNTPT "/chardev";
module.exports = exports;
module.nexports = nexports;
ret = insmod(&module);
if (ret < 0)
{
fprintf(stderr, "ERROR: insmod failed: %d\n", ret);
exit(EXIT_FAILURE);
}
/* Open the installed character driver */
fd = open("/dev/chardev", O_RDWR);
if (fd < 0)
{
int errcode = errno;
fprintf(stderr, "ERROR: Failed to open /dev/chardev: %d\n", errcode);
exit(EXIT_FAILURE);
}
/* Read from the character driver */
nbytes = read(fd, buffer, 128);
if (nbytes < 0)
{
int errcode = errno;
fprintf(stderr, "ERROR: Read from /dev/chardev failed: %d\n", errcode);
close(fd);
exit(EXIT_FAILURE);
}
printf("Read %d bytes: %d\n", (int)nbytes);
lib_dumpbuffer("Bytes read", (FAR const uint8_t *)buffer, nbytes);
/* Write to the character driver */
nbytes = write(fd, g_write_string, strlen(g_write_string));
if (nbytes < 0)
{
int errcode = errno;
fprintf(stderr, "ERROR: Write to /dev/chardev failed: %d\n", errcode);
close(fd);
exit(EXIT_FAILURE);
}
printf("Wrote %d bytes: %d\n", (int)nbytes);
lib_dumpbuffer("Bytes read", (FAR const uint8_t *)g_write_string, nbytes);
close(fd);
return EXIT_SUCCESS;
}