From d02295d1f26ec96357c26f354fcd34c56aa4e191 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 12 Dec 2015 09:43:32 -0600 Subject: [PATCH] apps/examples/module: Add a test harness for testing NuttX kernel modules --- ChangeLog.txt | 2 + examples/Kconfig | 1 + examples/README.txt | 62 ++++++ examples/module/.gitignore | 3 + examples/module/Kconfig | 45 +++++ examples/module/Make.defs | 38 ++++ examples/module/Makefile | 151 +++++++++++++++ examples/module/drivers/.gitignore | 6 + examples/module/drivers/Makefile | 98 ++++++++++ examples/module/drivers/chardev/.gitignore | 2 + examples/module/drivers/chardev/Makefile | 81 ++++++++ examples/module/drivers/chardev/chardev | Bin 0 -> 54462 bytes examples/module/drivers/chardev/chardev.c | 142 ++++++++++++++ examples/module/drivers/mksymtab.sh | 51 +++++ examples/module/module_main.c | 209 +++++++++++++++++++++ 15 files changed, 891 insertions(+) create mode 100644 examples/module/.gitignore create mode 100644 examples/module/Kconfig create mode 100644 examples/module/Make.defs create mode 100644 examples/module/Makefile create mode 100644 examples/module/drivers/.gitignore create mode 100644 examples/module/drivers/Makefile create mode 100644 examples/module/drivers/chardev/.gitignore create mode 100644 examples/module/drivers/chardev/Makefile create mode 100644 examples/module/drivers/chardev/chardev create mode 100644 examples/module/drivers/chardev/chardev.c create mode 100644 examples/module/drivers/mksymtab.sh create mode 100644 examples/module/module_main.c diff --git a/ChangeLog.txt b/ChangeLog.txt index aa1b8a62b..a98e0a872 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -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). diff --git a/examples/Kconfig b/examples/Kconfig index f7fa2c8fa..e50fa1e21 100644 --- a/examples/Kconfig +++ b/examples/Kconfig @@ -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" diff --git a/examples/README.txt b/examples/README.txt index 67a3ad872..919040f24 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -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 '. + + 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 ^^^^^^^^^^^^^^^ diff --git a/examples/module/.gitignore b/examples/module/.gitignore new file mode 100644 index 000000000..4cfc495be --- /dev/null +++ b/examples/module/.gitignore @@ -0,0 +1,3 @@ +/Make.dep +/.depend +/.built diff --git a/examples/module/Kconfig b/examples/module/Kconfig new file mode 100644 index 000000000..a4f9d7802 --- /dev/null +++ b/examples/module/Kconfig @@ -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 diff --git a/examples/module/Make.defs b/examples/module/Make.defs new file mode 100644 index 000000000..0a012432d --- /dev/null +++ b/examples/module/Make.defs @@ -0,0 +1,38 @@ +############################################################################ +# apps/examples/module/Make.defs +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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 diff --git a/examples/module/Makefile b/examples/module/Makefile new file mode 100644 index 000000000..f869adf30 --- /dev/null +++ b/examples/module/Makefile @@ -0,0 +1,151 @@ +############################################################################ +# apps/examples/module/Makefile +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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 diff --git a/examples/module/drivers/.gitignore b/examples/module/drivers/.gitignore new file mode 100644 index 000000000..500f6638f --- /dev/null +++ b/examples/module/drivers/.gitignore @@ -0,0 +1,6 @@ +/romfs +/romfs.h +/romfs.img +/symtab.c +/varlist.tmp + diff --git a/examples/module/drivers/Makefile b/examples/module/drivers/Makefile new file mode 100644 index 000000000..f2f6f93b1 --- /dev/null +++ b/examples/module/drivers/Makefile @@ -0,0 +1,98 @@ +############################################################################ +# apps/examples/module/drivers/Makefile +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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) diff --git a/examples/module/drivers/chardev/.gitignore b/examples/module/drivers/chardev/.gitignore new file mode 100644 index 000000000..9a80a2252 --- /dev/null +++ b/examples/module/drivers/chardev/.gitignore @@ -0,0 +1,2 @@ +hello + diff --git a/examples/module/drivers/chardev/Makefile b/examples/module/drivers/chardev/Makefile new file mode 100644 index 000000000..adeb983dc --- /dev/null +++ b/examples/module/drivers/chardev/Makefile @@ -0,0 +1,81 @@ +############################################################################ +# examples/module/drivers/chardev/Makefile +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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) diff --git a/examples/module/drivers/chardev/chardev b/examples/module/drivers/chardev/chardev new file mode 100644 index 0000000000000000000000000000000000000000..ccf22f1c5cd00f3ea97f71b7011addad70df1f20 GIT binary patch literal 54462 zcmeHw31C#!_4j-8-Ym&vB`g5~Oaj3~NJ!WOWEY23At5R%8bTHl%tjW7OBEH@S`}An zQK;5x)mm&tZR>7b>jLV(QmYlMRjXEmb)jy2zu&#*&b$d={pf$|_jQu@e&?Kf?z!il zySzJZ-g3s_3!=7dTjpb11s1t8MR5L)6yYDMpup;H^|dB!?Hx^x`sW8C{<#}w`{xu! z^P=wj4YMQB3HMQLKDI`sZ&|HdQ;&r9{M2Ykbi?d*GfSi4`2`QS(E{YzFgq_Anj46O zkT;~PkcvcG@3S6|>1=gwDc|i5v@fIFx8;Q0?t9Lb z*4fqrAO0=#?CE)D{Vnr+citaF(e$V_tZy_B84xX;d#Li^&YAO`xAFs#;d8Z5 zBl`bhX5jfl`wvB2jyr+gI6DK8+_|Leagn0Hwv3|pw+}`tC2zl-A6?jOhXRrQN@K*p zj1fuO1ChRp+d9+#LTHyAvd4Y&_STuH&!2L_^}8a@i6h({>5`weQYkpJ_et6zcdQwpX#ef$b02{*3J%Z0}-A9(u|(W`f_J2FwL zPxg$cFNnIkO6>dIX`P-uyLGGG9rQmLa-;UPJ)iB~GqgSu^(Um-{<-@}W!(BkheZ2F z-KaG*BbuDYdRs&Lpg$$&O;j=TMZ?kZcOBceEdu^6kNxf$*|W8UK~Z0KFz7}<3cVMa z`R?Iu)TcMyN;{~$p?2$5U$^Z)KD6-N(LPsMrPjwDo2-#tNUMSC+-Se(plIO79m@+#x78G;Zd+1V zx;=eoD=6QNmcl{XTJP&DbhdRB`awmarBSx=7jIn_462%yp!I2Ij?3n7gp}M-*mX}dzi|3?=BV2_qN`{`>9&#)qqiN58KNo}+~qox z>Wg2T)g5w&L@$dTyz_=#rM}R?89Pc2UD?%;Q!;7W&yxz=9m$c@sP%<2^y9aCcf0AK z2d;_s*;zcow|!Q(>t^g6p(xu8?;HxNv$}n5U?=9Iu!FrXZ0#Hpwa4B0c6;HF?K^f` z)7?WF=UXE~59CB6QF}7IJT_`wx;AR%l|&b#jVr$Hz1tp@cLzPrL@hsi`BV%E*jSjf{iLqO5ze+*-4WLw=i51}dztGSS2m}x zOU)JqR`+FVdv{MyFYKDXt+jCOw%{QRg$H#99cNc4_`+YT3sSfF(ciPtA42F4?#`CN z-Y>KkX8gXZFav$#o?TY@$-68k`DM5JYj?*kD>SQnt=sV4+$4La+kLw0zu8&Oa)95@ zi#`K;dp>*o>sNQ@JV@VBhX?aezh`!*Jhb?KhZuK%h8y(BNn^x)Sh zIhMZXv!8!$k9*>+E%ixT&`&S19(W(~`z&mGu!Xi}|I(Q=RvkgluD8dWy)1NJ2nz*g zzO&4kf7mi>=-JE6F%jz4A(%y}TamOR|)(H3Iv^i69`|NZ_^x3|%K6O{nw$(gt z7vQ+D{RY^(VOeOWYO5lr{=GjqbIMgo4v)|eTBC-M@FhzTiZv~c2zaCHrBR}YHF$JY^;rR)V6md>&onZU(npy*jQ*) z*H^XG)UK{v)7H>YJ1KGuprLt1B)=xI{AAck-j6~|+*VsvGbvJD+tJz9yzh)XG^|l5 zZj=;j<+n!)@>>fhC1YY9+cha-ML>-1vLe80tJq4mY8pDbmbA7kuRXkO#q7of?bZ1) zk=5Q&)6g=iv0-^7E7Q{1(cXd5nu@DEDQ#72+FSM^Z){oP&9KLseb`}>A_cRLJStMr z($d%-scUJA%qTx1a(L77+M1f$n#iKImg?H}_LjEx!pPX-iN#|gqf1K1m5dubF;dW0 z+gMxGURxMB9$7}!N|vIrl@p7Ww^cP)*GJlFS2wgbv@}OXj~+XE!h{p7e;4@gkp8>V z{CimZd#3s4=h7MDaiFWJty5`;t(s48ayJ&mmKQl_O|=j{hVyO zzdgXtu?M?(ww-C`r)7nmw1H`vcCSE2Kg;qBv%=x25Md?K*K*P(g%1tS&9W?4--O-l9HNX|+~3&+zYAZLoOFiSQSYzStAP3vPH)PHUk zZKnGz7MKyU=BG4sxRUmgZ19Ozva(SA+IAbt9 z`|6qfX)oI!^W2BH^ao3KV3+KG3(jKns5tP#vuw+ky?$o4W#wqGWepmekb5v#PwpYb z_O$+{+=Nmi+Q8*Bmg}(r);hq}iiJrvNPtmhY{nuerp-(nCg~U^GuEtHSVx*IBi@^q zk$yqe+cMs0MpStj@wlOl;x)3YUfv+|2!2*#@O#INF!+5EquFq{N%&YcsoyHq z?N_Rrs(%=P>lHwojYWbFksPRlT&j9gj;HwsnFPxk>?smihOhx5o^ru^+GkpS_OZNJ zjr<2ezz7cYisoif>pu_w7-AfXsv5J&q6#myD%x4~MwOZpb9wJU zks7zjhDeJ$z__M+8-lgZFri1ovrT$=6x5*2QcVI&y}c=DVYXoo8dJ4xxqVc>#I}u> zJFP!U{zoy5PhPHfQcIl4zM-{Fl6Kvtd&?e!)e9JWz% zqOV~+O{W-_Q#mjGBZs{)^BxFd5kpT(n8pH$E-`$@;eCY9j5>CiWY2I6n* zPm2|;Iw{AMIV`X{9B761ePm0VK||gdR5d-k)(syv6K9H^IL$Fk4n}FrsgEI?IMd^Y zv<%mdA2Txxpq7)WW=K6O%{b+>$d*>)w70agV)}&fb-AyESxNdyyDKI;KH?MF$sE<7 zq>gHFlVtzVJbC3zgne*N(^u)^CysH(d0ix1Hxl=d1#kwH`jE}j?XBibOsWf0KPp)q0XAT&89iVcluLg{eKB12Y9OpFbWg}M4b&?hy)4f}(mNJ_o)Z-g zG-gOLqJ3kEh?G8p_xpBp`u?WKea|SIbVDYDNjil4SRH#pXjaEEm88b!4oroKA;d&z z>V!kEH-tUcUwYXTTk>Lh(ecF8q6w_DKrk@zA=b|XJ6jL3{wC(^eFHpE=k$T`#jcza zi)+sY7!-Gw<@8*3#qxQ2c%;~p)w3FMocnXVdb-{6zFoWRZ)Nab(9yk4$7W%C(eXq8 zQ`dox%)|ls?`8f!K76rb_Uv!yg8xm+d{4(Sea-Lf#pYNd2cvzgsAP8FunB#;&c44% z$~f@9a#rWG@?STvV`bzWm+A{z1%5nm(Gjq>?{F|8$76Ao=~EJGvj)p&2Yv|B`92hU zhaUpcXNMMoaXv*}-|V@R`201L;Lq~SIbKPE&%>Cr1=f7?njmpqe?xPJ<#U5aBEc8( zUrx19a3a9Do*5TY%}FL%(LwS?6yUtV^E}Qe-2HJX_q?dUd2JE*vsvg{%R%}>D9DM} z7m&s|9m~nJuK@U5w}1viF0Vsyu7gGQEM+_h-o5H2N(Ym?`nM!sq{7c`A(;a=-IpE& z37;Fl1l)1-+z#EwV*7yhw{Jpn(Dk`~<__`qCO7a%J0NKnc7aD(rKC4uH1ODL2(0AE z$m<4YUIZq533kC*Bx#(voMt2kqa>4m3TY^~@L|y5D=01_X@#FfO@rm6UF5n9=-dN& zu;N;f0r&UVC!YZQl+e;-sH##zC%yo&6+RDwP^C*B!lyzKT1E#$R&pg03POkdfEkLB z96J1KkXHB+CP$xusvAC@8D=v!Dd9fUnL|1)%wO|Db4h1}r<0yXx>r~o{1-4ny~Cy0 zhsx+gb~ulD%X@*&37i$*G-Il5H2@6kbZo%ar?V20tTZBQpo=vyjpop<-5wG#vIoJmoALouvTRm5 zl)~hs-l{?=utSg2f>5Jh%6R%HaOq!CFW^35k~z?IvZ5q80BI(Bb-;a_nk1HiQ~`G(=;RZTo|4r3Q_$fD8Ijh>%o08eyQEd5 z?eJ>K+erJuh1e&x(?2)-GUXkl(M8_`O zok%+OOwiIq=WPZpO>}`Y5u-Q~ViqF8h~rwde(Q(wSk@haX&$21k?)m)0COszhF z>I~GWF?CWfR0D?t?h2Dme{{j#u$~8L^6l_zQPR~n1Wd&@Jp@uJev_wf-t6g{Kk@X< zTRnaAHr+SxMCnOenK!#vO=qi>bk|$3nG+rhNz$(}FgZrTPqHQMJs9+`a5G!te$oZu zPf0&WdSv)Y>O6Wh=#ub2=6(EB&||}F?xZI-gPx$r!85-CJvm%W{bzpyYCNSL&JH|ROxPRd`%!ysLtW5?=x`mPGlE+`>>42p{HAE={tGQeJkAd{mk;684Y z{IIWstOfyDB!>Z6e})4A_kE+u+G$Nu>I;GH|FM+0q!wX^j0*w111_f-3%ChKo$cSaL+VKj8fclr2N>VFqZL@bcxG@CYd4iB(vVg z{hCSchbViJ$s&0WAdAfqaKDCT=o64`(z{g_}NDsJeBz3jEL-NPy+kH6qTn4T$cj`#{80`1s(cNCd0m%4d*tZlaJE)K;bunpik;49c2XqWpsurKpF^C22&FS5s5Ih@*K zDZWmM{Z1o;@VGb4@0<;h)P%F!UNyN9 zLY&WUWlg@j7GwmQy)lvu>Qay@B8%-3WOS16vQ=~nAXj0)b*K2K)+s>-)jGqh+-q2& zX)_@4BLZkcTFd={(j(c@euoyUbR@bKr!Ch$7_Dp@M3>I@Ztw|dnLKbqLhb-xQ?3|f!%Rl)I zkRkUS?2~t67goCkpdkGkd;eglrTC-l6)CNq9hQF%SD9AoS1{+FN3omwGD`3-V6Kqm z{G16>cp*^8V*&Q|#}_>8JnP`?0`=|`z{4J})}oSzWaB5ECL$?5zwv zL_;&k(%3^Z)&#DP>e7!;_bRY`>ET^qdSSDF+wWqq*=J+76p8M8!48bK-mi;CzchdXoxjY3KtsW`R&!w3H^7MfUF_;Y zmi0aoBiOD*5{ASy402}~cjl|s5-4Fvb63%?8&FA1pU%iKFA^+D3g1-eg zBba^y*CEau%%;Cdjfd2Id$G>-3FQ8xX!<`+r{3Mz1yabrbOA^!cm(ae={yHIq~vcZ zx&Lgq@B6A9Vuv+IQfanLBlzaRO!>AGK&8WvYKE#-%DXIY7b9fqZEt)LTB$iG(>|UF zAA?QnP4)y@v&#asV4p|>>GXp+G3}rubAHV*Z02i__4w~64 zH)chgmwh0n)Xe zf}U&tkyUsKyGP+{3jIK0HK`@tr+ zHXwB}+3jGhu$$t#U{X`ukzlRy5W4s#iM{<2bKZ^JC8=2WLW!MV28V|on9Qq7=3o~) zz?}&tgk>0IzThL^;s?0jF)ifJWLhZrCveW^+^KQv_d)Dl=`$tR8~t!1(A2)dvZs># z5?insO7_%#Aje=n363K>jbptMYzP<4%pk)RT4<$Z&m?mlnUgI0FfzXble7Sp$fI#! zvc1^12K#c(g~?n&Jq5L7wSr1oDvJCL2oY{S zE|j#>Od9VVk$hZ)&^;bTRC%5>&InAqb029>N!m7(_UE|G7bWd|llD$5EzGH#HdR^g z#^hFt8-_GB13UD?AqaJfJBShvzO-l1Bm7S;0GY0KY$D76lhWC9URFKlHSl&F1T7#^ zkp2z^S9M6W{_PNBR)3mc2Q~tn6)3@X_~EdK;!bCR&%cf`U+@!frXPj;W2n89DHS83 z?fe;}^9q-n{*OuK+Vs$wh*I75cG`2@VYC-=Z-C6X7)t)DIIY2h6Ceq=zb0dchB5gk zNDdS{14-}*mK(C(1RWZJG!mROoM)-C{9!OyO&vqqZg4YYF2__d%>~@!uy^i2w&3J} zkOtgb?8BwlrKla#Aw2|w;Jr{w2}bKdr*cgdoRb04N?Qio!Fd$BX+O&Zy@0u}rurJC z1*dR95^zt(KArOOK`7f+hHanw6L6U!7`8G`fwrAl4%(Ml2HLTD&46Wlf^B~Vt*n;i z7%mfRx|M~QVS>%TW>t}50DC`;oc1L9Leg`X@lYl2(|bM>rYQzTr#s=HJ=MX2#@L+d z7@Jd_e6cyziQAm+#BI({aTYYb)(n*@Wj82@S zqTlz&ak?L7hbASpvj56(9AvXk4nuZ(;|$CT{Z$YSQbFh@k3bxx0&x(IY6DuCr%>^8 z$Y0JP4_5p-@B=x7=wlADVu=<0n_c$V$Vs1#9QYYn^(|*m36t%zEF^hSCk@USS`u50 zWnV2Tq4ER`KWBH$O@r zlTWWYuo^v5dliK6kO5v#K2VXjnXWxKiY2QktyG@yT;FNZ&w4Kg|XkF#4#{s8sL?LQcF0ZS{(|9t5TngmD;LGJq~tQ*H&e9 zJxfthZ&RiIGFEE4O6Td5fgi)z44C;fOAVA??k>LEP5PVji7&tOv;0{2eX4gz?T1XK z9|bOj9HREdI@VUzzCaB?KW6g&Y7iEvfp-Gl(5TM!#K5F1Thai_C_D-n12^Ui(w@H zVGy^HcpAhTAcp@AgoBmRa31PrfjHAueB1<4$s%m^Wnm(VuJFsKs_XY6; zi3o^p5W^1!k%Q4SoD0npKpfPFyd}tcBytWv4AKiBwF)Rw`L}>o`JW&`({F=N>4mgb zNK1pZz)CC{u?BgL4RWT#Q^FT2_v+E}bc39!4^Qaoxju&M1Q_Vw*oY=M zQ;jJeh)43P4(E@&FR=^3Vys|x(L5JJZLpEXnqdH>4AmHwBJm#v;asB{i+>5EoGDK9 zsE(WjAqTQm#6#>ha5g2ZYN%_PnOaS4dxi$VC-TZPvEN6kV0 z97dQKwos4BzcCqJB0&?oNzi)#EKjcCv~dU|LzmG`Y{>GwDvsNap`q>f9s5wYmZheN z_f>H9vHE>S$yHF_cX-AP>lhx&18x=eC087sM>|)kkK=sIYE8BiirT_Ag_(-&3Pam;avj3r+f-os0&tN?u{+K0Yp^Y<@Y_KKJp(*B6@3 zLY_Xpk+Jgn`M7|yN_(Na;16x)uR%O6MR4qmFT<$rX_u%ub2-A*Uwu!z#N7kUUyIK7ThuAom)q#RWxi9D(rPOQXS;k|=pgmbWxmxga}dwJ!823iFCIqP6-Zl#NiSD5?FK*l18!lkdSAeCe2vl`!w&x&C@({zeUtxc*vc=4 z><}pC=Yd#AqA!RQAgr;oLGf3g0o1?Mp9TB*t&p8dwHgrDkyrxa4iKY^>bTP&@vUDl zFdKRMAOi2H+Ae~~8b2H|&UCTUc<%aHSKy8ern2hJCn0vrfm5N!NXkh+sbuJS8&(gf*6<bUnIVSKJb zUdAVkj5-3=_*)?3p_z5=!k%BCQD;w-P}soxp~2{!sB%g_+DCMJCqwxuF?qTu$IYtF zHU4F!b7s_GMsGd~mN$t{tHECi{%3K1;E%u`1iv|3!Ee7h+h>j6g04le5^aS;$9|f6o z^j4@Tl@vB2o+p8s#I?S_jPKg-u(!X0`QcW~z8|ArB~Um4-4EZFABWg^0lV0FmusPf z@5|Rx<_qouXTC4H!9Em*{A&~h^8n67?$mh~d^f&~c|)$tbT{}KIXm>Q;`}ee3kaL3 ze>ZmS+`EcSyCSbTb)L+6&;DbUc?sn=&2 zU0Ogla0b0^7@YrlE;oZ}C(+;qLjCG#B?)UK7r!QBZy$;|+#Z8r_%(=OFiVY#F+S0* z^C5OtVHa!HZYZH$(ux0JW6^o%Xd0SRxBoYACvT1w#!LI z)Cm&*K-k8~l6I(|7yOweh1?UU5CH97btUtTA$j!$N+&oPiRc?25nO*hbGX4jfWze# z&&+DG?Y}UVzd)SQ;KoJp1`A$mD&|HEhQC6L&h`hW zU<9~OzzBF5!uW~yA22QC|DJ;20|eLon)yQRQv^5oQwr_S?^K%qIxXA|a4#o4`7#vf zcQ;@kxEZ^k+RXqZlU%3*1*iC;{PjgmXTCY-F*W%}Iy8@BH~D5-U%*@;%e{$qr@RZs z?{;G!rkuwCW!p-b$&Bl4N==RJjj8M`_Hvf~64LQFA;j6WuEf0H+804$f7BnxNNkrP zO7ozwO-JbttZ1D3u!~I@i=c#nT|}8Lcn7%nl+laAkbk*?;1GZ_o;!0W7|*;R_a%ZG z+(fWLt<;!7JNh@~CE(3(%u_+%L4Wxh^K;ZOzcHW0YP!LNQ1Jf7{A2Ln;y322pti5y zm^+zWeq-h}p0T;%FedE(H|F#|LfKx%&giVQG2qoIdfC(9)$hm4egP`8hJjxGHAt)1 zZ;&DQ6f-d5Jowrh$DvWOl2DR;8WVOyUH^W38V&VF4)y!-X*6~?IQ{$a>C|lo+jk*K z{xPg&KwzKSZzb65O6KnEng^)&-;gXR{L*cY2xQ`K05?t<)L#mj0+emY)X z1Cv&-v*1xsot1wOif|N8s}rZn>1*l8ttdq0-tUvTJl;q#f@5R4_c~^b)ckP;iDC!Gj&&HS0S5P2~T32)7 zVF${QhAudqfWsgZ(5GL7ZhR7W8yx!dV+w-l)O6hw2_bjB;(`+auG_^5+M%&v{2x>M z=r%}9f%ZoB;{bjwoJQhlI3L9CY13wa!4&AacY_GghQ$j)Tx&Z9plesbC40#r900I= z4Cg09Ay2KL0%e2Y=Ly)w#%5nAp&lbC^99ca7ayAsF)ifxF)b8)7M$~E?#$Q>t917| zf*V{#utOQtcKwSP7&rKL>PI2^7R$8pP}|ostq-%yGA$GKV#~C@lKF;Z+KouZ?*eL> zwvt9Dg zQ0>_7F>${QLBD#C*;hd!@JWzzwbK`0_^cbD;j_QMy?}U1AZV^%?OBtSE^h6tsaiU# zrMk1Jwz;EyX=_`{%GzoW&7B<`T}zv)+B<67glTB5ZtSe79aYta^~ZtbJ-}?E+D~pj z(5$K=|5WBtb?x{iP(QH;54pjoudQoewrrZK)fus%-@t1&yPhV37!`6lK%&N}9dvuYw8a|ZBz2JjD-jh}VCvTP@{ z*tMOtXG{kBupI$?|LKujFncUA=bTZjLYk{W8rWw@JKFHDtpAB{9N28Brac|Wjy7CP z`;8se#8mfJ)Dv+;d>O|S1cN^v_*{GHRG$z1uHgU0AT`xCRkxmeph4obO3p+Tq-lth zFHjsf&SxW5gH^1aK_vGYqfHICLhAtA_MaYIHJweZ%RB4pYTLfC$~CpiJEbqg#+USq zv8?hmyLhZ~N+h4XV@2r@C%JCwO4i?5HE()}le*-*k|Wj~w^T`5<|*hqS;69Y&ZuHv z79#X1?D;Hy6W=RB>RECB6CpalRzZlY|Gh^sH5cFjwz|C)Gg(L7H#U5H34-QHm>p{L zkqyg@_>m3AtR6=;HCcKl5gZ_$n|yZGp^@CuylL}`oI(&e!}3b!7Zn)7`IQqX9yKKQ z*de*Ar)r(zQAK$RrYfaTlZKISw%CzAgNl!sUQ&vVWCtSHJAo4JCvlfoS~9g{M#;32 zQA399TVWv-Mj!0_;pEAqhAbMTbS4KzmmKMIEdk>zbb1x%O&#fsnA~SjWSWx|n(U-U zoJXvPbKe=oPHJTI{DpZ(I>RH*am7w@Wb_OttJrBOc9J6CoYlq7pMAx}o%zRl?anKp zVW)kv(`&LZU3>&g_oC^k#m-D+YW~9E2ak4!O?H-w<;=-W3oVa#x{94k?8*JG5-2Ds zojNJc$>1=;P4sm~j-GL(lQu7BcrFD6qn$6Tc?+Bi&zS5aO?EPiM-Q1ozdC7gyc3=` zY)I~c;TW-F^PFBwN@pTc&eftj*;x{C&a;chO)H;Yl)H3lW##DHWAjU;v+hp%beotyPSKvmN?gkBF-Pz%zJm*s3HfI zNH1Qn!Z|NgeC|r;e_&q8D7Birn1_99&Atx)|J0$)69LTU%`J6}o$d8{I*-rE=xkiR@w}_^ zhGq9wOSeZ<5BmN-d(gkX_~D#|d|w>3uP=Uh{H!d3{)@l+@hq(KrDeYRtynVE8M4Ib zy(IR{?>yD9n)cnX{)w+C@&&g8=V)YIi2kI%4M=z5DMYOLvPLf)H$^RQc@E5H_1|ZY z;-h{Kbd>)yE8Ks6V(IauVbsn{A>Vcmr~i6p=P2aaQs+=Rw|;?>-C?G4oSZ}G_`$p+ zpUs8<>U3VHq0^bhpF_+?r=P^%O_Ye=cq1kesME`M?p8_pO^&DI%}1vfL8Q~o4Ht>& z6LEH0r*p->!z2QA{`M@BZmxSbDmwj+Jdnb zTb7`UmV!b#LF-l+T@(SK`Y`JRY!DIFVoNNQ3KOxRRKjva9z|G-jk@ttaQQNOD_C2Xc)IaZ7i`cD7uqAp*1)RvHrvy5K_z;Y4+*1fG zoPLHvc^*LPs+%6D3n})o51Je!r(_dRCoeK-_<7P>CN)r|Nu}~MC0az_XxiIlbpqX5 zM2PIA;6j3nUtn}G_OXu^Eh1!K+uNuQQpAqgsnDZBJn4rh5m*6cPYez7ArFB{R4CtM z)Wg;)E3(SUgDfxBoX}FLJsM0q${Qo_+zd=g)~Yi$kzld#0Q=a-QzvSm#svI$OHT+p zun@LZJ`w^K&ej@`{S^ob?X3K*c_|tj7@7n ztTW7J5I@IeTT8H4AEO+yI*=)^G$$cq_(dPeiwNw7Fise%rG#PFzOl|mAzo3&Q5&l; z#t`;Jn~b?$Y;F9Tdnj<1M9e4V)jpLIXgr1LMmMI&lrh-gJYl*bD+n_bxri_mTcY#K zrpHxd6R6WI)Uh>eG@ReR53xCX(8%G6L4O_s{wWLg;-!tf$Vf_ z7;S{jiad%yyQ(fg^*JB=%dr`gTB^-H1O^@wo>gQ8;W;fOY{Qo5A-&gm?+Ak#LF zGBy+3Vm_8@?2x9NWZeL~Q6$y~l=rrktAq)PtRNhrrGy$SC7i0I1m5weD?nvE8Q}}Ol&%V6mPynhbOQwoj{7$S0I7F8#Q$TsSce$SQ|^&+lg|o z6XnVYUB7ZuKbkDx#IkrH82Ti^n2gWV@p>)xnp~_*^5<(DMhJ@(c@)9aWU;cYYqHo| zlf|1@lU9{uF+o@AC~u_}C$t!!NaeHETSVPtM-z?|F_ER(*3l+-)Hd-VZ9c3-M5!J{ z$iwDXo%SXY+On#{QmsNb(WsEnr5t6ft%c}fZ0PueEsCrl+@Ym}$F!92xRw&0z{WOM zw29QyDk0XJ;&#huS6eumV6v5YvK_s*JLSwqqq>=m!iA79g^MlXMr>$6!ktQ7x`}wd z7RMc1+|z(#g(AuV)e%5f<>Q5Yp4Hi9V6Vc)8F<=&O(dxi!UI}5t$awxu~JInQeuLX z#Ie(+l#CZt(h}p$y^Plo#6G>r$l80<6_w+ zQoVEn!8lX4iPU(VKrqFYZ6Y;GClE}rWt-x~@))W<43dsaxi>Q9s@P;@q?}-iEmy_r z7?cxCvE`~*UE6YRZOc8ymhWBcVsEjFRk3NR*u@0hAVi${Z}9Zn3y4s007go~88bQ4i~dsN)1*i2{) zU}BiAEKnT_cvt1S6pUxhz7p(d*!);-VbHGyd2XCFO}qgjmejLelxs(h^;XN9O($0n z_8C>9%P{asb_hG+PnsmWiA}cvsrPjPA;qD31tC?DiwJ4hv^uGNI)RX<$O^(xEhP-Y zrqxLm=>!6ABh?9{M(YHxx7x)ruZv}y=;8;;#WI3%rfd_bzRE}$!4zAzDPC-uw^+;x zP}9Z6MmU4SdwQ`(AehLMt76~M2?SGYxhhu2pqyZeEmy@3SN@a}SQu-IIRTU|Ha5ap z><(<~ro=adCejCXWg=UGIz+laIguf!oJbESCyo?3k;PJOiuVo)x)a5QzCl=`$XI`m zrupCeGUI<4n#-^5Rzz3CM#}S@VWH~{{;W)y_O1hZvtO_d6s;H0G z)V^daW~45iPB4;igus9XaDpWi$=$@5UgP0O^D(GUC43}FNo#XAeGa-y`A|VP4I8a6 zX&q?Y6JovReiScN8jOq)Y@VpTh*YVX@tt>n&rw>72=$7Lofv8c%dY2B=aO_DKEd!) zYyoS@`fLyQpUk^gyc4>{gu1K-OC#n>>d%rY7w z@cSyp$URL@QP1oZkgdgrqbY%5#7~l^5g*oKQxG*N3RoZQj2I!%BTw*~^7YC@Z05gM zOn466aZ#+@jL2I{mdDeXmajJnpok)cBJo}9a=wQGhid;mPsijeXE+RI~ z#Pckk98-*~6Eh(4xJPAACtxZ)5r>#ckK+zOfG(hFM_@Get`e=F`h=2wD&Won7C~UO zq;^I(u{5n)9*OBzFbj1(;}x8`!=EiRJeItOVt!Z;Pnp#49CK)Eni74(d3~vLy!jWg z7wGUUChWJLDaABpzk-mVNEMxkmJ)_x+dGoUN}-Ivthy~oW$6Th$r%qD2LYA5{g$$Q zT7z7D>MC(%*J`W1;gs6S4yzLvd9`-5fvRq7X|J`~Mc!1^g-4B%v6?%YR@KzDTa7Jv zf2`VdHuHLOyg3z_&1LKQMYGn5+Lor;j<%Dnwx*hfHsoDh)z}HM9aS9`v`fdMB6}2@U%QPsqc{#k*zN%7P!d}@PCp#>7)`)8|bUtQbEtKh+md@pkwbt^+ zmg8QgSX06JZxOjYm)lydn z|KI?;R&F-8<5mT{7}nIXxH^`vwyCw_WGf*Q5;UvnB-VZJP~jSksuie7ZS6^j4C~oq z)ipLWpJXj>Xs)qVRPvR&mHO9otF4Alw{2?aWCJDCrLwxM7B>v224g|(^>`^_B*Bxq z_DZDSehUV!0kx@QnB)$F$~pvst)UzKTmKNwcM>l(?<8KT-$}f*2A!$4t$nH3w)8Cr zD2@SdN3g4E=p)-)y^0vYM+?=k4Odybgg>!rs%aW3o9Lm^x9Itp(d??tDpa&owYsXI zk#?*O5LQEFYi+GAL)we|7R}#`r0V*H#v1ss1|g;=m9fsEC>?`lc6OAY+5v%Ss6oTD zs6LB&C{rrZt11!Gwv$n@xL4l(+O(>YLq)d;Lyiutb9AW6S{QvT$XvNxH9@70mQ{}^ zX~!m@qO7ruNsa-&x%jaEgclP>ig59A=ag#w2F<2Jz<1PlHZ2F%L0;FodR$RW>3FiN zdJ*oAn8I69AYfN6s;+9p+mnk{M2Z#y>Y7`M)O`vK&6;7itwyfKhN^a61K&`od%Nx@ zs1sg5jYKqzzNFY{XsPaKL_lOzG;nyLzoXme0nJcw-auDxKe@R&)_d8d)bz!xEmQ}y z&|XkRH$Z2s>cDiPx;$bC^QtGRn5r3qU9MHGN{vq-E98caO5RE!cM1G22>iE=weG9U zylK3$68FMXSFWzAR8wSZR#4OFw;t;1$|l}3Q>`vnG*<)fV@})0xM#fb-kq47lc&1iO}&adc3Bs75bA37PkkIzw$*e(rO7V3wNos zSFJ`j^%(cw$nrlw;=gUjYp?BCj@P53ZR1D61MX@2=t_uG8(wJvRLrg z94dhEfO}d9$8X(*^db0LH`9T*wBM#x?!_a74W*o04Kz+x`n3tYg*s&zvY@M%k0&{W?Kx=0zT#;!*Ty#|B1xpvhVdphoGw4tLQb zDk={<{K$&K%k>ggkDJ&u*jC$Ag{3#v=TuxU@2JHUp5v`dihhuoz9>->ymTz5Jq^BEr zq_fB4$p}GMU)zPRY#r@AR~<~&OAK}CzUr?i(JY_v?J?FMs_|h8i(sp!VRb`IExrLJ zPI>&U7%w`OlZC)rTzwt4Mj5_Xbgb-b?`Wty8Q~Gr0DPy}*T`dQl&jWYOpJ@D5msEv zIhmQ2DcX?l$gOR)rj+J}<@^p7vsAK=_2Gd`i!$+b>c*gZvfLu+U7g`Z?o(>pTCCQN zrdE8vVu$$GnHdpS>1_?QjWwD?b5*rhH#DGMH)@Gm)T=gNr(*zm4un`9)mPXPI_ewR z|AhkK`Sud)ZMkKC_bCT zjnb#R+fk;C*xIvaS0^u{K#$ISO~vt9C&3HMJ3YH?syESc=Ob-_zmZ-74{3I`84iYgG>f^s8!~Jd3RadKQlF#fgq41VvAL z{0@~Mj^{`at2)Lciu>2;t)5V;>X{iL)~>uq$}A@0ck-F<2WG+a557aGe)pg8MT+i< z7qZ%+B-VF%)}#X`>6&!wvNDOMKmHXL?Vbsx$GSAJ(;diihtZ3zzf=c^*<|qc(X5D| zoCu38fTc6UQ{tz{Jg1prp~oTNKj(y8Y|h!=3Ai4!4?KwV6wmC_vj>s?#&c|mCs+19 z#3zPOFPHTiUkxO^faZZQW+)*?j8X2Z-QFz|8-VJ^FsUeiHTc(=dg9;o4y5Py9OwT( zFFfN1NpBZ7JuKFr_A{cfRA6_v;=?#LN_0YeEs* z?HOs=7rV35GG;!TmNMg!habW(>OF0fzZcv4*do~WmCpM`QgGQafA;U0&N_UFEeGkm zhTyPosKYSmjK#JCdNb3q*9Fe;pX;9IoWHL+N1#&y-4tB4z{>+>#p8CwvyVOc8(th> zba){$uPE}wb}yYHzd?ugSym%-W`geF+lkLU@wh6{=-m#z;=T1Mj9x_SnHRfw{3#V#-QTdQd_bi)Z_(7!e2Jm5^z4H*|=Bb*@ z$8pDtuQ=Athxe5{jEy&lsCz&pfft@%hwXZ7ygJ!@?n0b+;i9=}(a7&XS---@D+OJ& zt@-fszXjNM#odJ-xmDbLa#Kgua$rZB#(G1w)ixG))OK}P#iZI=YN|S_tYW=ij#tGM zSGP3rshw8wjPfIjt2*!#|MJcbT;Ncwp7~W-wS0M7?P{G{OB$N%TD&|i*{JpMRc*ZF z2L@Q6&Vp-oj6L|}O{v3U9+6wCNk&uMe~7%Q5}{TX3{rV4wh}z~)O-*=_2Knm9YZLvzOLm4aq=%Ff0WTX$pg zn2XW82$1DdZyj{*!RGy#Jd+_L&2hmG_3rcZ1Ez6192;!40@SAy2P~FhKE@ueGc+{Q zZi8OGOrsS~ThT-BkzC62pyWa7LAw8;a~8n6hjdEoVL z@-b=c;Jx;CKB`|GKzkg6#@>0LO&*Ze8aT4qBQWIINb}m8^O#;M&>qLLv3Ct^ak7z*NxKTX*IxGHmKA}F_7KXLy&FL@PYE`Do;U+HPkJu>Wg53T1p(?)avdJH zZ8{w!hTH<$TkZsu%S$;~F2iW*@epX*HJ^eTFs~X0Xwul^jz@kE^ms$C`4~N-XZo@x zJZV{L(Q$b^Xu!sDS#SE5U~fCds7GMzajwUkbF2svhKC6j5F0W6gs&&A!@7jnsyjCI zJIEt{m*|~FgwhqlZy>J3mHfj03Ygq!S-&Ad`Dx0})%Ox7pNTOD$G8re158GRmI(45 zRPr5y=L+)1M9P08$a$aqHo-p%z7M3o-GUzr?iTz~kin&%D;N?y9hkgI-%&+ubHSg4 zKJEvegBv?=MQAeOa~lzS?;sF;>>9y$fVBI*V7K6xOg|a*MjJ9chd2}ML2Q9tVDcKo zfp`k~ED`#xOo#qD;#^$tPlW!>Og|g9j1v*xdnreJpC*4gu9znxzncU^8H&{sn?%f+q@A z3!=(O4=yW2NEKcvc%|TG!CM9I5`0MTX~7+WZwdZY@FT&m1Xcfoe_8Agz`=qe1bLq^ zO~2$l(+AXqQR{!0C|f|mZ>Oc+lY%b`z9smP;ManDNiOyK2@Vw;C3vXd zY{A8Xm4YV;t`R(2@Djm|f?O-HoI3>{6nt7x-OYvcUBZVkc9ma(ykn01D8WMoXA3SC z{_qBf&GnwgE{WO7YdFOoGv(D@Mys+1+NkO5fOdu7sB61#Fwjwh39-i{ttpX ziO~NW5q*L44EZdXUj`82&oCn7d=(-2DMZ+rDf|NAj~84f@|D7$EXY^2)6T_$w+P-x zMEOq$|ElnB5>ei}BLBN!CKg51A0Svtq+i1G4Q}N5j!){HNJNbJ@;1sF1e*j`5#iU# zM3k{s{2789 z1o;Yh+IvX&ZNk4yg#8en;6*zJ5g{8bxKMBv5$&}`_|pW}3a%p}|3yT!*X1JLAb6wT zZGyiLd_eGN!50Ky7JNxiNa3dw;r{~Sx%du3M11)=RmztO z@&)YVR}xWf8xiq6S>$U4&l9{@kndz?z8eH@5&W6puLSu*R_Z+`_@dzJg6|0aRq!(+ z{7A#%nDxvN97BZvd~G}JO%=Haf@La*~3SK4nBf(n* zw+P-R_#43|1z#Y-k2i$>I}!B=U?D~f6XAa!;fD!MBcgtXOZq&)BL&NeuzMU4^{Wzj zonX7*DS~GTULtsvAYVVs@~;>CsUY9YPW#Ug;pg)re?|D$g?~@@-GY9c*r9$e!G1*8 z8ArrCJYD!>gkLUvyYQzA&)3gV{~F=>T0`=83IDk8&kO%2;Xe?5kMPO(QpfTK5|Mwn z@MDBuKt%nQ3Z6_v+|Lkxo#6R`7ZG9a3L@hE1Cd`Z_!Gg~1%EC0u;7z|FA2UP__p9j zf?o@Uv6iQQy#)IS4ihXD94|OS@Cd=<1Xl<)3$7EqRqzqP=LBC7bn!)jN&3w|Z(A)Gj1IjKaHpDp|#BJ7k3PLuSg@XLtw zPq1CmPZ$1d;V%~caw6>AB)C=5?-l-cMA&;%@Gp}7vG9Kv-o+P9>Ln3jZ*X8{ELFG3cexfyNJja%mJc) z>K$v~3&^9~34&83eU9);1WzDBzfSNp!OH}161-3FdBL56emzeL1wzQ~UgzFzPWBI0+Y@Ye`lCwM&(<=jF< z{O%C>U4oAYJ|(za@HN4=1pg}dk>FQ?e5X78%Mu(SSR^=BaH8NW!7{-mf|Y`Gf?a}} z1n(AnL~xs6x8Rq8y@zXmB7)-trwh&(JX)}ki1?gAMEjgCxL)vj!CM8l5TXB&@J|Uo zC-M&jg9mB748Z|J#3@(!65;0wHVAeKZX^aVe+qw-;H`o`Bf^iniD=jRMgFMZ(}FJu zzApHV;D>^r3VtQ%7HB`ig1rR$3l0`MT<`?J2Eo;WR|)=*2tRKV{w^Zo{4gu4!6|~XiKyq%!Y?BtJ}rXZ5xhw7N+R@sBK+;bKOp#m z;73Hn<4fVgBQ)QK2>XW-VQ0C>n*`4g{2>wTbCdA532qU*lZgEH5|b?J5s^P7xLt6E z;9G)!75rH63qjvV*nz)Ef_()C3g#10-eh7J=R1k;uSU`v1e*j`5utxF5&o?e`8k4@ z34UL2v*7K5TLteGd`R$F!T%8C>uBlsp9J3(+$H#_;GiO{H%@Sd;E{sOf~N>xL4^M| z5mDbQf?GxYnDEaDz9{myi8yY2AUrR^qJKdm?DZ9XnBd`pKSvtVPjNK<+STX;G!`J% zOdlB1I44=-DXAI*avtkp!PPup0{u)mUonT@_rb%Qg%=g6--5|wx>S4#5qwnmMZ(t! z-zxmM!e1)eN{A0pz6aFpXyM+&+3{^gnF!q*AkD*U;^Un=}eet$-N zjuZS`uou6_LXOi6mJcz)*F;rbiST2EUm*M<;X8!y68;L|Hwdrl1$!?Fuj&Q=dpZZ-8{AA(P?|vhYiU=Ogr}-zEHM!t>fa=D$by7lq#;{QJUp3y(Pi9@SbVaq0Wmt>Uc9DOe{8E5>7RgC#|P8?v0<$HcZ!E+`8hrK z2T>pW$+BkbqdZ=Vt3P-yJJR#PFM_~~CtkB-(%FA`eXikI9*49ogC3s#RCw(1cx*nVzrE5!e~U+-*SVOF(dRY2`eR!^ zM*1h%`lrV9^?bwYKlR72=AX}dq<8e- zb7J~B|AZcVc@KW2hrb8)dkFQzX;;kVwz?+Sl%4_Nc~5-EzXpCBwjHAX0cdj_Z3gmx zlAs^3z5xF{*k=f6pAS+W1R0h^icbS?KD0k1fp^q8BA)KIc-@fsP@hkC?}UAh7ux4~ z!+bJueB?b0=0p7o@Mi)e*r;FEBfYf;&+F;7L)XOT9PqUm|Gb8t`7Z-<&M@|_1-~Bt zl!*PC!KZrs`xSUpUwtxgJbwuM55XDzC&8N!c<80hP;F) zV8x%V#Cx2WYMwzvCibKnGVzCvh$@8UhDS*700Z@q4*f6;d18fn(kZ>|z} zUIj@W0n)Ebl*HH_UW|(8wn!<~dJF?Oy15$JahyP+p{X$<+A_Ec6Hsqxe<+dz4e4;n$-OU89VXh zM$a?-;L2%Y|y28(EdJco0i0DkxETWE2oT-l{-7Z?t%` Tv3fR*zQ;51R%3XgZ)*5Iu@z!$ literal 0 HcmV?d00001 diff --git a/examples/module/drivers/chardev/chardev.c b/examples/module/drivers/chardev/chardev.c new file mode 100644 index 000000000..15fb38ec3 --- /dev/null +++ b/examples/module/drivers/chardev/chardev.c @@ -0,0 +1,142 @@ +/**************************************************************************** + * apps/examples/module/drivers/chardev/chardev.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include +#include +#include +#include + +#include + +/**************************************************************************** + * 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); +} diff --git a/examples/module/drivers/mksymtab.sh b/examples/module/drivers/mksymtab.sh new file mode 100644 index 000000000..bb0ea5937 --- /dev/null +++ b/examples/module/drivers/mksymtab.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +usage="Usage: $0 " + +# Check for the required ROMFS directory path + +dir=$1 +if [ -z "$dir" ]; then + echo "ERROR: Missing " + 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 " +echo "#include " +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);" + diff --git a/examples/module/module_main.c b/examples/module/module_main.c new file mode 100644 index 000000000..d443b1019 --- /dev/null +++ b/examples/module/module_main.c @@ -0,0 +1,209 @@ +/**************************************************************************** + * examples/module/module_main.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#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; +}