apps/examples/module: Add a test harness for testing NuttX kernel modules
This commit is contained in:
parent
cfcd396861
commit
d02295d1f2
@ -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).
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
3
examples/module/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/Make.dep
|
||||
/.depend
|
||||
/.built
|
45
examples/module/Kconfig
Normal file
45
examples/module/Kconfig
Normal 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
38
examples/module/Make.defs
Normal 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
151
examples/module/Makefile
Normal 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
6
examples/module/drivers/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/romfs
|
||||
/romfs.h
|
||||
/romfs.img
|
||||
/symtab.c
|
||||
/varlist.tmp
|
||||
|
98
examples/module/drivers/Makefile
Normal file
98
examples/module/drivers/Makefile
Normal 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)
|
2
examples/module/drivers/chardev/.gitignore
vendored
Normal file
2
examples/module/drivers/chardev/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
hello
|
||||
|
81
examples/module/drivers/chardev/Makefile
Normal file
81
examples/module/drivers/chardev/Makefile
Normal 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)
|
BIN
examples/module/drivers/chardev/chardev
Normal file
BIN
examples/module/drivers/chardev/chardev
Normal file
Binary file not shown.
142
examples/module/drivers/chardev/chardev.c
Normal file
142
examples/module/drivers/chardev/chardev.c
Normal 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);
|
||||
}
|
51
examples/module/drivers/mksymtab.sh
Normal file
51
examples/module/drivers/mksymtab.sh
Normal 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);"
|
||||
|
209
examples/module/module_main.c
Normal file
209
examples/module/module_main.c
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user