mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-22 16:43:34 +08:00
+90
-9
@@ -3800,7 +3800,7 @@
|
||||
* configs/stm32f4discovery/elf: Enable support/test of the PATH
|
||||
to find executables using a relative path.
|
||||
|
||||
6.25 2013-xx-xx Gregory Nutt <gnutt@nuttx.org>
|
||||
6.25 2013-02-01 Gregory Nutt <gnutt@nuttx.org>
|
||||
|
||||
* graphics/: Adds 5x8 monospace font. This tiny font is useful for graph
|
||||
labels and for small bitmapped display. Contributed by Petteri
|
||||
@@ -3833,7 +3833,7 @@
|
||||
* drivers/usbhost/usbhost_hidkbd.c: Correct a logic error in how
|
||||
tasks waiting for read data are awakened.
|
||||
* libc/misc/lib_kbdencode.c and lib_kbddecode.c: Now handles keypress
|
||||
events too. However, the USB HID keyboard drier has not yet been
|
||||
events too. However, the USB HID keyboard driver has not yet been
|
||||
updated to detect key release events. That is kind of tricky in
|
||||
the USB HID keyboard report data.
|
||||
* configs/mcu123-214x/nsh: Converted to use the kconfig-frontends
|
||||
@@ -3857,7 +3857,7 @@
|
||||
buildroot toolchains: They may be EABI or OABI.
|
||||
* include/nuttx/progmem and arch/arm/src/stm32/stm32_flash.c:
|
||||
Fix a counting bug plus change interface to use either relative
|
||||
or absolut FLASH addressing (from Freddie Chopin).
|
||||
or absolute FLASH addressing (from Freddie Chopin).
|
||||
* libc/misc/Make.defs: Fix error in conditional for KBD CODEC.
|
||||
* libc/Kconfig and configs/*/defconfig (several): The default
|
||||
setting should be CONFIG_LIB_KBDCODEC=n
|
||||
@@ -3868,7 +3868,7 @@
|
||||
* tools/configure.bat: configure.bat is a small Windows batch
|
||||
file that can be used as a replacement for configure.sh in a
|
||||
Windows native environment. configure.bat is actually just a
|
||||
thin layer that execuates configure.exe if it is available. If
|
||||
thin layer that executes configure.exe if it is available. If
|
||||
configure.exe is not available, then configure.bat will attempt
|
||||
to build it first.
|
||||
* arch/arm/src/lpc17xx/lpc17_syscon.h: Correct some typos in bit
|
||||
@@ -3918,12 +3918,12 @@
|
||||
the scenario: (1) sched_lock() is called increments the lockcount
|
||||
on the current TCB (i.e., the one at the head of the ready to run
|
||||
list), (2) sched_mergepending is called which may change the task
|
||||
at the head of the readytorun list, then (2) sched_unlock() is called
|
||||
at the head of the ready-to-run list, then (3) sched_unlock() is called
|
||||
which decrements the lockcount on the wrong TCB. The failure case
|
||||
that I saw was that pre-emption got disabled in the IDLE thread,
|
||||
locking up the whole system.
|
||||
* sched/sched_waitpid.c: Use SIGCHLD instead of a semaphore. This
|
||||
is a much more spec-compliant implemenation. However, there are
|
||||
is a much more spec-compliant implementation. However, there are
|
||||
some issues with overruning signals because NuttX does not support
|
||||
queueing of signals (POSIX does not require it). I think it may
|
||||
need to.
|
||||
@@ -3959,7 +3959,7 @@
|
||||
CONFIG_APPS_BINDIR rename CONFIG_FS_BINFS
|
||||
* include/nuttx/binfmt/builtin.h: Some of the content of
|
||||
apps/include/apps.h moved to include/nuttx/binfmt/builtin.h
|
||||
* binfmt/libbuiltin/libbuiltin_utils.c: Move utility builtin
|
||||
* binfmt/libbuiltin/libbuiltin_utils.c: Move builtin
|
||||
utility functions from apps/builtin/exec_builtins.c to
|
||||
binfmt/libbuiltin/libbuiltin_utils.c
|
||||
* binfmt/builtin.c and binfmt/libbuiltin: Add a binary "loader"
|
||||
@@ -3985,7 +3985,7 @@
|
||||
* arch/arm/src/[many]: More LPC1788 definitions from Rommel
|
||||
Marcelo incorporated.
|
||||
* configs/open1788: Board configuration for the Wave Share
|
||||
Open1788 board. Still fragmentary (contribnuted by Rommel
|
||||
Open1788 board. Still fragmentary (contributed by Rommel
|
||||
Marcelo, adapted to use kconfig-frontends.
|
||||
* net/send(): Add logic to work around delayed ACKs by splitting
|
||||
packets (contributed by Yan T.).
|
||||
@@ -4011,11 +4011,92 @@
|
||||
* arch/armv7-m/up_hardfault.c: Fail if a hardfault occurs
|
||||
while CONFIG_ARM7VM_USEBASEPRI=y.
|
||||
* arch/arm/src/stm32/stm32_serial.c: Add support for USART
|
||||
single wire more (Contributed by the PX4 team).
|
||||
single wire mode (Contributed by the PX4 team).
|
||||
* sched/: Implement support for retaining child task status after
|
||||
the child task exists. This is behavior required by POSIX.
|
||||
But in NuttX is only enabled with CONFIG_SCHED_HAVE_PARENT and
|
||||
CONFIG_SCHED_CHILD_STATUS
|
||||
* Add support for keyboard encode to the keypad test (from
|
||||
Denis Carikli).
|
||||
* configs/olimex-lpc1766stk/nettest: Configuration converted to
|
||||
use the kconfig-frontends tools.
|
||||
* net/net_poll.c: Split net_poll() to create psock_poll() too.
|
||||
* net/net_poll.c: Fix poll/select issure reported by Qiang:
|
||||
poll_interrupt() must call net_lostconnection() when a
|
||||
loss of connection is reported. Otherwise, the system will
|
||||
not know that the connection has been lost.
|
||||
* sched/group_create.c, group_join.c, and group_leave.c: Add
|
||||
support for task groups.
|
||||
* sched/group_signal.c and task_exithook.c: Send signal to all
|
||||
members for the parent task group.
|
||||
* include/nuttx/sched.h and sched/env_*.c: Move environment
|
||||
variables into task group structure.
|
||||
* sched/: Lots of file changed. Don't keep the parent task's
|
||||
task ID in the child task's TCB. Instead, keep the parent
|
||||
task group IN the child task's task group.
|
||||
* fs/, sched/, include/nuttx/sched.h, and include/nutts/fs/fs.h:
|
||||
Move file data from the TCB to the task group structure.
|
||||
* libc/stdio/, sched/, include/nuttx/lib.h, and include/nutts/fs/fs.h:
|
||||
Move stream data from the TCB to the task group structure.
|
||||
* net/, sched/, and include/nuttx/net/net.h: Move socket data
|
||||
from the TCB to the task group structure.
|
||||
* sched/task_starthook.c, sched/task_start.c, and include/nuttx/sched.h:
|
||||
Add a task start hook that will be called before the task main
|
||||
is started. This can be used to schedule C++ constructors to run
|
||||
automatically in the context of the new task.
|
||||
* binfmt/binfmt_execmodule: Execute constructors as a start hook.
|
||||
* sched/os_start.c: Fix ordering of group initialization.
|
||||
* configs/stm32f4discovery/usbnsh: Add an NSH STM32F4Discovery
|
||||
configuration that uses USB CDC/ACM for the NSH console.
|
||||
* configs/stm32f4discovery/nsh: Converted to use the kconfig-frontends
|
||||
tools.
|
||||
* configs/*/src/up_userleds.c: Fix a error that was cloned into
|
||||
all STM32 user LED code. The wrong definitions were being used
|
||||
to set LEDs on or off.
|
||||
* arch/*/common/up_internal.h and arch/*/common/up_initialize.c:
|
||||
Serial was driver was not being built if there is no console
|
||||
device. Obviously, the serial driver may be needed even in
|
||||
this case.
|
||||
* arch/arm/src/stm32/stm32_serial.c: If there is a serial console,
|
||||
it would be ttyS0 and the others would be ttyS1-5. If there
|
||||
is not serial console, was labeling them ttyS1-6; now labels them
|
||||
ttyS0-5.
|
||||
* fs/fs_syslog.c: Can't handle SYSLOG output to character device from
|
||||
the IDLE task (because it can't block). syslog_putc now returns EOF
|
||||
on failure and sets errno. Fixed some errors in error handling.
|
||||
* libc/stdio/lib_syslogstream.c: Checking of return value from
|
||||
syslog_putc was bogus. Switching to EOF for all errors solves
|
||||
this.
|
||||
* arch/arm/src/lm/chip/lm4f_memorymap.h: More LM4F changes from
|
||||
Jose Pablo Carballo.
|
||||
* drivers/serial/serial.c, include/nuttx/serial/serial.h,
|
||||
drivers/usbdev/cdcacm.c, and drivers/pl2303.c: Add support for
|
||||
removable serial devices (like USB serial). This support is enabled
|
||||
by CONFIG_SERIAL_REMOVABLE.
|
||||
* arch/*/src/*/Toolchain.defs: Change assignment so that we can
|
||||
override CROSSDEV with a make command line argument.
|
||||
* include/assert.h: Mark assertion functions as non-returning.
|
||||
* arch/*/src/*/up_assert.h: Mark _up_assert() as non-returning.
|
||||
* drivers/mtd/at25.c: When the AT25 device was not available the
|
||||
initialization did not fail like it should. From Petteri Aimonen.
|
||||
* fs/fat/fs_configfat.c: Fix some errors in FAT formatting logic
|
||||
for large devices and for FAT32. From Petteri Aimonen.
|
||||
* fs/fat/fs_fat32util.c: Fix an initialization error found by
|
||||
Petteri Aimonen. freecount and next freecount initialization were
|
||||
reversed.
|
||||
* drivers/mmcsd/mmcsd_spi.c: Some SD cards will appear busy until
|
||||
switched to SPI mode for first time. Having a pull-up resistor on
|
||||
MISO may avoid this problem, but this patch makes it work also
|
||||
without pull-up. From Petteri Aimonen.
|
||||
* fs/fat/fs_fat32.c: Fix a compilation error when FAT_DMAMEMORY=y.
|
||||
From Petteri Aimonen.
|
||||
* arch/arm/src/stm32/chip/stm32_spi.h: STM32F4 max SPI clock freq is
|
||||
37.5 MHz. Patch from Petteri Aimonen.
|
||||
* arch/arm/src/stm32/stm32_spi.c: Fixes for SPI DMA work on the
|
||||
STM32F4. Includes untested additions for the F1 implementation as
|
||||
well. From Petteri Aimonen.
|
||||
|
||||
6.26 2013-xx-xx Gregory Nutt <gnutt@nuttx.org>
|
||||
|
||||
* drivers/serial/serial.c: Correct some race conditions when checking
|
||||
for disconnection of a removable serial device.
|
||||
|
||||
+25
-30
@@ -297,26 +297,21 @@ config DEBUG
|
||||
---help---
|
||||
Enables built-in debug features. Selecting this option will (1) Enable
|
||||
debug assertions in the code, (2) enable extended parameter testing in
|
||||
many functions, and (3) enable support for debug output. Note that enabling
|
||||
this option by itself does not produce debug output. Debug output must
|
||||
also be selected on a subsystem-by-subsystem basis.
|
||||
many functions, and (3) enable support for debug output to the SYSLOG.
|
||||
Note that enabling this option by itself does not produce debug output.
|
||||
Debug output must also be selected on a subsystem-by-subsystem basis.
|
||||
|
||||
if DEBUG
|
||||
config DEBUG_VERBOSE
|
||||
bool "Enable Debug Verbose Output"
|
||||
default n
|
||||
---help---
|
||||
Enables verbose debug output (assuming debug output is enabled). As a
|
||||
general rule, when DEBUG is enabled only errors will be reported in the debug
|
||||
output. But if you also enable DEBUG_VERBOSE, then very chatty (and
|
||||
often annoying) output will be generated. This means there are two levels
|
||||
of debug output: errors-only and everything.
|
||||
|
||||
config DEBUG_ENABLE
|
||||
bool "Enable Debug Controls"
|
||||
default n
|
||||
---help---
|
||||
Support an interface to dynamically enable or disable debug output.
|
||||
Enables verbose debug output (assuming debug featurses are enabled).
|
||||
As a general rule, when DEBUG is enabled only errors will be
|
||||
reported in the debug SYSLOG output. But if you also enable
|
||||
DEBUG_VERBOSE, then very chatty (and often annoying) output will be
|
||||
generated. This means there are two levels of debug output:
|
||||
errors-only and everything.
|
||||
|
||||
comment "Subsystem Debug Options"
|
||||
|
||||
@@ -324,58 +319,58 @@ config DEBUG_MM
|
||||
bool "Enable Memory Manager Debug Output"
|
||||
default n
|
||||
---help---
|
||||
Enable memory management debug output (disabled by default)
|
||||
Enable memory management debug SYSLOG output (disabled by default)
|
||||
|
||||
config DEBUG_SCHED
|
||||
bool "Enable Scheduler Debug Output"
|
||||
default n
|
||||
---help---
|
||||
Enable OS debug output (disabled by default)
|
||||
Enable OS debug SYSLOG output (disabled by default)
|
||||
|
||||
config DEBUG_PAGING
|
||||
bool "Enable Demand Paging Debug Output"
|
||||
default n
|
||||
depends on PAGING
|
||||
---help---
|
||||
Enable demand paging debug output (disabled by default)
|
||||
Enable demand paging debug SYSLOG output (disabled by default)
|
||||
|
||||
config DEBUG_NET
|
||||
bool "Enable Network Debug Output"
|
||||
default n
|
||||
depends on NET
|
||||
---help---
|
||||
Enable network debug output (disabled by default)
|
||||
Enable network debug SYSLOG output (disabled by default)
|
||||
|
||||
config DEBUG_USB
|
||||
bool "Enable USB Debug Output"
|
||||
default n
|
||||
depends on USBDEV || USBHOST
|
||||
---help---
|
||||
Enable usb debug output (disabled by default)
|
||||
Enable usb debug SYSLOG output (disabled by default)
|
||||
|
||||
config DEBUG_FS
|
||||
bool "Enable File System Debug Output"
|
||||
default n
|
||||
---help---
|
||||
Enable file system debug output (disabled by default)
|
||||
Enable file system debug SYSLOG output (disabled by default)
|
||||
|
||||
config DEBUG_LIB
|
||||
bool "Enable C Library Debug Output"
|
||||
default n
|
||||
---help---
|
||||
Enable C library debug output (disabled by default)
|
||||
Enable C library debug SYSLOG output (disabled by default)
|
||||
|
||||
config DEBUG_BINFMT
|
||||
bool "Enable Binary Loader Debug Output"
|
||||
default n
|
||||
---help---
|
||||
Enable binary loader debug output (disabled by default)
|
||||
Enable binary loader debug SYSLOG output (disabled by default)
|
||||
|
||||
config DEBUG_GRAPHICS
|
||||
bool "Enable Graphics Debug Output"
|
||||
default n
|
||||
---help---
|
||||
Enable NX graphics debug output (disabled by default)
|
||||
Enable NX graphics debug SYSLOG output (disabled by default)
|
||||
|
||||
comment "Driver Debug Options"
|
||||
|
||||
@@ -384,21 +379,21 @@ config DEBUG_LCD
|
||||
default n
|
||||
depends on LCD
|
||||
---help---
|
||||
Enable low level debug output from the LCD driver (disabled by default)
|
||||
Enable low level debug SYSLOG output from the LCD driver (disabled by default)
|
||||
|
||||
config DEBUG_INPUT
|
||||
bool "Enable Input Device Debug Output"
|
||||
default n
|
||||
depends on INPUT
|
||||
---help---
|
||||
Enable low level debug output from the input device drivers such as
|
||||
Enable low level debug SYSLOG output from the input device drivers such as
|
||||
mice and touchscreens (disabled by default)
|
||||
|
||||
config DEBUG_ANALOG
|
||||
bool "Enable Analog Device Debug Output"
|
||||
default n
|
||||
---help---
|
||||
Enable low level debug output from the analog device drivers such as
|
||||
Enable low level debug SYSLOG output from the analog device drivers such as
|
||||
A/D and D/A converters (disabled by default)
|
||||
|
||||
config DEBUG_I2C
|
||||
@@ -406,27 +401,27 @@ config DEBUG_I2C
|
||||
default n
|
||||
depends on I2C
|
||||
---help---
|
||||
Enable I2C driver debug output (disabled by default)
|
||||
Enable I2C driver debug SYSLOG output (disabled by default)
|
||||
|
||||
config DEBUG_SPI
|
||||
bool "Enable SPI Debug Output"
|
||||
default n
|
||||
depends on SPI
|
||||
---help---
|
||||
Enable I2C driver debug output (disabled by default)
|
||||
Enable I2C driver debug SYSLOG output (disabled by default)
|
||||
|
||||
config DEBUG_DMA
|
||||
bool "Enable DMA Debug Output"
|
||||
default n
|
||||
---help---
|
||||
Enable DMA-releated debug output (disabled by default)
|
||||
Enable DMA-releated debug SYSLOG output (disabled by default)
|
||||
|
||||
config DEBUG_WATCHDOG
|
||||
bool "Enable Watchdog Timer Debug Output"
|
||||
default n
|
||||
depends on WATCHDOG
|
||||
---help---
|
||||
Enable watchdog timer debug output (disabled by default)
|
||||
Enable watchdog timer debug SYSLOG output (disabled by default)
|
||||
|
||||
endif
|
||||
|
||||
|
||||
+41
-14
@@ -280,8 +280,14 @@ NuttX Configuration Tool
|
||||
|
||||
make menuconfig
|
||||
|
||||
This make target will bring up NuttX configuration menus. The
|
||||
'menuconfig' target depends on two things:
|
||||
This make target will bring up NuttX configuration menus.
|
||||
|
||||
WARNING: Never do 'make menuconfig' on a configuration that has
|
||||
not been converted to use the kconfig-frontends tools! This will
|
||||
damage your configuration (see
|
||||
http://www.nuttx.org/doku.php?id=wiki:howtos:convertconfig).
|
||||
|
||||
The 'menuconfig' make target depends on two things:
|
||||
|
||||
1. The Kconfig configuration data files that appear in almost all
|
||||
NuttX directories. These data files are the part that is still
|
||||
@@ -319,6 +325,22 @@ NuttX Configuration Tool
|
||||
This is pretty straight forward for creating new configurations
|
||||
but may be less intuitive for modifying existing configurations.
|
||||
|
||||
Refreshing Configurations with 'make oldconfig'
|
||||
-----------------------------------------------
|
||||
|
||||
Whenever you use a configuration, you really should always do
|
||||
the following *before* you make NuttX:
|
||||
|
||||
make oldconfig
|
||||
|
||||
This will make sure that the configuration is up-to-date in
|
||||
the event that it has lapsed behind the current NuttX development.
|
||||
|
||||
WARNING: Never do 'make oldconfig' (OR 'make menuconfig') on a
|
||||
configuration that has not been converted to use the kconfig-frontends
|
||||
tools! This will damage your configuration (see
|
||||
http://www.nuttx.org/doku.php?id=wiki:howtos:convertconfig).
|
||||
|
||||
Incompatibilities with Older Configurations
|
||||
-------------------------------------------
|
||||
|
||||
@@ -501,8 +523,21 @@ NuttX Buildroot Toolchain
|
||||
|
||||
Disadvantages: This tool chain is not was well supported as some other
|
||||
toolchains. GNU tools are not my priority and so the buildroot tools
|
||||
often get behind. For example, the is still no EABI support in the
|
||||
NuttX buildroot toolchain for ARM.
|
||||
often get behind. For example, until recently there was no EABI support
|
||||
in the NuttX buildroot toolchain for ARM.
|
||||
|
||||
NOTE: For Cortex-M3/4, there are OABI and EABI versions of the buildroot
|
||||
toolchains. If you are using the older OABI toolchain the prefix for
|
||||
the tools will be arm-nuttx-elf-; for the EABI toolchin the prefix will
|
||||
be arm-nuttx-eabi-. If you are using the older OABI toolchain with
|
||||
an ARM Cortex-M3/4, you will need to set CONFIG_ARMV7M_OABI_TOOLCHAIN
|
||||
in the .config file in order to pick the right tool prefix.
|
||||
|
||||
If the make system ever picks the wrong prefix for your toolchain, you
|
||||
can always specify the prefix on the command to override the default
|
||||
like:
|
||||
|
||||
make CROSSDEV=arm-nuttx-elf
|
||||
|
||||
SHELLS
|
||||
^^^^^^
|
||||
@@ -1159,17 +1194,9 @@ apps
|
||||
|- NxWidgets/
|
||||
| `- README.txt
|
||||
|- system/
|
||||
| |- i2c/README.txt
|
||||
| |- free/README.txt
|
||||
| |- install
|
||||
| |- i2c
|
||||
| | `- README.txt
|
||||
| |- poweroff
|
||||
| | `- README.txt
|
||||
| |- ramtron
|
||||
| | `- README.txt
|
||||
| |- sdcard
|
||||
| | `- README.txt
|
||||
| `- sysinfo
|
||||
| `- install
|
||||
| `- README.txt
|
||||
`- README.txt
|
||||
|
||||
|
||||
@@ -3440,3 +3440,323 @@ Bugfixes (see the change log for details). Some of these are very important
|
||||
* Applications: Modbus fixes from Freddie Chopin.
|
||||
|
||||
As well as other, less critical bugs (see the ChangeLog for details)
|
||||
|
||||
NuttX-6.25
|
||||
^^^^^^^^^^
|
||||
|
||||
The 92nd release of NuttX, Version 6.25, was made on February 1, 2013,
|
||||
and is available for download from the SourceForge website. Note
|
||||
that release consists of two tarballs: nuttx-6.25.tar.gz and
|
||||
apps-6.25.tar.gz. Both may be needed (see the top-level nuttx/README.txt
|
||||
file for build information).
|
||||
|
||||
This release corresponds with SVN release number: r5595
|
||||
|
||||
Note that all SVN information has been stripped from the tarballs. If you
|
||||
need the SVN configuration information, you should check out directly from
|
||||
SVN. Revision r5595 should equivalent to release 6.25 of NuttX:
|
||||
|
||||
svn checkout -r5595 svn://svn.code.sf.net/p/nuttx/code/trunk nuttx-code
|
||||
|
||||
Or (HTTP):
|
||||
|
||||
svn checkout -r5595 http://svn.code.sf.net/p/nuttx/code/trunk nuttx-code
|
||||
|
||||
Additional new features and extended functionality:
|
||||
|
||||
* OS Initialization
|
||||
|
||||
- Removed support for CONFIG_BUILTIN_APP_START. This is not really a
|
||||
useful feature and creates a violation of the OS layered
|
||||
architecture.
|
||||
|
||||
* Task Creation:
|
||||
|
||||
- Implement a simple vfork(). In NuttX-6.25, this interface is
|
||||
available only for ARM7/9, ARMv7-M (Cortext-M3/4), and MIPS32
|
||||
(PIC32MX) platforms.
|
||||
- exec() now sets the priority of the new task to the same priority as
|
||||
the parent task (instead of the arbirtrary value of 50).
|
||||
- New, partially complient implementations of execv() and execl().
|
||||
These are only partially compliant because they do not overlay any
|
||||
existing "process space" but rather create the new task and exit().
|
||||
- Add a complete implementation of posix_spawn(). This standard
|
||||
interface is a better match for an MMU-less architecture than are
|
||||
vfork() plus execv() or execl().
|
||||
- Add a task start hook that will be called before the task main
|
||||
is started. This can be used, for example, to schedule C++
|
||||
static constructors to run automatically in the context of the
|
||||
new task.
|
||||
|
||||
* Task Parentage
|
||||
|
||||
- Repartitioned tasking data structures. All shared resources are now
|
||||
collected together in a "task group". A task group includes the
|
||||
original task plus all of the pthreads created by the task.
|
||||
- Added support for remember the parent "task group" when a new task is
|
||||
started.
|
||||
- Added optional support to record the membership of each thread in
|
||||
the "task group".
|
||||
- Implement support for retaining child task status in the "task group"
|
||||
after the child task exists. This is behavior required by POSIX.
|
||||
But in NuttX is only enabled with CONFIG_SCHED_HAVE_PARENT and
|
||||
CONFIG_SCHED_CHILD_STATUS
|
||||
- Add internal logic to "reparent" a task. This is useful,
|
||||
for example, where the child task is created through a trampoline
|
||||
task that redirects I/O. Reparenting allows the caller of posix_spawn()
|
||||
to be reparented for the eventual child thread.
|
||||
- Added support for SIGCHLD. Sent to all members of the parent task
|
||||
group when the file member of the child task group exits.
|
||||
- If SIGCHLD and retention of child task exist status are enabled, then
|
||||
a more spec-compliant version of waitpid() is enabled.
|
||||
- New interfaces waitid() and wait() are also enabled when SIGCHLD
|
||||
is enabled.
|
||||
|
||||
* File System
|
||||
|
||||
- dup() and dup2() can new be used with opened files in a mounted file
|
||||
system. This supports re-direction of output in NSH to files.
|
||||
- The binfs file system was moved from apps/builtin to fs/binfs. The
|
||||
binfs file system was extended to support execution of "builtin
|
||||
applications" using exec(), execv(), execl(), or posix_spawn().
|
||||
- Added logic based on SIGCHLD to automatically unload and clean-up
|
||||
after running a task that was loaded into memory.
|
||||
|
||||
* Binary Formats
|
||||
|
||||
- Much of the logic for "builtin applications" was moved from
|
||||
apps/builtin to nuttx/binfmt/libbuiltin. Includes some extensions
|
||||
contributed by Mike Smith.
|
||||
- A binary loader was added for builtin applications to support
|
||||
execution of "builtin applications" using exec(), execv(),
|
||||
execl(), or posix_spawn().
|
||||
|
||||
* Drivers:
|
||||
|
||||
- Added logic to marshal and serialized "out-of-band" keyboard
|
||||
commands (such as cursor controls and key release events) intermixed
|
||||
with normal ASCII keypress data. The encoding is partially integrated
|
||||
in the HID keyboard driver and the decoding full integrated into the
|
||||
apps/examples hidkbd and keypadtest (the latter contributed by Denis
|
||||
Carlikli).
|
||||
- Driver for the UG-2864HSWEG01 OLED contributed by Darcy Gong.
|
||||
- Add support for removable serial devices (like USB serial). This
|
||||
support is enabled by CONFIG_SERIAL_REMOVABLE.
|
||||
|
||||
* ARMv7-M:
|
||||
|
||||
- Added an option to use the BASEPRI register to disable interrupts
|
||||
(instead of the PRIMASK). This eliminates some innocuous hardfaults
|
||||
that interfere with some debug tools. You need to switch to the
|
||||
BASEPRI method only if you have such tool interference.
|
||||
|
||||
* STM32 Drivers
|
||||
|
||||
- Bring STM32 F1 DMA capabilities up to par with the STM32 F2/F4
|
||||
(contributed by Mike Smith).
|
||||
- Add support for USART single wire mode (Contributed by the PX4
|
||||
team).
|
||||
- Updates to support for SPI DMA on the STM32 F1/F2/F4. From
|
||||
Petteri Aimonen.
|
||||
|
||||
* STM32 Boards:
|
||||
|
||||
- New configuration to support the UG-2864HSWEG01 OLED on the
|
||||
STM32F4Discovery board.
|
||||
- Added a posix_spawn() test configuration for the STM32F4Discovery.
|
||||
|
||||
* LM3S/LM4F
|
||||
|
||||
- Files and directories repartitioned to support both LM3S and LM4F
|
||||
using the STM32 organization as a model.
|
||||
- Partial definitions for the LM4F contributed by Jose Pablo Carballo
|
||||
(this is still a work in progress).
|
||||
|
||||
* LM3S Boards
|
||||
|
||||
- Added scripts and documentation to use OpenOCD with the LM3S (from
|
||||
Jose Pablo Carballo).
|
||||
|
||||
* LPC176x/LPC178x
|
||||
|
||||
- Files and directories repartitioned to support both LPC175x/LPC176x
|
||||
and the LPC177x/LPC178x families using the STM32 organization as a
|
||||
model. The LPC1788 port is a work in progress by Rommel Marcelo.
|
||||
|
||||
* LPC176x/LPC178x Boards:
|
||||
|
||||
- Added a configuration to support the Wave Share Open1788 board.
|
||||
This is still a work in progress by Rommel Marcelo.
|
||||
|
||||
* LPC2148 Boards:
|
||||
|
||||
- Add basic support for the The0.net ZP213x/4xPA board (with the LPC2148
|
||||
and the UG_2864AMBAG01 OLED).
|
||||
- Add an nxlines configuration for the ZP213x/4xPA (with the LPC2148
|
||||
and the UG_2864AMBAG01).
|
||||
|
||||
* Simulator:
|
||||
|
||||
- Add an nxlines configuration for the simulator.
|
||||
|
||||
* Networking:
|
||||
|
||||
- Add logic to work around delayed ACKs by splitting packets
|
||||
(contributed by Yan T.).
|
||||
- Split net_poll() to create the internal interface psock_poll().
|
||||
|
||||
* LCDs:
|
||||
|
||||
- Added support for LCD1602 alphanumeric LCD (HD4468OU controller).
|
||||
|
||||
* Graphics:
|
||||
|
||||
- Added 5x8 monospace font. This tiny font is useful for graph
|
||||
labels and for small bitmapped display. Contributed by Petteri
|
||||
Aimonen.
|
||||
|
||||
* Build System:
|
||||
|
||||
- Add an options to better manage toolchain prefixes.
|
||||
- Redesigned how the context targer works in the apps/ directory.
|
||||
The old design caused lots of problems when changing configurations
|
||||
because there is no easy way to get the system to rebuild the
|
||||
context. This change should solve most the problems and eliminate
|
||||
questions like "Why don't I see my builtin application in NSH?"
|
||||
|
||||
* Kconfig Files:
|
||||
|
||||
- There are several new configurations that use the kconfig-frontends
|
||||
tools and several older configurations that have been converted to
|
||||
use these tools. There is still a long way to go before the conversion
|
||||
is complete:
|
||||
|
||||
configs/sim/nxwm
|
||||
configs/sim/nsh
|
||||
configs/stm3220g-eval/nxwm
|
||||
configs/stm32f4discovery/posix_spawn
|
||||
configs/olimex-lpc1766stk/nsh
|
||||
configs/olimex-lpc1766stk/hidkbd
|
||||
configs/olimex-lpc1766stk/nettest
|
||||
configs/open1788/ostest
|
||||
configs/stm32f4discovery/nsh
|
||||
configs/stm32f4discovery/usbnsh
|
||||
configs/lm326965-ek (all configurations)
|
||||
configs/mcu123-214x/nsh
|
||||
configs/ubw32/ostest
|
||||
|
||||
* Tools:
|
||||
|
||||
- tools/kconfig.bat: Kludge to run kconfig-frontends from a DOS shell.
|
||||
- tools/configure.c: configure.c can be used to build a work-alike
|
||||
program as a replacement for configure.sh. This work-alike
|
||||
program would be used in environments that do not support Bash
|
||||
scripting (such as the Windows native environment).
|
||||
- tools/configure.bat: configure.bat is a small Windows batch
|
||||
file that can be used as a replacement for configure.sh in a
|
||||
Windows native environment. configure.bat is actually just a
|
||||
thin layer that executes configure.exe if it is available. If
|
||||
configure.exe is not available, then configure.bat will attempt
|
||||
to build it first.
|
||||
|
||||
* Applications:
|
||||
|
||||
- New and modified examples:
|
||||
|
||||
apps/examples/wlan: Remove non-functional example.
|
||||
apps/examples/ostest: Added a test of vfork(). Extend signal
|
||||
handler test to catch death-of-child signals (SIGCHLD). Add a
|
||||
test for waitpid(), waitid(), and wait().
|
||||
apps/exampes/posix_spawn: Added a test of posix_spawn().
|
||||
|
||||
- NSH:
|
||||
|
||||
NSH now supports re-direction of I/O to files (but still not from).
|
||||
The block driver source argument to the mount command is now
|
||||
optional for file systems that do not require a block driver.
|
||||
NSH can now execute a program from a file system using posix_spawn().
|
||||
Added support for a login script. The init.d/rcS script will be
|
||||
executed once when NSH starts; the .nshrc script will be executed
|
||||
for each session: Once for serial, once for each USB connection,
|
||||
once for each Telnet session.
|
||||
|
||||
- Supports a new daemon that can be used to monitor USB trace outpout.
|
||||
- Removed non-functional wlan example.
|
||||
|
||||
Bugfixes (see the ChangeLog for details). Some of these are very important:
|
||||
|
||||
* Tasking:
|
||||
|
||||
- Fixed a *critical* task exit bug. Here is the failure scenario:
|
||||
(1) sched_lock() is called increments the lockcount on the current
|
||||
TCB (i.e., the one at the head of the ready to run list), (2)
|
||||
sched_mergepending is called which may change the task at the head
|
||||
of the ready-to-run list, then (3) sched_unlock() is called which
|
||||
decrements the lockcount on the wrong TCB. The failure case that
|
||||
I saw was that pre-emption got disabled in the IDLE thread, locking
|
||||
up the whole system.
|
||||
|
||||
* Signals:
|
||||
|
||||
- sigtimedwait() would return a bad signal number if the signal was
|
||||
already pending when the function was called.
|
||||
|
||||
* Drivers:
|
||||
|
||||
- Some SD cards will appear busy until switched to SPI mode for
|
||||
first time. Having a pull-up resistor on MISO may avoid this
|
||||
problem, but this fix from Petteri Aimonen makes it work also
|
||||
without pull-up.
|
||||
|
||||
* STM32 Drivers:
|
||||
|
||||
- STM32 FLASH driver counting error (from Freddie Chopin).
|
||||
- STM32 F4 maximum SPI frequency was wrong (corrected by Petteri
|
||||
Aimonen).
|
||||
|
||||
* STM32 Boards
|
||||
|
||||
- Due to cloning of untested code, the logic to control on-board
|
||||
LEDs did not work on any STM32 boards.
|
||||
- Serial devices number /dev/ttyS0-5 is there is a serial console,
|
||||
but /dev/ttyS1-6 if there is no serial console.
|
||||
|
||||
* Binary Formats
|
||||
|
||||
- C++ static constructors execute now using a start taskhook
|
||||
so that they execute in the context of the child task (instead
|
||||
of in the context of the parent task).
|
||||
|
||||
* File Systems:
|
||||
|
||||
- Several FAT-related bugs fixed by Petteri Aimonen.
|
||||
|
||||
* Networking:
|
||||
|
||||
- Fix poll/select issure reported by Qiang: poll_interrupt() must call
|
||||
net_lostconnection() when a loss of connection is reported. Otherwise,
|
||||
the system will not remember that the connection has been lost and will
|
||||
hang waiting on a unconnected socket later.
|
||||
- Similar issues corrected for recvfrom() and send().
|
||||
- Telnetd would hang in a loop if recv() ever returned a value <= 0.
|
||||
|
||||
* Libraries:
|
||||
|
||||
- fread() could hang on certain error conditions.
|
||||
- Can't handle SYSLOG output to a character device from the IDLE task
|
||||
(because the IDLE task can't block).
|
||||
|
||||
* Build System:
|
||||
|
||||
- Serial was driver was not being built if there is no console
|
||||
device. Obviously, the serial driver may be needed even in
|
||||
this case.
|
||||
|
||||
* Additional Bugfixes:
|
||||
|
||||
- sig_timedwait() and clock_time2ticks.c: Timing "rounding" logic
|
||||
- ARM9 Compilation issue with low vectors.
|
||||
- readline() return value
|
||||
- Others as detailed in the ChangeLog: HID keyboard, LPC17xx bit
|
||||
definitions, strndup(), PL2303, SYSLOG error handling, AT25,
|
||||
apps/examples.
|
||||
|
||||
+30
-56
@@ -1,4 +1,4 @@
|
||||
NuttX TODO List (Last updated January 23, 2013)
|
||||
NuttX TODO List (Last updated January 30, 2013)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This file summarizes known NuttX bugs, limitations, inconsistencies with
|
||||
@@ -7,14 +7,14 @@ standards, things that could be improved, and ideas for enhancements.
|
||||
nuttx/
|
||||
|
||||
(11) Task/Scheduler (sched/)
|
||||
(1) Memory Managment (mm/)
|
||||
(2) Memory Managment (mm/)
|
||||
(3) Signals (sched/, arch/)
|
||||
(2) pthreads (sched/)
|
||||
(2) C++ Support
|
||||
(6) Binary loaders (binfmt/)
|
||||
(17) Network (net/, drivers/net)
|
||||
(16) Network (net/, drivers/net)
|
||||
(4) USB (drivers/usbdev, drivers/usbhost)
|
||||
(12) Libraries (libc/, )
|
||||
(11) Libraries (libc/, )
|
||||
(9) File system/Generic drivers (fs/, drivers/)
|
||||
(5) Graphics subystem (graphics/)
|
||||
(1) Pascal add-on (pcode/)
|
||||
@@ -161,25 +161,6 @@ o Task/Scheduler (sched/)
|
||||
Status: Open
|
||||
Priority: Medium Low for now
|
||||
|
||||
Title: IMPROVED TASK CONTROL BLOCK STRUCTURE
|
||||
Description: All task resources that are shared amongst threads have
|
||||
their own "break-away", reference-counted structure. The
|
||||
Task Control Block (TCB) of each thread holds a reference
|
||||
to each breakaway structure (see include/nuttx/sched.h).
|
||||
It would be more efficent to have one reference counted
|
||||
structure that holds all of the shared resources.
|
||||
|
||||
These are the current shared structures:
|
||||
- Environment varaibles (struct environ_s)
|
||||
- PIC data space and address environments (struct dspace_s)
|
||||
- File descriptors (struct filelist)
|
||||
- FILE streams (struct streamlist)
|
||||
- Sockets (struct socketlist)
|
||||
Status: Open
|
||||
Priority: Low. This is an enhancement. It would slight reduce
|
||||
memory usage but would also increase coupling. These
|
||||
resources are nicely modular now.
|
||||
|
||||
Title: ISSUES WITH atexit() AND on_exit()
|
||||
Description: These functions execute with the following bad properties:
|
||||
|
||||
@@ -212,6 +193,16 @@ o Task/Scheduler (sched/)
|
||||
Status: Open
|
||||
Priority: Low (it might as well be low since it isn't going to be fixed).
|
||||
|
||||
Title: errno IS NOT SHARED AMONG THREADS
|
||||
Description: In NuttX, the errno value is unique for each thread. But for
|
||||
bug-for-bug compatibility, the same errno should be shared by
|
||||
the task and each thread that it creates. It is *very* easy
|
||||
to make this change: Just move the pterrno field from
|
||||
_TCB to struct task_group_s. However, I am still not sure
|
||||
if this should be done or not.
|
||||
Status: Open
|
||||
Priority: Low
|
||||
|
||||
o Memory Managment (mm/)
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -278,6 +269,19 @@ o Memory Managment (mm/)
|
||||
Priority: Medium/Low, a good feature to prevent memory leaks but would
|
||||
have negative impact on memory usage and code size.
|
||||
|
||||
Title: CONTAINER ALLOCATOR
|
||||
Description: There are several places where the logic requires allocation of
|
||||
a tiny structure that just contains pointers to other things or
|
||||
small amounts of data that needs to be bundled together. There
|
||||
are examples net/net_poll.c and numerous other places.
|
||||
|
||||
I am wondering if it would not be good create a pool of generic
|
||||
containers (say void *[4]). There re-use these when we need
|
||||
small containers. The code in sched/task_childstatus.c might
|
||||
be generalized for this purpose.
|
||||
Status: Open
|
||||
Priority: Very low (I am not even sure that this is a good idea yet).
|
||||
|
||||
o Signals (sched/, arch/)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -413,6 +417,9 @@ o Binary loaders (binfmt/)
|
||||
Description: Not all of the NXFLAT test under apps/examples/nxflat are working.
|
||||
Most simply do not compile yet. tests/mutex runs okay but
|
||||
outputs garbage on completion.
|
||||
|
||||
Update: 13-27-1, tests/mutex crashed with a memory corruption
|
||||
problem the last time that I ran it.
|
||||
Status: Open
|
||||
Priority: High
|
||||
|
||||
@@ -667,21 +674,6 @@ o Network (net/, drivers/net)
|
||||
Status: Open
|
||||
Priority: Low... fix defconfig files as necessary.
|
||||
|
||||
Title: net_poll() DOES NOT HANDLE LOSS-OF-CONNECTION CORRECTLY
|
||||
Description: When a loss of connection is detected by any logic waiting on the
|
||||
networking events, the function net_lostconnection() must be called.
|
||||
That function just sets some bits in the socket structure so that
|
||||
it remembers that the connection is lost.
|
||||
|
||||
That is currently done in recvfrom(), send(), and net_monitor.c. But
|
||||
it is not done in the net_poll() logic; that logic correctly sets
|
||||
the POLLHUP status, but it does not call net_lostconnection(). As a
|
||||
result, if recv() is called after the poll() or select(), the system
|
||||
will hang because the recv() does not know that the connection has
|
||||
been lost.
|
||||
Status: Open
|
||||
Priority: High
|
||||
|
||||
o USB (drivers/usbdev, drivers/usbhost)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -820,19 +812,6 @@ o Libraries (libc/)
|
||||
Status: Open
|
||||
Priority: ??
|
||||
|
||||
Title: SYSLOG INTEGRATION
|
||||
Description: There are the beginnings of some system logging capabilities (see
|
||||
drivers/syslog, fs/fs_syslog.c, and libc/stdio/lib_librawprintf.c and
|
||||
lib_liblowprintf.c. For NuttX, SYSLOG is a concept and includes,
|
||||
extends, and replaces the legacy NuttX debug ouput. Some additional
|
||||
integration is required to formalized this. For example:
|
||||
|
||||
o lib_rawprintf() shjould be renamed syslog().
|
||||
o debug.h should be renamed syslog.h
|
||||
o And what about lib_lowprintf()? llsyslog?
|
||||
Status: Open
|
||||
Priority: Low -- more of a roadmap
|
||||
|
||||
Title: FLOATING POINT FORMATS
|
||||
Description: Only the %f floating point format is supported. Others are accepted
|
||||
but treated like %f.
|
||||
@@ -1526,11 +1505,6 @@ o ARM/STM32 (arch/arm/src/stm32/)
|
||||
Status: Open
|
||||
Priority: Low
|
||||
|
||||
Title: STM32 F4 USB OTG FS DEVICE-SIDE DRIVER
|
||||
Description: This driver is reported to be buggy and to need some TLC.
|
||||
Status: Open
|
||||
Priority: High
|
||||
|
||||
o AVR (arch/avr)
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
############################################################################
|
||||
# arch/arm/src/armv7-m/Toolchain.defs
|
||||
#
|
||||
# Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
# Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@@ -141,8 +141,8 @@ endif
|
||||
# Atollic toolchain under Windows
|
||||
|
||||
ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),ATOLLIC)
|
||||
CROSSDEV = arm-atollic-eabi-
|
||||
ARCROSSDEV = arm-atollic-eabi-
|
||||
CROSSDEV ?= arm-atollic-eabi-
|
||||
ARCROSSDEV ?= arm-atollic-eabi-
|
||||
ifneq ($(CONFIG_WINDOWS_NATIVE),y)
|
||||
WINTOOL = y
|
||||
endif
|
||||
@@ -161,12 +161,12 @@ endif
|
||||
|
||||
ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),BUILDROOT)
|
||||
ifeq ($(CONFIG_ARMV7M_OABI_TOOLCHAIN),y)
|
||||
CROSSDEV = arm-nuttx-elf-
|
||||
ARCROSSDEV = arm-nuttx-elf-
|
||||
CROSSDEV ?= arm-nuttx-elf-
|
||||
ARCROSSDEV ?= arm-nuttx-elf-
|
||||
ARCHCPUFLAGS = -mtune=cortex-m3 -march=armv7-m -mfloat-abi=soft
|
||||
else
|
||||
CROSSDEV = arm-nuttx-eabi-
|
||||
ARCROSSDEV = arm-nuttx-eabi-
|
||||
CROSSDEV ?= arm-nuttx-eabi-
|
||||
ARCROSSDEV ?= arm-nuttx-eabi-
|
||||
ARCHCPUFLAGS = -mcpu=cortex-m3 -mthumb -mfloat-abi=soft
|
||||
endif
|
||||
MAXOPTIMIZATION = -Os
|
||||
@@ -175,8 +175,8 @@ endif
|
||||
# Code Red RedSuite under Linux
|
||||
|
||||
ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),CODEREDL)
|
||||
CROSSDEV = arm-none-eabi-
|
||||
ARCROSSDEV = arm-none-eabi-
|
||||
CROSSDEV ?= arm-none-eabi-
|
||||
ARCROSSDEV ?= arm-none-eabi-
|
||||
ifeq ($(CONFIG_ARCH_CORTEXM4),y)
|
||||
ifeq ($(CONFIG_ARCH_FPU),y)
|
||||
ARCHCPUFLAGS = -mcpu=cortex-m4 -mthumb -march=armv7e-m -mfpu=fpv4-sp-d16 -mfloat-abi=hard
|
||||
@@ -191,8 +191,8 @@ endif
|
||||
# Code Red RedSuite under Windows
|
||||
|
||||
ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),CODEREDW)
|
||||
CROSSDEV = arm-none-eabi-
|
||||
ARCROSSDEV = arm-none-eabi-
|
||||
CROSSDEV ?= arm-none-eabi-
|
||||
ARCROSSDEV ?= arm-none-eabi-
|
||||
ifneq ($(CONFIG_WINDOWS_NATIVE),y)
|
||||
WINTOOL = y
|
||||
endif
|
||||
@@ -210,8 +210,8 @@ endif
|
||||
# CodeSourcery under Linux
|
||||
|
||||
ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),CODESOURCERYL)
|
||||
CROSSDEV = arm-none-eabi-
|
||||
ARCROSSDEV = arm-none-eabi-
|
||||
CROSSDEV ?= arm-none-eabi-
|
||||
ARCROSSDEV ?= arm-none-eabi-
|
||||
ARCHCPUFLAGS = -mcpu=cortex-m3 -mthumb -mfloat-abi=soft
|
||||
MAXOPTIMIZATION = -O2
|
||||
endif
|
||||
@@ -219,8 +219,8 @@ endif
|
||||
# CodeSourcery under Windows
|
||||
|
||||
ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),CODESOURCERYW)
|
||||
CROSSDEV = arm-none-eabi-
|
||||
ARCROSSDEV = arm-none-eabi-
|
||||
CROSSDEV ?= arm-none-eabi-
|
||||
ARCROSSDEV ?= arm-none-eabi-
|
||||
ifneq ($(CONFIG_WINDOWS_NATIVE),y)
|
||||
WINTOOL = y
|
||||
endif
|
||||
@@ -230,8 +230,8 @@ endif
|
||||
# devkitARM under Windows
|
||||
|
||||
ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),DEVKITARM)
|
||||
CROSSDEV = arm-eabi-
|
||||
ARCROSSDEV = arm-eabi-
|
||||
CROSSDEV ?= arm-eabi-
|
||||
ARCROSSDEV ?= arm-eabi-
|
||||
ifneq ($(CONFIG_WINDOWS_NATIVE),y)
|
||||
WINTOOL = y
|
||||
endif
|
||||
@@ -241,8 +241,8 @@ endif
|
||||
# Generic GNU EABI toolchain on OS X, Linux or any typical Posix system
|
||||
|
||||
ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),GNU_EABI)
|
||||
CROSSDEV = arm-none-eabi-
|
||||
ARCROSSDEV = arm-none-eabi-
|
||||
CROSSDEV ?= arm-none-eabi-
|
||||
ARCROSSDEV ?= arm-none-eabi-
|
||||
MAXOPTIMIZATION = -O3
|
||||
ifeq ($(CONFIG_ARCH_CORTEXM4),y)
|
||||
ifeq ($(CONFIG_ARCH_FPU),y)
|
||||
@@ -258,8 +258,8 @@ endif
|
||||
# Raisonance RIDE7 under Windows
|
||||
|
||||
ifeq ($(CONFIG_ARMV7M_TOOLCHAIN),RAISONANCE)
|
||||
CROSSDEV = arm-none-eabi-
|
||||
ARCROSSDEV = arm-none-eabi-
|
||||
CROSSDEV ?= arm-none-eabi-
|
||||
ARCROSSDEV ?= arm-none-eabi-
|
||||
ifneq ($(CONFIG_WINDOWS_NATIVE),y)
|
||||
WINTOOL = y
|
||||
endif
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
|
||||
#ifdef CONFIG_ARCH_STACKDUMP
|
||||
# undef lldbg
|
||||
# define lldbg lib_lowprintf
|
||||
# define lldbg lowsyslog
|
||||
#endif
|
||||
|
||||
/* The following is just intended to keep some ugliness out of the mainline
|
||||
@@ -70,7 +70,7 @@
|
||||
*
|
||||
* CONFIG_TASK_NAME_SIZE > 0 && <-- The task has a name
|
||||
* (defined(CONFIG_DEBUG) || <-- And the debug is enabled (lldbg used)
|
||||
* defined(CONFIG_ARCH_STACKDUMP) <-- Or lib_lowprintf() is used
|
||||
* defined(CONFIG_ARCH_STACKDUMP) <-- Or lowsyslog() is used
|
||||
*/
|
||||
|
||||
#undef CONFIG_PRINT_TASKNAME
|
||||
@@ -267,7 +267,8 @@ static void up_dumpstate(void)
|
||||
* Name: _up_assert
|
||||
****************************************************************************/
|
||||
|
||||
static void _up_assert(int errorcode) /* noreturn_function */
|
||||
static void _up_assert(int errorcode) noreturn_function;
|
||||
static void _up_assert(int errorcode)
|
||||
{
|
||||
/* Are we in an interrupt handler or the idle task? */
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-m/up_reprioritizertr.c
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2012-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -89,9 +89,14 @@ void up_reprioritize_rtr(_TCB *tcb, uint8_t priority)
|
||||
/* Verify that the caller is sane */
|
||||
|
||||
if (tcb->task_state < FIRST_READY_TO_RUN_STATE ||
|
||||
tcb->task_state > LAST_READY_TO_RUN_STATE ||
|
||||
priority < SCHED_PRIORITY_MIN ||
|
||||
priority > SCHED_PRIORITY_MAX)
|
||||
tcb->task_state > LAST_READY_TO_RUN_STATE
|
||||
#if SCHED_PRIORITY_MIN > 0
|
||||
|| priority < SCHED_PRIORITY_MIN
|
||||
#endif
|
||||
#if SCHED_PRIORITY_MAX < UINT8_MAX
|
||||
|| priority > SCHED_PRIORITY_MAX
|
||||
#endif
|
||||
)
|
||||
{
|
||||
PANIC(OSERR_BADREPRIORITIZESTATE);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* common/up_exit.c
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 201-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -75,7 +75,11 @@
|
||||
#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG)
|
||||
static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg)
|
||||
{
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NFILE_STREAMS > 0
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
FAR struct filelist *filelist;
|
||||
#if CONFIG_NFILE_STREAMS > 0
|
||||
FAR struct streamlist *streamlist;
|
||||
#endif
|
||||
int i;
|
||||
#endif
|
||||
|
||||
@@ -83,42 +87,32 @@ static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg)
|
||||
sdbg(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
if (tcb->filelist)
|
||||
filelist = tcb->group->tg_filelist;
|
||||
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||
{
|
||||
sdbg(" filelist refcount=%d\n",
|
||||
tcb->filelist->fl_crefs);
|
||||
|
||||
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||
struct inode *inode = filelist->fl_files[i].f_inode;
|
||||
if (inode)
|
||||
{
|
||||
struct inode *inode = tcb->filelist->fl_files[i].f_inode;
|
||||
if (inode)
|
||||
{
|
||||
sdbg(" fd=%d refcount=%d\n",
|
||||
i, inode->i_crefs);
|
||||
}
|
||||
sdbg(" fd=%d refcount=%d\n",
|
||||
i, inode->i_crefs);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_NFILE_STREAMS > 0
|
||||
if (tcb->streams)
|
||||
streamlist = tcb->group->tg_streamlist;
|
||||
for (i = 0; i < CONFIG_NFILE_STREAMS; i++)
|
||||
{
|
||||
sdbg(" streamlist refcount=%d\n",
|
||||
tcb->streams->sl_crefs);
|
||||
|
||||
for (i = 0; i < CONFIG_NFILE_STREAMS; i++)
|
||||
struct file_struct *filep = &streamlist->sl_streams[i];
|
||||
if (filep->fs_filedes >= 0)
|
||||
{
|
||||
struct file_struct *filep = &tcb->streams->sl_streams[i];
|
||||
if (filep->fs_filedes >= 0)
|
||||
{
|
||||
#if CONFIG_STDIO_BUFFER_SIZE > 0
|
||||
sdbg(" fd=%d nbytes=%d\n",
|
||||
filep->fs_filedes,
|
||||
filep->fs_bufpos - filep->fs_bufstart);
|
||||
sdbg(" fd=%d nbytes=%d\n",
|
||||
filep->fs_filedes,
|
||||
filep->fs_bufpos - filep->fs_bufstart);
|
||||
#else
|
||||
sdbg(" fd=%d\n", filep->fs_filedes);
|
||||
sdbg(" fd=%d\n", filep->fs_filedes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/common/up_initialize.c
|
||||
*
|
||||
* Copyright (C) 2007-2010, 2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2010, 2012-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -161,11 +161,17 @@ void up_initialize(void)
|
||||
devnull_register(); /* Standard /dev/null */
|
||||
#endif
|
||||
|
||||
/* Initialize the console device driver */
|
||||
/* Initialize the serial device driver */
|
||||
|
||||
#if defined(USE_SERIALDRIVER)
|
||||
#ifdef USE_SERIALDRIVER
|
||||
up_serialinit();
|
||||
#elif defined(CONFIG_DEV_LOWCONSOLE)
|
||||
#endif
|
||||
|
||||
/* Initialize the console device driver (if it is other than the standard
|
||||
* serial driver).
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_DEV_LOWCONSOLE)
|
||||
lowconsole_init();
|
||||
#elif defined(CONFIG_RAMLOG_CONSOLE)
|
||||
ramlog_consoleinit();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* common/up_internal.h
|
||||
*
|
||||
* Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -63,7 +63,10 @@
|
||||
#undef CONFIG_SUPPRESS_UART_CONFIG /* DEFINED: Do not reconfig UART */
|
||||
#undef CONFIG_DUMP_ON_EXIT /* DEFINED: Dump task state on exit */
|
||||
|
||||
/* Determine which (if any) console driver to use */
|
||||
/* Determine which (if any) console driver to use. If a console is enabled
|
||||
* and no other console device is specified, then a serial console is
|
||||
* assumed.
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_DEV_CONSOLE) || CONFIG_NFILE_DESCRIPTORS == 0
|
||||
# undef USE_SERIALDRIVER
|
||||
@@ -84,6 +87,16 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* If some other device is used as the console, then the serial driver may
|
||||
* still be needed. Let's assume that if the upper half serial driver is
|
||||
* built, then the lower half will also be needed. There is no need for
|
||||
* the early serial initialization in this case.
|
||||
*/
|
||||
|
||||
#if !defined(USE_SERIALDRIVER) && defined(CONFIG_STANDARD_SERIAL)
|
||||
# define USE_SERIALDRIVER 1
|
||||
#endif
|
||||
|
||||
/* Determine which device to use as the system logging device */
|
||||
|
||||
#ifndef CONFIG_SYSLOG
|
||||
|
||||
@@ -47,7 +47,13 @@
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
#define STM32_SPI_CLK_MAX 18000000UL /* Maximum allowed speed as per specifications for all SPIs */
|
||||
/* Maximum allowed speed as per specifications for all SPIs */
|
||||
|
||||
#if defined(CONFIG_STM32_STM32F40XX)
|
||||
# define STM32_SPI_CLK_MAX 37500000UL
|
||||
#else
|
||||
# define STM32_SPI_CLK_MAX 18000000UL
|
||||
#endif
|
||||
|
||||
/* Register Offsets *****************************************************************/
|
||||
|
||||
|
||||
@@ -118,25 +118,12 @@ struct stm32_dev_s
|
||||
uint32_t freq; /* The desired frequency of conversions */
|
||||
#endif
|
||||
uint8_t chanlist[ADC_MAX_SAMPLES];
|
||||
#ifdef CONFIG_ADC_DMA
|
||||
const unsigned int rxdma_channel; /* DMA channel assigned */
|
||||
DMA_HANDLE rxdma; /* currently-open receive DMA stream */
|
||||
bool rxenable; /* DMA-based reception en/disable */
|
||||
uint32_t rxdmanext; /* Next byte in the DMA buffer to be read */
|
||||
int32_t *const rxfifo; /* Receive DMA buffer */
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
# ifdef CONFIG_ADC_DMA
|
||||
static int16_t g_adc3dmarxfifo[ADC_MAX_SAMPLES];
|
||||
# endif
|
||||
|
||||
|
||||
|
||||
/* ADC Register access */
|
||||
|
||||
static uint32_t adc_getreg(struct stm32_dev_s *priv, int offset);
|
||||
@@ -179,15 +166,6 @@ static int adc_timinit(FAR struct stm32_dev_s *priv);
|
||||
static void adc_startconv(FAR struct stm32_dev_s *priv, bool enable);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ADC_DMA
|
||||
static int up_dma_setup(struct adc_dev_s *dev);
|
||||
static void up_dma_shutdown(struct adc_dev_s *dev);
|
||||
//static int up_dma_receive(struct uart_dev_s *dev, uint32_t *status);
|
||||
//static void up_dma_rxint(struct uart_dev_s *dev, bool enable);
|
||||
//static bool up_dma_rxavailable(struct uart_dev_s *dev);
|
||||
static void up_dma_rxcallback(DMA_HANDLE handle, uint8_t status, FAR struct adc_dev_s *dev);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
@@ -284,10 +262,6 @@ static struct stm32_dev_s g_adcpriv3 =
|
||||
.pclck = ADC3_TIMER_PCLK_FREQUENCY,
|
||||
.freq = CONFIG_STM32_ADC3_SAMPLE_FREQUENCY,
|
||||
#endif
|
||||
#ifdef CONFIG_ADC_DMA
|
||||
.rxdma_channel = DMAMAP_ADC3_2,
|
||||
.rxfifo = g_adc3dmarxfifo,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct adc_dev_s g_adcdev3 =
|
||||
@@ -569,7 +543,7 @@ static int adc_timinit(FAR struct stm32_dev_s *priv)
|
||||
* So ( prescaler = pclck / 65535 / freq ) would be optimal.
|
||||
*/
|
||||
|
||||
prescaler = 128;//(priv->pclck / priv->freq + 65534) / 65535;
|
||||
prescaler = (priv->pclck / priv->freq + 65534) / 65535;
|
||||
|
||||
/* We need to decrement the prescaler value by one, but only, the value does
|
||||
* not underflow.
|
||||
@@ -591,7 +565,7 @@ static int adc_timinit(FAR struct stm32_dev_s *priv)
|
||||
|
||||
timclk = priv->pclck / prescaler;
|
||||
|
||||
reload = priv->freq;//timclk / priv->freq;
|
||||
reload = timclk / priv->freq;
|
||||
if (reload < 1)
|
||||
{
|
||||
adbg("WARNING: Reload value underflowed.\n");
|
||||
@@ -720,10 +694,10 @@ static int adc_timinit(FAR struct stm32_dev_s *priv)
|
||||
|
||||
case 4: /* TimerX TRGO event */
|
||||
{
|
||||
#warning "TRGO support not yet implemented"
|
||||
|
||||
/* TODO: TRGO support not yet implemented */
|
||||
/* Set the event TRGO */
|
||||
|
||||
ccenable = 0;
|
||||
egr = GTIM_EGR_TG;
|
||||
|
||||
/* Set the duty cycle by writing to the CCR register for this channel */
|
||||
@@ -936,139 +910,6 @@ static void adc_rccreset(struct stm32_dev_s *priv, bool reset)
|
||||
irqrestore(flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_dma_setup
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ADC_DMA
|
||||
static int up_dma_setup(FAR struct adc_dev_s *dev)
|
||||
{
|
||||
|
||||
FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv;
|
||||
int result;
|
||||
uint32_t regval;
|
||||
|
||||
//
|
||||
// result = up_setup(dev);
|
||||
// if (result != OK)
|
||||
// {
|
||||
// return result;
|
||||
// }
|
||||
|
||||
/* Acquire the DMA channel. This should always succeed. */
|
||||
|
||||
priv->rxdma = stm32_dmachannel(priv->rxdma_channel);
|
||||
|
||||
/* Configure for circular DMA reception into the RX fifo */
|
||||
|
||||
stm32_dmasetup(priv->rxdma,
|
||||
priv->base + STM32_ADC_DR_OFFSET,
|
||||
(uint32_t)priv->rxfifo,
|
||||
4,//buffersize
|
||||
DMA_SCR_DIR_P2M |
|
||||
DMA_SCR_CIRC |
|
||||
DMA_SCR_MINC |
|
||||
DMA_SCR_PSIZE_16BITS |
|
||||
DMA_SCR_MSIZE_16BITS |
|
||||
DMA_SCR_PBURST_SINGLE |
|
||||
DMA_SCR_MBURST_SINGLE);
|
||||
|
||||
/* Reset our DMA shadow pointer to match the address just
|
||||
* programmed above.
|
||||
*/
|
||||
|
||||
//priv->rxdmanext = 0;
|
||||
|
||||
/* Enable DMA for the ADC */
|
||||
|
||||
/* Start the DMA channel, and arrange for callbacks at the half and
|
||||
* full points in the FIFO. This ensures that we have half a FIFO
|
||||
* worth of time to claim bytes before they are overwritten.
|
||||
*/
|
||||
|
||||
stm32_dmastart(priv->rxdma, up_dma_rxcallback, (void *)dev, false);
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
/****************************************************************************
|
||||
* Name: up_dma_rxcallback
|
||||
*
|
||||
* Description:
|
||||
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ADC_DMA
|
||||
static void up_dma_rxcallback(DMA_HANDLE handle, uint8_t status, FAR struct adc_dev_s *dev)
|
||||
{
|
||||
//struct up_dev_s *priv = (struct up_dev_s*)arg;
|
||||
//uint32_t regval;
|
||||
FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv;
|
||||
//struct stm32_dma_s *dmast = (struct stm32_dma_s *)handle;
|
||||
|
||||
//if (priv->rxenable && up_dma_rxavailable(&priv->dev))
|
||||
{
|
||||
/* Give the ADC data to the ADC driver. adc_receive accepts 3 parameters:
|
||||
*
|
||||
* 1) The first is the ADC device instance for this ADC block.
|
||||
* 2) The second is the channel number for the data, and
|
||||
* 3) The third is the converted data for the channel.
|
||||
*/
|
||||
|
||||
|
||||
adc_receive(dev, 10, (int32_t)g_adc3dmarxfifo[1]);
|
||||
adc_receive(dev, 11, (int32_t)g_adc3dmarxfifo[2]);
|
||||
adc_receive(dev, 12, (int32_t)g_adc3dmarxfifo[3]);
|
||||
adc_receive(dev, 13, (int32_t)g_adc3dmarxfifo[0]);
|
||||
|
||||
|
||||
/* Set the channel number of the next channel that will complete conversion */
|
||||
|
||||
priv->current++;
|
||||
|
||||
if (priv->current >= priv->nchannels)
|
||||
{
|
||||
/* Restart the conversion sequence from the beginning */
|
||||
|
||||
priv->current = 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_dma_shutdown
|
||||
*
|
||||
* Description:
|
||||
* Disable the DMA
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ADC_DMA
|
||||
static void up_dma_shutdown(struct adc_dev_s *dev)
|
||||
{
|
||||
|
||||
FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv;
|
||||
|
||||
|
||||
/* Stop the DMA channel */
|
||||
|
||||
stm32_dmastop(priv->rxdma);
|
||||
|
||||
/* Release the DMA channel */
|
||||
|
||||
stm32_dmafree(priv->rxdma);
|
||||
priv->rxdma = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: adc_enable
|
||||
*
|
||||
@@ -1089,7 +930,7 @@ static void adc_enable(FAR struct stm32_dev_s *priv, bool enable)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
// avdbg("enable: %d\n", enable);
|
||||
avdbg("enable: %d\n", enable);
|
||||
|
||||
regval = adc_getreg(priv, STM32_ADC_CR2_OFFSET);
|
||||
if (enable)
|
||||
@@ -1123,12 +964,14 @@ static void adc_reset(FAR struct adc_dev_s *dev)
|
||||
uint32_t regval;
|
||||
int offset;
|
||||
int i;
|
||||
#ifdef ADC_HAVE_TIMER
|
||||
int ret;
|
||||
#endif
|
||||
|
||||
avdbg("intf: ADC%d\n", priv->intf);
|
||||
flags = irqsave();
|
||||
|
||||
/* Enable ADC reset state */
|
||||
/* Enable ADC reset state */
|
||||
|
||||
adc_rccreset(priv, true);
|
||||
|
||||
@@ -1146,7 +989,6 @@ static void adc_reset(FAR struct adc_dev_s *dev)
|
||||
|
||||
adc_putreg(priv, STM32_ADC_LTR_OFFSET, 0x00000000);
|
||||
|
||||
|
||||
/* Initialize the same sample time for each ADC 55.5 cycles
|
||||
*
|
||||
* During sample cycles channel selection bits must remain unchanged.
|
||||
@@ -1179,8 +1021,16 @@ static void adc_reset(FAR struct adc_dev_s *dev)
|
||||
regval |= ADC_CR1_AWDEN;
|
||||
regval |= (priv->chanlist[0] << ADC_CR1_AWDCH_SHIFT);
|
||||
|
||||
/* Enable interrupt flags */
|
||||
|
||||
regval |= ADC_CR1_ALLINTS;
|
||||
|
||||
#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
|
||||
|
||||
/* Enable or disable Overrun interrupt */
|
||||
|
||||
regval &= ~ADC_CR1_OVRIE;
|
||||
|
||||
/* Set the resolution of the conversion */
|
||||
|
||||
regval |= ACD_CR1_RES_12BIT;
|
||||
@@ -1229,12 +1079,6 @@ static void adc_reset(FAR struct adc_dev_s *dev)
|
||||
{
|
||||
regval |= (uint32_t)priv->chanlist[i] << offset;
|
||||
}
|
||||
/* Set the number of conversions */
|
||||
|
||||
DEBUGASSERT(priv->nchannels <= ADC_MAX_SAMPLES);
|
||||
|
||||
regval |= (((uint32_t)priv->nchannels-1) << ADC_SQR1_L_SHIFT);
|
||||
adc_putreg(priv, STM32_ADC_SQR1_OFFSET, regval);
|
||||
|
||||
/* ADC CCR configuration */
|
||||
|
||||
@@ -1246,7 +1090,12 @@ static void adc_reset(FAR struct adc_dev_s *dev)
|
||||
putreg32(regval, STM32_ADC_CCR);
|
||||
#endif
|
||||
|
||||
/* Set the number of conversions */
|
||||
|
||||
DEBUGASSERT(priv->nchannels <= ADC_MAX_SAMPLES);
|
||||
|
||||
regval |= (((uint32_t)priv->nchannels-1) << ADC_SQR1_L_SHIFT);
|
||||
adc_putreg(priv, STM32_ADC_SQR1_OFFSET, regval);
|
||||
|
||||
/* Set the channel index of the first conversion */
|
||||
|
||||
@@ -1269,30 +1118,25 @@ static void adc_reset(FAR struct adc_dev_s *dev)
|
||||
*/
|
||||
|
||||
adc_enable(priv, true);
|
||||
#else
|
||||
#ifdef CONFIG_ADC_DMA
|
||||
//nothing
|
||||
#else
|
||||
adc_startconv(priv, true);
|
||||
#endif
|
||||
#endif /* CONFIG_STM32_STM32F10XX */
|
||||
#endif /* ADC_HAVE_TIMER */
|
||||
|
||||
|
||||
irqrestore(flags);
|
||||
|
||||
// avdbg("SR: 0x%08x CR1: 0x%08x CR2: 0x%08x\n",
|
||||
// adc_getreg(priv, STM32_ADC_SR_OFFSET),
|
||||
// adc_getreg(priv, STM32_ADC_CR1_OFFSET),
|
||||
// adc_getreg(priv, STM32_ADC_CR2_OFFSET));
|
||||
// avdbg("SQR1: 0x%08x SQR2: 0x%08x SQR3: 0x%08x\n",
|
||||
// adc_getreg(priv, STM32_ADC_SQR1_OFFSET),
|
||||
// adc_getreg(priv, STM32_ADC_SQR2_OFFSET),
|
||||
// adc_getreg(priv, STM32_ADC_SQR3_OFFSET));
|
||||
//#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
|
||||
// avdbg("CCR: 0x%08x\n",
|
||||
// getreg32(STM32_ADC_CCR));
|
||||
//#endif
|
||||
avdbg("SR: 0x%08x CR1: 0x%08x CR2: 0x%08x\n",
|
||||
adc_getreg(priv, STM32_ADC_SR_OFFSET),
|
||||
adc_getreg(priv, STM32_ADC_CR1_OFFSET),
|
||||
adc_getreg(priv, STM32_ADC_CR2_OFFSET));
|
||||
avdbg("SQR1: 0x%08x SQR2: 0x%08x SQR3: 0x%08x\n",
|
||||
adc_getreg(priv, STM32_ADC_SQR1_OFFSET),
|
||||
adc_getreg(priv, STM32_ADC_SQR2_OFFSET),
|
||||
adc_getreg(priv, STM32_ADC_SQR3_OFFSET));
|
||||
#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
|
||||
avdbg("CCR: 0x%08x\n",
|
||||
getreg32(STM32_ADC_CCR));
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -1314,86 +1158,21 @@ static int adc_setup(FAR struct adc_dev_s *dev)
|
||||
{
|
||||
FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv;
|
||||
int ret;
|
||||
uint32_t regval;
|
||||
|
||||
|
||||
/* the adc seems to need a full reset to be enabled correctly */
|
||||
adc_reset(dev);
|
||||
|
||||
#ifndef CONFIG_ADC_DMA
|
||||
/* Attach the ADC interrupt */
|
||||
|
||||
ret = irq_attach(priv->irq, priv->isr);
|
||||
if (ret == OK)
|
||||
{
|
||||
/* Make sure that the ADC device is in the powered up, reset state */
|
||||
|
||||
adc_reset(dev);
|
||||
|
||||
/* Enable the ADC interrupt */
|
||||
|
||||
avdbg("Enable the ADC interrupt: irq=%d\n", priv->irq);
|
||||
up_enable_irq(priv->irq);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ADC_DMA
|
||||
up_dma_setup(dev);
|
||||
|
||||
|
||||
//#ifndef ADC_HAVE_TIMER
|
||||
// /*disable external trigger*/
|
||||
// regval = adc_getreg(priv, STM32_ADC_CR2_OFFSET);
|
||||
// regval |= ACD_CR2_EXTEN_NONE;
|
||||
// //regval |= ADC_CR1_DISCEN;
|
||||
// adc_putreg(priv, STM32_ADC_CR2_OFFSET, regval);
|
||||
//#else
|
||||
// /*enable external trigger*/
|
||||
// regval = adc_getreg(priv, STM32_ADC_CR2_OFFSET);
|
||||
// regval |=ADC_CR2_EXTSEL_T4CC4;
|
||||
// regval |=ACD_CR2_EXTEN_BOTH;
|
||||
// //regval |= ADC_CR2_CONT;
|
||||
// adc_putreg(priv, STM32_ADC_CR2_OFFSET, regval);
|
||||
//#endif
|
||||
|
||||
|
||||
/*enable scan mode*/
|
||||
regval = adc_getreg(priv, STM32_ADC_CR1_OFFSET);
|
||||
regval |= ADC_CR1_SCAN;
|
||||
//regval |= ADC_CR1_DISCEN;
|
||||
adc_putreg(priv, STM32_ADC_CR1_OFFSET, regval);
|
||||
|
||||
/* Enable DMA request after last transfer (Single-ADC mode) */
|
||||
//ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);
|
||||
regval = adc_getreg(priv, STM32_ADC_CR2_OFFSET);
|
||||
regval |= ADC_CR2_DDS;
|
||||
adc_putreg(priv, STM32_ADC_CR2_OFFSET, regval);
|
||||
|
||||
/* Enable ADC3 DMA */
|
||||
// ADC_DMACmd(ADC3, ENABLE);
|
||||
regval = adc_getreg(priv, STM32_ADC_CR2_OFFSET);
|
||||
regval |= ADC_CR2_DMA;
|
||||
adc_putreg(priv, STM32_ADC_CR2_OFFSET, regval);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef ADC_HAVE_TIMER
|
||||
/*set continuous conversion */
|
||||
regval = adc_getreg(priv, STM32_ADC_CR2_OFFSET);
|
||||
regval |= ADC_CR2_CONT;
|
||||
adc_putreg(priv, STM32_ADC_CR2_OFFSET, regval);
|
||||
#endif
|
||||
|
||||
/* Enable ADC3 */
|
||||
//ADC_Cmd(ADC3, ENABLE);
|
||||
regval = adc_getreg(priv, STM32_ADC_CR2_OFFSET);
|
||||
regval |= ADC_CR2_ADON;
|
||||
adc_putreg(priv, STM32_ADC_CR2_OFFSET, regval);
|
||||
|
||||
//// /*start conversion*/
|
||||
// regval = adc_getreg(priv, STM32_ADC_CR2_OFFSET);
|
||||
// regval |= ADC_CR2_SWSTART;
|
||||
// adc_putreg(priv, STM32_ADC_CR2_OFFSET, regval);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1415,24 +1194,14 @@ static void adc_shutdown(FAR struct adc_dev_s *dev)
|
||||
{
|
||||
FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv;
|
||||
|
||||
#ifdef CONFIG_ADC_DMA
|
||||
up_dma_shutdown(dev);
|
||||
#endif
|
||||
|
||||
#ifdef ADC_HAVE_TIMER
|
||||
/* stop adc timer */
|
||||
adc_timstart(priv, false);
|
||||
#endif
|
||||
|
||||
/* power down ADC */
|
||||
adc_enable(priv, false);
|
||||
|
||||
adc_rxint(dev, false);
|
||||
|
||||
/* Disable ADC interrupts and detach the ADC interrupt handler */
|
||||
|
||||
up_disable_irq(priv->irq);
|
||||
// irq_detach(priv->irq);
|
||||
// XXX Why is irq_detach here commented out?
|
||||
irq_detach(priv->irq);
|
||||
|
||||
/* Disable and reset the ADC module */
|
||||
|
||||
adc_rccreset(priv, true);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -161,6 +161,12 @@
|
||||
|
||||
#if defined(CONFIG_STM32_ADC1) || defined(CONFIG_STM32_ADC2) || defined(CONFIG_STM32_ADC3)
|
||||
|
||||
/* DMA support is not yet implemented for this driver */
|
||||
|
||||
#ifdef CONFIG_ADC_DMA
|
||||
# warning "DMA is not supported by the current driver"
|
||||
#endif
|
||||
|
||||
/* Timer configuration: If a timer trigger is specified, then get information
|
||||
* about the timer.
|
||||
*/
|
||||
|
||||
@@ -107,11 +107,11 @@
|
||||
|
||||
#if !defined(CONFIG_STM32_I2CTIMEOSEC) && !defined(CONFIG_STM32_I2CTIMEOMS)
|
||||
# define CONFIG_STM32_I2CTIMEOSEC 0
|
||||
# define CONFIG_STM32_I2CTIMEOMS 500 /* Default is 500 milliseconds */
|
||||
# define CONFIG_STM32_I2CTIMEOMS 500 /* Default is 500 milliseconds */
|
||||
#elif !defined(CONFIG_STM32_I2CTIMEOSEC)
|
||||
# define CONFIG_STM32_I2CTIMEOSEC 0 /* User provided milliseconds */
|
||||
#elif !defined(CONFIG_STM32_I2CTIMEOMS)
|
||||
# define CONFIG_STM32_I2CTIMEOMS 0 /* User provided seconds */
|
||||
# define CONFIG_STM32_I2CTIMEOMS 0 /* User provided seconds */
|
||||
#endif
|
||||
|
||||
/* Interrupt wait time timeout in system timer ticks */
|
||||
@@ -141,7 +141,7 @@
|
||||
#endif
|
||||
|
||||
/* I2C event trace logic. NOTE: trace uses the internal, non-standard, low-level
|
||||
* debug interface lib_rawprintf() but does not require that any other debug
|
||||
* debug interface syslog() but does not require that any other debug
|
||||
* is enabled.
|
||||
*/
|
||||
|
||||
@@ -219,31 +219,31 @@ struct stm32_i2c_config_s
|
||||
struct stm32_i2c_priv_s
|
||||
{
|
||||
const struct stm32_i2c_config_s *config; /* Port configuration */
|
||||
int refs; /* Referernce count */
|
||||
sem_t sem_excl; /* Mutual exclusion semaphore */
|
||||
int refs; /* Referernce count */
|
||||
sem_t sem_excl; /* Mutual exclusion semaphore */
|
||||
#ifndef CONFIG_I2C_POLLED
|
||||
sem_t sem_isr; /* Interrupt wait semaphore */
|
||||
sem_t sem_isr; /* Interrupt wait semaphore */
|
||||
#endif
|
||||
volatile uint8_t intstate; /* Interrupt handshake (see enum stm32_intstate_e) */
|
||||
volatile uint8_t intstate; /* Interrupt handshake (see enum stm32_intstate_e) */
|
||||
|
||||
uint8_t msgc; /* Message count */
|
||||
struct i2c_msg_s *msgv; /* Message list */
|
||||
uint8_t *ptr; /* Current message buffer */
|
||||
int dcnt; /* Current message length */
|
||||
uint16_t flags; /* Current message flags */
|
||||
uint8_t msgc; /* Message count */
|
||||
struct i2c_msg_s *msgv; /* Message list */
|
||||
uint8_t *ptr; /* Current message buffer */
|
||||
int dcnt; /* Current message length */
|
||||
uint16_t flags; /* Current message flags */
|
||||
|
||||
/* I2C trace support */
|
||||
|
||||
#ifdef CONFIG_I2C_TRACE
|
||||
int tndx; /* Trace array index */
|
||||
uint32_t start_time; /* Time when the trace was started */
|
||||
int tndx; /* Trace array index */
|
||||
uint32_t start_time; /* Time when the trace was started */
|
||||
|
||||
/* The actual trace data */
|
||||
|
||||
struct stm32_trace_s trace[CONFIG_I2C_NTRACE];
|
||||
#endif
|
||||
|
||||
uint32_t status; /* End of transfer SR2|SR1 status */
|
||||
uint32_t status; /* End of transfer SR2|SR1 status */
|
||||
};
|
||||
|
||||
/* I2C Device, Instance */
|
||||
@@ -281,7 +281,7 @@ static void stm32_i2c_tracenew(FAR struct stm32_i2c_priv_s *priv, uint32_t statu
|
||||
static void stm32_i2c_traceevent(FAR struct stm32_i2c_priv_s *priv,
|
||||
enum stm32_trace_e event, uint32_t parm);
|
||||
static void stm32_i2c_tracedump(FAR struct stm32_i2c_priv_s *priv);
|
||||
#endif
|
||||
#endif /* CONFIG_I2C_TRACE */
|
||||
static void stm32_i2c_setclock(FAR struct stm32_i2c_priv_s *priv,
|
||||
uint32_t frequency);
|
||||
static inline void stm32_i2c_sendstart(FAR struct stm32_i2c_priv_s *priv);
|
||||
@@ -291,7 +291,7 @@ static inline uint32_t stm32_i2c_getstatus(FAR struct stm32_i2c_priv_s *priv);
|
||||
#ifdef I2C1_FSMC_CONFLICT
|
||||
static inline uint32_t stm32_i2c_disablefsmc(FAR struct stm32_i2c_priv_s *priv);
|
||||
static inline void stm32_i2c_enablefsmc(uint32_t ahbenr);
|
||||
#endif
|
||||
#endif /* I2C1_FSMC_CONFLICT */
|
||||
static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv);
|
||||
#ifndef CONFIG_I2C_POLLED
|
||||
#ifdef CONFIG_STM32_I2C1
|
||||
@@ -582,15 +582,14 @@ static inline int stm32_i2c_sem_waitdone(FAR struct stm32_i2c_priv_s *priv, int
|
||||
abstime.tv_sec++;
|
||||
abstime.tv_nsec -= 1000 * 1000 * 1000;
|
||||
}
|
||||
#else
|
||||
#if CONFIG_STM32_I2CTIMEOMS > 0
|
||||
abstime.tv_nsec += CONFIG_STM32_I2CTIMEOMS * 1000 * 1000;
|
||||
if (abstime.tv_nsec > 1000 * 1000 * 1000)
|
||||
{
|
||||
abstime.tv_sec++;
|
||||
abstime.tv_nsec -= 1000 * 1000 * 1000;
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif CONFIG_STM32_I2CTIMEOMS > 0
|
||||
abstime.tv_nsec += CONFIG_STM32_I2CTIMEOMS * 1000 * 1000;
|
||||
if (abstime.tv_nsec > 1000 * 1000 * 1000)
|
||||
{
|
||||
abstime.tv_sec++;
|
||||
abstime.tv_nsec -= 1000 * 1000 * 1000;
|
||||
}
|
||||
#endif
|
||||
/* Wait until either the transfer is complete or the timeout expires */
|
||||
|
||||
@@ -866,11 +865,11 @@ static void stm32_i2c_tracedump(FAR struct stm32_i2c_priv_s *priv)
|
||||
struct stm32_trace_s *trace;
|
||||
int i;
|
||||
|
||||
lib_rawprintf("Elapsed time: %d\n", clock_systimer() - priv->start_time);
|
||||
syslog("Elapsed time: %d\n", clock_systimer() - priv->start_time);
|
||||
for (i = 0; i <= priv->tndx; i++)
|
||||
{
|
||||
trace = &priv->trace[i];
|
||||
lib_rawprintf("%2d. STATUS: %08x COUNT: %3d EVENT: %2d PARM: %08x TIME: %d\n",
|
||||
syslog("%2d. STATUS: %08x COUNT: %3d EVENT: %2d PARM: %08x TIME: %d\n",
|
||||
i+1, trace->status, trace->count, trace->event, trace->parm,
|
||||
trace->time - priv->start_time);
|
||||
}
|
||||
@@ -932,7 +931,7 @@ static void stm32_i2c_setclock(FAR struct stm32_i2c_priv_s *priv, uint32_t frequ
|
||||
{
|
||||
/* Fast mode speed calculation with Tlow/Thigh = 16/9 */
|
||||
|
||||
#ifdef CONFIG_I2C_DUTY16_9
|
||||
#ifdef CONFIG_STM32_I2C_DUTY16_9
|
||||
speed = (uint16_t)(STM32_PCLK1_FREQUENCY / (frequency * 25));
|
||||
|
||||
/* Set DUTY and fast speed bits */
|
||||
@@ -1071,7 +1070,7 @@ static inline uint32_t stm32_i2c_disablefsmc(FAR struct stm32_i2c_priv_s *priv)
|
||||
|
||||
/* Is this I2C1 */
|
||||
|
||||
#ifdef CONFIG_STM32_I2C2
|
||||
#if defined(CONFIG_STM32_I2C2) || defined(CONFIG_STM32_I2C3)
|
||||
if (priv->config->base == STM32_I2C1_BASE)
|
||||
#endif
|
||||
{
|
||||
@@ -1198,26 +1197,29 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv)
|
||||
{
|
||||
stm32_i2c_traceevent(priv, I2CEVENT_RCVBYTE, priv->dcnt);
|
||||
|
||||
/* No interrupts or context switches may occur in the following
|
||||
* sequence. Otherwise, additional bytes may be sent by the
|
||||
* device.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_I2C_POLLED
|
||||
irqstate_t state = irqsave();
|
||||
#endif
|
||||
|
||||
/* Receive a byte */
|
||||
|
||||
*priv->ptr++ = stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET);
|
||||
|
||||
/* Disable acknowledge when last byte is to be received */
|
||||
|
||||
priv->dcnt--;
|
||||
if (priv->dcnt == 1)
|
||||
{
|
||||
stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_ACK, 0);
|
||||
}
|
||||
priv->dcnt--;
|
||||
|
||||
#ifdef CONFIG_I2C_POLLED
|
||||
irqrestore(state);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1408,7 +1410,6 @@ static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv)
|
||||
/* Enable power and reset the peripheral */
|
||||
|
||||
modifyreg32(STM32_RCC_APB1ENR, 0, priv->config->clk_bit);
|
||||
|
||||
modifyreg32(STM32_RCC_APB1RSTR, 0, priv->config->reset_bit);
|
||||
modifyreg32(STM32_RCC_APB1RSTR, priv->config->reset_bit, 0);
|
||||
|
||||
@@ -1428,10 +1429,10 @@ static int stm32_i2c_init(FAR struct stm32_i2c_priv_s *priv)
|
||||
/* Attach ISRs */
|
||||
|
||||
#ifndef CONFIG_I2C_POLLED
|
||||
irq_attach(priv->config->ev_irq, priv->config->isr);
|
||||
irq_attach(priv->config->er_irq, priv->config->isr);
|
||||
up_enable_irq(priv->config->ev_irq);
|
||||
up_enable_irq(priv->config->er_irq);
|
||||
irq_attach(priv->config->ev_irq, priv->config->isr);
|
||||
irq_attach(priv->config->er_irq, priv->config->isr);
|
||||
up_enable_irq(priv->config->ev_irq);
|
||||
up_enable_irq(priv->config->er_irq);
|
||||
#endif
|
||||
|
||||
/* Set peripheral frequency, where it must be at least 2 MHz for 100 kHz
|
||||
@@ -1461,17 +1462,23 @@ static int stm32_i2c_deinit(FAR struct stm32_i2c_priv_s *priv)
|
||||
|
||||
stm32_i2c_putreg(priv, STM32_I2C_CR1_OFFSET, 0);
|
||||
|
||||
/* Unconfigure GPIO pins */
|
||||
|
||||
stm32_unconfiggpio(priv->config->scl_pin);
|
||||
stm32_unconfiggpio(priv->config->sda_pin);
|
||||
|
||||
/* Disable and detach interrupts */
|
||||
|
||||
#ifndef CONFIG_I2C_POLLED
|
||||
up_disable_irq(priv->config->ev_irq);
|
||||
up_disable_irq(priv->config->er_irq);
|
||||
irq_detach(priv->config->ev_irq);
|
||||
irq_detach(priv->config->er_irq);
|
||||
#endif
|
||||
modifyreg32(STM32_RCC_APB1ENR, priv->config->clk_bit, 0);
|
||||
|
||||
/* Disable clocking */
|
||||
|
||||
modifyreg32(STM32_RCC_APB1ENR, priv->config->clk_bit, 0);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -1623,7 +1630,9 @@ static int stm32_i2c_process(FAR struct i2c_dev_s *dev, FAR struct i2c_msg_s *ms
|
||||
*/
|
||||
|
||||
stm32_i2c_clrstart(priv);
|
||||
// XXX also clear busy flag in case of timeout
|
||||
|
||||
/* Clear busy flag in case of timeout */
|
||||
|
||||
status = priv->status & 0xffff;
|
||||
}
|
||||
else
|
||||
@@ -2070,4 +2079,4 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* defined(CONFIG_STM32_I2C1) || defined(CONFIG_STM32_I2C2) || defined(CONFIG_STM32_I2C3) */
|
||||
#endif /* CONFIG_STM32_I2C1 || CONFIG_STM32_I2C2 || CONFIG_STM32_I2C3 */
|
||||
|
||||
@@ -146,15 +146,6 @@
|
||||
# error "CONFIG_USBDEV_EP3_TXFIFO_SIZE is out of range"
|
||||
#endif
|
||||
|
||||
/* REVISIT! This forces a hack that polls DTXFSTS for space in the Tx FIFO.
|
||||
* Enabling this option is a BAD thing. It will cause inline waits inside
|
||||
* of the USB interrupt handler. The correct way to handle this is to
|
||||
* enable the correct TxFIFO interrupt and wait until the Tx FIFO is empty.
|
||||
* Unfortunately, the interrupt driven logic is not working... Please fix!
|
||||
*/
|
||||
|
||||
#define ENABLE_DTXFSTS_POLLHACK 1
|
||||
|
||||
/* Debug ***********************************************************************/
|
||||
/* Trace error codes */
|
||||
|
||||
@@ -184,8 +175,9 @@
|
||||
#define STM32_TRACEERR_NOEP 0x18
|
||||
#define STM32_TRACEERR_NOTCONFIGURED 0x19
|
||||
#define STM32_TRACEERR_EPOUTQEMPTY 0x1a
|
||||
#define STM32_TRACEERR_EPINQEMPTY 0x1b
|
||||
#define STM32_TRACEERR_EPINREQEMPTY 0x1b
|
||||
#define STM32_TRACEERR_NOOUTSETUP 0x1c
|
||||
#define STM32_TRACEERR_POLLTIMEOUT 0x1d
|
||||
|
||||
/* Trace interrupt codes */
|
||||
|
||||
@@ -432,7 +424,6 @@ struct stm32_usbdev_s
|
||||
|
||||
uint8_t stalled:1; /* 1: Protocol stalled */
|
||||
uint8_t selfpowered:1; /* 1: Device is self powered */
|
||||
uint8_t connected:1; /* 1: Host connected */
|
||||
uint8_t addressed:1; /* 1: Peripheral address has been set */
|
||||
uint8_t configured:1; /* 1: Class driver has been configured */
|
||||
uint8_t wakeup:1; /* 1: Device remote wake-up */
|
||||
@@ -508,7 +499,7 @@ static void stm32_ep0out_ctrlsetup(FAR struct stm32_usbdev_s *priv);
|
||||
static void stm32_txfifo_write(FAR struct stm32_ep_s *privep,
|
||||
FAR uint8_t *buf, int nbytes);
|
||||
static void stm32_epin_transfer(FAR struct stm32_ep_s *privep,
|
||||
FAR uint8_t *buf, int nbytes);
|
||||
FAR uint8_t *buf, int nbytes);
|
||||
static void stm32_epin_request(FAR struct stm32_usbdev_s *priv,
|
||||
FAR struct stm32_ep_s *privep);
|
||||
|
||||
@@ -962,7 +953,7 @@ static void stm32_txfifo_write(FAR struct stm32_ep_s *privep,
|
||||
regval |= ((uint32_t)*buf++) << 16;
|
||||
regval |= ((uint32_t)*buf++) << 24;
|
||||
|
||||
/* Then write the packed data to the TxFIFO */
|
||||
/* Then write the packet data to the TxFIFO */
|
||||
|
||||
stm32_putreg(regval, regaddr);
|
||||
}
|
||||
@@ -1082,9 +1073,6 @@ static void stm32_epin_request(FAR struct stm32_usbdev_s *priv,
|
||||
struct stm32_req_s *privreq;
|
||||
uint32_t regaddr;
|
||||
uint32_t regval;
|
||||
#ifdef ENABLE_DTXFSTS_POLLHACK
|
||||
int32_t timeout;
|
||||
#endif
|
||||
uint8_t *buf;
|
||||
int nbytes;
|
||||
int nwords;
|
||||
@@ -1113,7 +1101,7 @@ static void stm32_epin_request(FAR struct stm32_usbdev_s *priv,
|
||||
privreq = stm32_rqpeek(privep);
|
||||
if (!privreq)
|
||||
{
|
||||
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPINQEMPTY), privep->epphy);
|
||||
usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPINREQEMPTY), privep->epphy);
|
||||
|
||||
/* There is no TX transfer in progress and no new pending TX
|
||||
* requests to send. To stop transmitting any data on a particular
|
||||
@@ -1151,13 +1139,20 @@ static void stm32_epin_request(FAR struct stm32_usbdev_s *priv,
|
||||
privep->zlp = true;
|
||||
}
|
||||
|
||||
/* Loop while there are still bytes to be transferred (or a zero-length-
|
||||
* packet, ZLP, to be sent). The loop will also be terminated if there
|
||||
* is insufficient space remaining in the TxFIFO to send a complete
|
||||
* packet.
|
||||
/* Add one more packet to the TxFIFO. We will wait for the transfer
|
||||
* complete event before we add the next packet (or part of a packet
|
||||
* to the TxFIFO).
|
||||
*
|
||||
* The documentation says that we can can multiple packets to the TxFIFO,
|
||||
* but it seems that we need to get the transfer complete event before
|
||||
* we can add the next (or maybe I have got something wrong?)
|
||||
*/
|
||||
|
||||
#if 0
|
||||
while (privreq->req.xfrd < privreq->req.len || privep->zlp)
|
||||
#else
|
||||
if (privreq->req.xfrd < privreq->req.len || privep->zlp)
|
||||
#endif
|
||||
{
|
||||
/* Get the number of bytes left to be sent in the request */
|
||||
|
||||
@@ -1219,25 +1214,9 @@ static void stm32_epin_request(FAR struct stm32_usbdev_s *priv,
|
||||
|
||||
regaddr = STM32_OTGFS_DTXFSTS(privep->epphy);
|
||||
|
||||
#ifdef ENABLE_DTXFSTS_POLLHACK
|
||||
/* If ENABLE_DTXFSTS_POLLHACK is enabled , then poll DTXFSTS until
|
||||
* space in the TxFIFO is available. If it doesn't become available,
|
||||
* in a reasonable amount of time, then just pretend that it is.
|
||||
*/
|
||||
|
||||
for (timeout = 250000; timeout > 0; timeout--)
|
||||
{
|
||||
regval = stm32_getreg(regaddr);
|
||||
if ((regval & OTGFS_DTXFSTS_MASK) >= nwords)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* If ENABLE_DTXFSTS_POLLHACK is not enabled, then check once for
|
||||
* space in the TxFIFO. If space in the TxFIFO is not available,
|
||||
* then set up an interrupt to resume the transfer when the TxFIFO
|
||||
* is empty.
|
||||
/* Check for space in the TxFIFO. If space in the TxFIFO is not
|
||||
* available, then set up an interrupt to resume the transfer when
|
||||
* the TxFIFO is empty.
|
||||
*/
|
||||
|
||||
regval = stm32_getreg(regaddr);
|
||||
@@ -1253,11 +1232,12 @@ static void stm32_epin_request(FAR struct stm32_usbdev_s *priv,
|
||||
empmsk |= OTGFS_DIEPEMPMSK(privep->epphy);
|
||||
stm32_putreg(empmsk, STM32_OTGFS_DIEPEMPMSK);
|
||||
|
||||
/* Terminate the transfer loop */
|
||||
/* Terminate the transfer. We will try again when the TxFIFO empty
|
||||
* interrupt is received.
|
||||
*/
|
||||
|
||||
break;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Transfer data to the TxFIFO */
|
||||
|
||||
@@ -1290,11 +1270,12 @@ static void stm32_epin_request(FAR struct stm32_usbdev_s *priv,
|
||||
if (privreq->req.xfrd >= privreq->req.len && !privep->zlp)
|
||||
{
|
||||
usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd);
|
||||
|
||||
/* We are finished with the request (although the transfer has not
|
||||
* yet completed).
|
||||
*/
|
||||
|
||||
stm32_req_complete(privep, OK);
|
||||
|
||||
/* The endpoint is no longer transferring data */
|
||||
|
||||
privep->active = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2690,7 +2671,7 @@ static inline void stm32_epin_txfifoempty(FAR struct stm32_usbdev_s *priv, int e
|
||||
FAR struct stm32_ep_s *privep = &priv->epin[epno];
|
||||
|
||||
/* Continue processing the write request queue. This may mean sending
|
||||
* more dat from the exisiting request or terminating the current requests
|
||||
* more data from the exisiting request or terminating the current requests
|
||||
* and (perhaps) starting the IN transfer from the next write request.
|
||||
*/
|
||||
|
||||
@@ -2741,9 +2722,11 @@ static inline void stm32_epin_interrupt(FAR struct stm32_usbdev_s *priv)
|
||||
|
||||
mask = stm32_getreg(STM32_OTGFS_DIEPMSK);
|
||||
|
||||
/* Check for FIFO not empty. Bits n corresponds to endpoint n.
|
||||
* That condition corresponds to bit 7 of the DIEPINT interrupt
|
||||
* status register.
|
||||
/* Check if the TxFIFO not empty interrupt is enabled for this
|
||||
* endpoint in the DIEPMSK register. Bits n corresponds to
|
||||
* endpoint n in the register. That condition corresponds to
|
||||
* bit 7 of the DIEPINT interrupt status register. There is
|
||||
* no TXFE bit in the mask register, so we fake one here.
|
||||
*/
|
||||
|
||||
empty = stm32_getreg(STM32_OTGFS_DIEPEMPMSK);
|
||||
@@ -2763,11 +2746,13 @@ static inline void stm32_epin_interrupt(FAR struct stm32_usbdev_s *priv)
|
||||
|
||||
if ((diepint & OTGFS_DIEPINT_XFRC) != 0)
|
||||
{
|
||||
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_XFRC), (uint16_t)diepint);
|
||||
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_XFRC),
|
||||
(uint16_t)diepint);
|
||||
|
||||
/* It is possible that logic may be waiting for a the TxFIFO to become
|
||||
* empty. We disable the TxFIFO empty interrupt here; it will be
|
||||
* re-enabled if there is still insufficient space in the TxFIFO.
|
||||
/* It is possible that logic may be waiting for a the
|
||||
* TxFIFO to become empty. We disable the TxFIFO empty
|
||||
* interrupt here; it will be re-enabled if there is still
|
||||
* insufficient space in the TxFIFO.
|
||||
*/
|
||||
|
||||
empty &= ~OTGFS_DIEPEMPMSK(epno);
|
||||
@@ -2828,7 +2813,7 @@ static inline void stm32_epin_interrupt(FAR struct stm32_usbdev_s *priv)
|
||||
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_TXFE), (uint16_t)diepint);
|
||||
|
||||
/* If we were waiting for TxFIFO to become empty, the we might have both
|
||||
* XFRC and TXFE interrups pending. Since we do the same thing for both
|
||||
* XFRC and TXFE interrupts pending. Since we do the same thing for both
|
||||
* cases, ignore the TXFE if we have already processed the XFRC.
|
||||
*/
|
||||
|
||||
@@ -2886,6 +2871,13 @@ static inline void stm32_resumeinterrupt(FAR struct stm32_usbdev_s *priv)
|
||||
/* Restore full power -- whatever that means for this particular board */
|
||||
|
||||
stm32_usbsuspend((struct usbdev_s *)priv, true);
|
||||
|
||||
/* Notify the class driver of the resume event */
|
||||
|
||||
if (priv->driver)
|
||||
{
|
||||
CLASS_RESUME(priv->driver, &priv->usbdev);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -2900,7 +2892,16 @@ static inline void stm32_suspendinterrupt(FAR struct stm32_usbdev_s *priv)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_LOWPOWER
|
||||
uint32_t regval;
|
||||
#endif
|
||||
|
||||
/* Notify the class driver of the suspend event */
|
||||
|
||||
if (priv->driver)
|
||||
{
|
||||
CLASS_SUSPEND(priv->driver, &priv->usbdev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBDEV_LOWPOWER
|
||||
/* OTGFS_DSTS_SUSPSTS is set as long as the suspend condition is detected
|
||||
* on USB. Check if we are still have the suspend condition, that we are
|
||||
* connected to the host, and that we have been configured.
|
||||
@@ -2908,9 +2909,7 @@ static inline void stm32_suspendinterrupt(FAR struct stm32_usbdev_s *priv)
|
||||
|
||||
regval = stm32_getreg(STM32_OTGFS_DSTS);
|
||||
|
||||
if ((regval & OTGFS_DSTS_SUSPSTS) != 0 &&
|
||||
priv->connected &&
|
||||
devstate == DEVSTATE_CONFIGURED)
|
||||
if ((regval & OTGFS_DSTS_SUSPSTS) != 0 && devstate == DEVSTATE_CONFIGURED)
|
||||
{
|
||||
/* Switch off OTG FS clocking. Setting OTGFS_PCGCCTL_STPPCLK stops the
|
||||
* PHY clock.
|
||||
@@ -4957,8 +4956,9 @@ static void stm32_hwinitialize(FAR struct stm32_usbdev_s *priv)
|
||||
|
||||
/* At startup the core is in FS mode. */
|
||||
|
||||
/* Disable the USB global interrupt by clearing GINTMSK in the global OTG
|
||||
* FS AHB configuration register.
|
||||
/* Disable global interrupts by clearing the GINTMASK bit in the GAHBCFG
|
||||
* register; Set the TXFELVL bit in the GAHBCFG register so that TxFIFO
|
||||
* interrupts will occur when the TxFIFO is truly empty (not just half full).
|
||||
*/
|
||||
|
||||
stm32_putreg(OTGFS_GAHBCFG_TXFELVL, STM32_OTGFS_GAHBCFG);
|
||||
@@ -5074,6 +5074,7 @@ static void stm32_hwinitialize(FAR struct stm32_usbdev_s *priv)
|
||||
|
||||
stm32_putreg(0, STM32_OTGFS_DIEPMSK);
|
||||
stm32_putreg(0, STM32_OTGFS_DOEPMSK);
|
||||
stm32_putreg(0, STM32_OTGFS_DIEPEMPMSK);
|
||||
stm32_putreg(0xffffffff, STM32_OTGFS_DAINT);
|
||||
stm32_putreg(0, STM32_OTGFS_DAINTMSK);
|
||||
|
||||
@@ -5155,10 +5156,13 @@ static void stm32_hwinitialize(FAR struct stm32_usbdev_s *priv)
|
||||
stm32_putreg(regval, STM32_OTGFS_GINTMSK);
|
||||
|
||||
/* Enable the USB global interrupt by setting GINTMSK in the global OTG
|
||||
* FS AHB configuration register.
|
||||
* FS AHB configuration register; Set the TXFELVL bit in the GAHBCFG
|
||||
* register so that TxFIFO interrupts will occur when the TxFIFO is truly
|
||||
* empty (not just half full).
|
||||
*/
|
||||
|
||||
stm32_putreg(OTGFS_GAHBCFG_GINTMSK | OTGFS_GAHBCFG_TXFELVL, STM32_OTGFS_GAHBCFG);
|
||||
stm32_putreg(OTGFS_GAHBCFG_GINTMSK | OTGFS_GAHBCFG_TXFELVL,
|
||||
STM32_OTGFS_GAHBCFG);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -5314,6 +5318,7 @@ void up_usbuninitialize(void)
|
||||
|
||||
stm32_putreg(0, STM32_OTGFS_DIEPMSK);
|
||||
stm32_putreg(0, STM32_OTGFS_DOEPMSK);
|
||||
stm32_putreg(0, STM32_OTGFS_DIEPEMPMSK);
|
||||
stm32_putreg(0, STM32_OTGFS_DAINTMSK);
|
||||
stm32_putreg(0xffffffff, STM32_OTGFS_DAINT);
|
||||
|
||||
|
||||
@@ -2077,7 +2077,8 @@ void up_serialinit(void)
|
||||
{
|
||||
#ifdef HAVE_UART
|
||||
char devname[16];
|
||||
unsigned i, j;
|
||||
unsigned i;
|
||||
unsigned minor = 0;
|
||||
#ifdef CONFIG_PM
|
||||
int ret;
|
||||
#endif
|
||||
@@ -2094,6 +2095,7 @@ void up_serialinit(void)
|
||||
#if CONSOLE_UART > 0
|
||||
(void)uart_register("/dev/console", &uart_devs[CONSOLE_UART - 1]->dev);
|
||||
(void)uart_register("/dev/ttyS0", &uart_devs[CONSOLE_UART - 1]->dev);
|
||||
minor = 1;
|
||||
|
||||
/* If we need to re-initialise the console to enable DMA do that here. */
|
||||
|
||||
@@ -2107,19 +2109,19 @@ void up_serialinit(void)
|
||||
|
||||
strcpy(devname, "/dev/ttySx");
|
||||
|
||||
for (i = 0, j = 1; i < STM32_NUSART; i++)
|
||||
for (i = 0; i < STM32_NUSART; i++)
|
||||
{
|
||||
|
||||
/* don't create a device for the console - we did that above */
|
||||
/* Don't create a device for the console - we did that above */
|
||||
|
||||
if ((uart_devs[i] == 0) || (uart_devs[i]->dev.isconsole))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* register USARTs as devices in increasing order */
|
||||
/* Register USARTs as devices in increasing order */
|
||||
|
||||
devname[9] = '0' + j++;
|
||||
devname[9] = '0' + minor++;
|
||||
(void)uart_register(devname, &uart_devs[i]->dev);
|
||||
}
|
||||
#endif /* HAVE UART */
|
||||
|
||||
@@ -130,14 +130,28 @@
|
||||
|
||||
/* DMA channel configuration */
|
||||
|
||||
#define SPI_RXDMA16_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_16BITS|DMA_CCR_PSIZE_16BITS|DMA_CCR_MINC )
|
||||
#define SPI_RXDMA8_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS |DMA_CCR_MINC )
|
||||
#define SPI_RXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_16BITS )
|
||||
#define SPI_RXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS )
|
||||
#define SPI_TXDMA16_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_16BITS|DMA_CCR_PSIZE_16BITS|DMA_CCR_MINC|DMA_CCR_DIR)
|
||||
#define SPI_TXDMA8_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS |DMA_CCR_MINC|DMA_CCR_DIR)
|
||||
#define SPI_TXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_16BITS |DMA_CCR_DIR)
|
||||
#define SPI_TXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS |DMA_CCR_DIR)
|
||||
#if defined(CONFIG_STM32_STM32F10XX)
|
||||
# define SPI_RXDMA16_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_16BITS|DMA_CCR_PSIZE_16BITS|DMA_CCR_MINC )
|
||||
# define SPI_RXDMA8_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS |DMA_CCR_MINC )
|
||||
# define SPI_RXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_16BITS )
|
||||
# define SPI_RXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS )
|
||||
# define SPI_TXDMA16_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_16BITS|DMA_CCR_PSIZE_16BITS|DMA_CCR_MINC|DMA_CCR_DIR)
|
||||
# define SPI_TXDMA8_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS |DMA_CCR_MINC|DMA_CCR_DIR)
|
||||
# define SPI_TXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_16BITS |DMA_CCR_DIR)
|
||||
# define SPI_TXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_CCR_MSIZE_8BITS |DMA_CCR_PSIZE_8BITS |DMA_CCR_DIR)
|
||||
#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
|
||||
# define SPI_RXDMA16_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_16BITS|DMA_SCR_PSIZE_16BITS|DMA_SCR_MINC|DMA_SCR_DIR_P2M)
|
||||
# define SPI_RXDMA8_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_8BITS |DMA_SCR_MINC|DMA_SCR_DIR_P2M)
|
||||
# define SPI_RXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_16BITS |DMA_SCR_DIR_P2M)
|
||||
# define SPI_RXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_8BITS |DMA_SCR_DIR_P2M)
|
||||
# define SPI_TXDMA16_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_16BITS|DMA_SCR_PSIZE_16BITS|DMA_SCR_MINC|DMA_SCR_DIR_M2P)
|
||||
# define SPI_TXDMA8_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_8BITS |DMA_SCR_MINC|DMA_SCR_DIR_M2P)
|
||||
# define SPI_TXDMA16NULL_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_16BITS |DMA_SCR_DIR_M2P)
|
||||
# define SPI_TXDMA8NULL_CONFIG (SPI_DMA_PRIO|DMA_SCR_MSIZE_8BITS |DMA_SCR_PSIZE_8BITS |DMA_SCR_DIR_M2P)
|
||||
#else
|
||||
# error "Unknown STM32 DMA"
|
||||
#endif
|
||||
|
||||
|
||||
/* Debug ****************************************************************************/
|
||||
/* Check if (non-standard) SPI debug is enabled */
|
||||
@@ -549,6 +563,21 @@ static inline void spi_dmarxwakeup(FAR struct stm32_spidev_s *priv)
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: spi_dmatxwakeup
|
||||
*
|
||||
* Description:
|
||||
* Signal that DMA is complete
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32_SPI_DMA
|
||||
static inline void spi_dmatxwakeup(FAR struct stm32_spidev_s *priv)
|
||||
{
|
||||
(void)sem_post(&priv->txsem);
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: spi_dmarxcallback
|
||||
*
|
||||
@@ -1183,8 +1212,8 @@ static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords)
|
||||
{
|
||||
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
|
||||
uint16_t rxdummy = 0xffff;
|
||||
uint16_t txdummy;
|
||||
static uint16_t rxdummy = 0xffff;
|
||||
static const uint16_t txdummy = 0xffff;
|
||||
|
||||
spivdbg("txbuffer=%p rxbuffer=%p nwords=%d\n", txbuffer, rxbuffer, nwords);
|
||||
DEBUGASSERT(priv && priv->spibase);
|
||||
@@ -1330,6 +1359,8 @@ static void spi_portinitialize(FAR struct stm32_spidev_s *priv)
|
||||
priv->rxdma = stm32_dmachannel(priv->rxch);
|
||||
priv->txdma = stm32_dmachannel(priv->txch);
|
||||
DEBUGASSERT(priv->rxdma && priv->txdma);
|
||||
|
||||
spi_putreg(priv, STM32_SPI_CR2_OFFSET, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN);
|
||||
#endif
|
||||
|
||||
/* Enable spi */
|
||||
|
||||
@@ -2346,6 +2346,13 @@ static void stm32_suspend(struct stm32_usbdev_s *priv)
|
||||
{
|
||||
uint16_t regval;
|
||||
|
||||
/* Notify the class driver of the suspend event */
|
||||
|
||||
if (priv->driver)
|
||||
{
|
||||
CLASS_SUSPEND(priv->driver, &priv->usbdev);
|
||||
}
|
||||
|
||||
/* Disable ESOF polling, disable the SUSP interrupt, and enable the WKUP
|
||||
* interrupt. Clear any pending WKUP interrupt.
|
||||
*/
|
||||
@@ -2411,6 +2418,13 @@ static void stm32_initresume(struct stm32_usbdev_s *priv)
|
||||
/* Reset FSUSP bit and enable normal interrupt handling */
|
||||
|
||||
stm32_putreg(STM32_CNTR_SETUP, STM32_USB_CNTR);
|
||||
|
||||
/* Notify the class driver of the resume event */
|
||||
|
||||
if (priv->driver)
|
||||
{
|
||||
CLASS_RESUME(priv->driver, &priv->usbdev);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -72,9 +72,10 @@ config PIC
|
||||
config BINFMT_CONSTRUCTORS
|
||||
bool "C++ Static Constructor Support"
|
||||
default n
|
||||
depends on HAVE_CXX && ELF # FIX ME: Currently only supported for ELF
|
||||
depends on HAVE_CXX && SCHED_STARTHOOK && ELF
|
||||
---help---
|
||||
Build in support for C++ constructors in loaded modules.
|
||||
Build in support for C++ constructors in loaded modules. Currently
|
||||
only support for ELF binary formats.
|
||||
|
||||
config SYMTAB_ORDEREDBYNAME
|
||||
bool "Symbol Tables Ordered by Name"
|
||||
|
||||
@@ -58,6 +58,14 @@
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* If C++ constructors are used, then CONFIG_SCHED_STARTHOOK must also be
|
||||
* selected be the start hook is used to schedule execution of the
|
||||
* constructors.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_BINFMT_CONSTRUCTORS) && !defined(CONFIG_SCHED_STARTHOOK)
|
||||
# errror "CONFIG_SCHED_STARTHOOK must be defined to use constructors"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
@@ -75,7 +83,9 @@
|
||||
* Name: exec_ctors
|
||||
*
|
||||
* Description:
|
||||
* Execute C++ static constructors.
|
||||
* Execute C++ static constructors. This function is registered as a
|
||||
* start hook and runs on the thread of the newly created task before
|
||||
* the new task's main function is called.
|
||||
*
|
||||
* Input Parameters:
|
||||
* loadinfo - Load state information
|
||||
@@ -87,26 +97,12 @@
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_BINFMT_CONSTRUCTORS
|
||||
static inline int exec_ctors(FAR const struct binary_s *binp)
|
||||
static void exec_ctors(FAR void *arg)
|
||||
{
|
||||
FAR const struct binary_s *binp = (FAR const struct binary_s *)arg;
|
||||
binfmt_ctor_t *ctor = binp->ctors;
|
||||
#ifdef CONFIG_ADDRENV
|
||||
hw_addrenv_t oldenv;
|
||||
int ret;
|
||||
#endif
|
||||
int i;
|
||||
|
||||
/* Instantiate the address enviroment containing the constructors */
|
||||
|
||||
#ifdef CONFIG_ADDRENV
|
||||
ret = up_addrenv_select(binp->addrenv, &oldenv);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("up_addrenv_select() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Execute each constructor */
|
||||
|
||||
for (i = 0; i < binp->nctors; i++)
|
||||
@@ -116,14 +112,6 @@ static inline int exec_ctors(FAR const struct binary_s *binp)
|
||||
(*ctor)();
|
||||
ctor++;
|
||||
}
|
||||
|
||||
/* Restore the address enviroment */
|
||||
|
||||
#ifdef CONFIG_ADDRENV
|
||||
return up_addrenv_restore(oldenv);
|
||||
#else
|
||||
return OK;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -139,7 +127,7 @@ static inline int exec_ctors(FAR const struct binary_s *binp)
|
||||
*
|
||||
* Returned Value:
|
||||
* This is an end-user function, so it follows the normal convention:
|
||||
* Returns the PID of the exec'ed module. On failure, it.returns
|
||||
* Returns the PID of the exec'ed module. On failure, it returns
|
||||
* -1 (ERROR) and sets errno appropriately.
|
||||
*
|
||||
****************************************************************************/
|
||||
@@ -229,22 +217,19 @@ int exec_module(FAR const struct binary_s *binp)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Setup a start hook that will execute all of the C++ static constructors
|
||||
* on the newly created thread. The struct binary_s must persist at least
|
||||
* until the new task has been started.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_BINFMT_CONSTRUCTORS
|
||||
task_starthook(tcb, exec_ctors, (FAR void *)binp);
|
||||
#endif
|
||||
|
||||
/* Get the assigned pid before we start the task */
|
||||
|
||||
pid = tcb->pid;
|
||||
|
||||
/* Execute all of the C++ static constructors */
|
||||
|
||||
#ifdef CONFIG_BINFMT_CONSTRUCTORS
|
||||
ret = exec_ctors(binp);
|
||||
if (ret < 0)
|
||||
{
|
||||
err = -ret;
|
||||
bdbg("exec_ctors() failed: %d\n", ret);
|
||||
goto errout_with_stack;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Then activate the task at the provided priority */
|
||||
|
||||
ret = task_activate(tcb);
|
||||
|
||||
@@ -71,7 +71,7 @@ EXTERN FAR struct binfmt_s *g_binfmts;
|
||||
* Public Function Prototypes
|
||||
***********************************************************************/
|
||||
|
||||
/* Dump the contents of strtuc binary_s */
|
||||
/* Dump the contents of struct binary_s */
|
||||
|
||||
#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_BINFMT)
|
||||
EXTERN int dump_module(FAR const struct binary_s *bin);
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#undef ELF_DUMP_READDATA /* Define to dump all file data read */
|
||||
#define DUMPER lib_rawprintf /* If ELF_DUMP_READDATA is defined, this
|
||||
#define DUMPER syslog /* If ELF_DUMP_READDATA is defined, this
|
||||
* is the API used to dump data */
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#undef NXFLAT_DUMP_READDATA /* Define to dump all file data read */
|
||||
#define DUMPER lib_rawprintf /* If NXFLAT_DUMP_READDATA is defined, this
|
||||
#define DUMPER syslog /* If NXFLAT_DUMP_READDATA is defined, this
|
||||
* is the API used to dump data */
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -261,7 +261,7 @@ defconfig -- This is a configuration file similar to the Linux
|
||||
|
||||
CONFIG_DEBUG - enables built-in debug options
|
||||
CONFIG_DEBUG_VERBOSE - enables verbose debug output
|
||||
CCONFIG_DEBUG_ENABLE - Support an interface to enable or disable debug output.
|
||||
CCONFIG_SYSLOG_ENABLE - Support an interface to enable or disable debug output.
|
||||
CONFIG_DEBUG_SYMBOLS - build without optimization and with
|
||||
debug symbols (needed for use with a debugger).
|
||||
CONFIG_DEBUG_SCHED - enable OS debug output (disabled by
|
||||
|
||||
@@ -246,6 +246,7 @@ CONFIG_AT24XX_MTD_BLOCKSIZE=256
|
||||
#
|
||||
CONFIG_SERIAL_TERMIOS=y
|
||||
CONFIG_SERIAL_CONSOLE_REINIT=y
|
||||
CONFIG_STANDARD_SERIAL=y
|
||||
|
||||
CONFIG_USART1_SERIAL_CONSOLE=y
|
||||
CONFIG_USART2_SERIAL_CONSOLE=n
|
||||
|
||||
@@ -159,6 +159,7 @@ CONFIG_STM32_ADC3=n
|
||||
# CONFIG_USARTn_2STOP - Two stop bits
|
||||
#
|
||||
CONFIG_SERIAL_TERMIOS=y
|
||||
CONFIG_STANDARD_SERIAL=y
|
||||
|
||||
CONFIG_USART1_SERIAL_CONSOLE=y
|
||||
CONFIG_USART2_SERIAL_CONSOLE=n
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
# see misc/tools/kconfig-language.txt.
|
||||
#
|
||||
|
||||
config DISABLE_POLL
|
||||
bool "Disable driver poll interfaces"
|
||||
default n
|
||||
---help---
|
||||
The sizes of drivers can be reduced if the poll() method is not
|
||||
supported. If you do not use poll() or select(), then you can
|
||||
select DISABLE_POLL to reduce the code footprint by a small amount.
|
||||
|
||||
config DEV_NULL
|
||||
bool "Enable /dev/null"
|
||||
default y
|
||||
|
||||
@@ -495,14 +495,14 @@ static void mio283qt2_dumprun(FAR const char *msg, FAR uint16_t *run, size_t npi
|
||||
{
|
||||
int i, j;
|
||||
|
||||
lib_rawprintf("\n%s:\n", msg);
|
||||
syslog("\n%s:\n", msg);
|
||||
for (i = 0; i < npixels; i += 16)
|
||||
{
|
||||
up_putc(' ');
|
||||
lib_rawprintf(" ");
|
||||
syslog(" ");
|
||||
for (j = 0; j < 16; j++)
|
||||
{
|
||||
lib_rawprintf(" %04x", *run++);
|
||||
syslog(" %04x", *run++);
|
||||
}
|
||||
up_putc('\n');
|
||||
}
|
||||
|
||||
@@ -497,14 +497,14 @@ static void ssd1289_dumprun(FAR const char *msg, FAR uint16_t *run, size_t npixe
|
||||
{
|
||||
int i, j;
|
||||
|
||||
lib_rawprintf("\n%s:\n", msg);
|
||||
syslog("\n%s:\n", msg);
|
||||
for (i = 0; i < npixels; i += 16)
|
||||
{
|
||||
up_putc(' ');
|
||||
lib_rawprintf(" ");
|
||||
syslog(" ");
|
||||
for (j = 0; j < 16; j++)
|
||||
{
|
||||
lib_rawprintf(" %04x", *run++);
|
||||
syslog(" %04x", *run++);
|
||||
}
|
||||
up_putc('\n');
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@ static ssize_t loop_write(FAR struct inode *inode, const unsigned char *buffer,
|
||||
size_t start_sector, unsigned int nsectors)
|
||||
{
|
||||
FAR struct loop_struct_s *dev;
|
||||
size_t nbyteswritten;
|
||||
ssize_t nbyteswritten;
|
||||
off_t offset;
|
||||
int ret;
|
||||
|
||||
|
||||
@@ -56,9 +56,9 @@
|
||||
/* This needs to match the logic in include/debug.h */
|
||||
|
||||
#ifdef CONFIG_CPP_HAVE_VARARGS
|
||||
# define message(format, arg...) lib_rawprintf(format, ##arg)
|
||||
# define message(format, arg...) syslog(format, ##arg)
|
||||
#else
|
||||
# define message lib_rawprintf
|
||||
# define message syslog
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* drivers/mmcsd/mmcsd_spi.c
|
||||
*
|
||||
* Copyright (C) 2008-2010, 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2008-2010, 2011-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -409,10 +409,14 @@ static uint32_t mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot,
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* Wait until the card is not busy */
|
||||
/* Wait until the card is not busy. Some SD cards will not enter the IDLE
|
||||
* state until CMD0 is sent for the first time, switching the card to SPI
|
||||
* mode. Having a pull-up resistor on MISO may avoid this problem, but
|
||||
* this check makes it work also without the pull-up.
|
||||
*/
|
||||
|
||||
ret = mmcsd_waitready(slot);
|
||||
if (ret != OK)
|
||||
if (ret != OK && cmd != &g_cmd0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -691,14 +691,16 @@ FAR struct mtd_dev_s *at25_initialize(FAR struct spi_dev_s *dev)
|
||||
kfree(priv);
|
||||
priv = NULL;
|
||||
}
|
||||
|
||||
/* Unprotect all sectors */
|
||||
else
|
||||
{
|
||||
/* Unprotect all sectors */
|
||||
|
||||
at25_writeenable(priv);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
|
||||
(void)SPI_SEND(priv->dev, AT25_WRSR);
|
||||
(void)SPI_SEND(priv->dev, AT25_SR_UNPROT);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
|
||||
at25_writeenable(priv);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
|
||||
(void)SPI_SEND(priv->dev, AT25_WRSR);
|
||||
(void)SPI_SEND(priv->dev, AT25_SR_UNPROT);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the implementation-specific state structure as the MTD device */
|
||||
|
||||
@@ -179,10 +179,10 @@
|
||||
/* Debug ********************************************************************/
|
||||
|
||||
#ifdef CONFIG_ENC28J60_REGDEBUG
|
||||
# define enc_wrdump(a,v) lib_lowprintf("ENC28J60: %02x<-%02x\n", a, v);
|
||||
# define enc_rddump(a,v) lib_lowprintf("ENC28J60: %02x->%02x\n", a, v);
|
||||
# define enc_cmddump(c) lib_lowprintf("ENC28J60: CMD: %02x\n", c);
|
||||
# define enc_bmdump(c,b,s) lib_lowprintf("ENC28J60: CMD: %02x buffer: %p length: %d\n", c,b,s);
|
||||
# define enc_wrdump(a,v) lowsyslog("ENC28J60: %02x<-%02x\n", a, v);
|
||||
# define enc_rddump(a,v) lowsyslog("ENC28J60: %02x->%02x\n", a, v);
|
||||
# define enc_cmddump(c) lowsyslog("ENC28J60: CMD: %02x\n", c);
|
||||
# define enc_bmdump(c,b,s) lowsyslog("ENC28J60: CMD: %02x buffer: %p length: %d\n", c,b,s);
|
||||
#else
|
||||
# define enc_wrdump(a,v)
|
||||
# define enc_rddump(a,v)
|
||||
@@ -773,56 +773,56 @@ static int enc_waitbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg,
|
||||
#if 0 /* Sometimes useful */
|
||||
static void enc_rxdump(FAR struct enc_driver_s *priv)
|
||||
{
|
||||
lib_lowprintf("Rx Registers:\n");
|
||||
lib_lowprintf(" EIE: %02x EIR: %02x\n",
|
||||
enc_rdgreg(priv, ENC_EIE), enc_rdgreg(priv, ENC_EIR));
|
||||
lib_lowprintf(" ESTAT: %02x ECON1: %02x ECON2: %02x\n",
|
||||
enc_rdgreg(priv, ENC_ESTAT), enc_rdgreg(priv, ENC_ECON1),
|
||||
enc_rdgreg(priv, ENC_ECON2));
|
||||
lib_lowprintf(" ERXST: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ERXSTH), enc_rdbreg(priv, ENC_ERXSTL));
|
||||
lib_lowprintf(" ERXND: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ERXNDH), enc_rdbreg(priv, ENC_ERXNDL));
|
||||
lib_lowprintf(" ERXRDPT: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ERXRDPTH), enc_rdbreg(priv, ENC_ERXRDPTL));
|
||||
lib_lowprintf(" ERXFCON: %02x EPKTCNT: %02x\n",
|
||||
enc_rdbreg(priv, ENC_ERXFCON), enc_rdbreg(priv, ENC_EPKTCNT));
|
||||
lib_lowprintf(" MACON1: %02x MACON3: %02x\n",
|
||||
enc_rdbreg(priv, ENC_MACON1), enc_rdbreg(priv, ENC_MACON3));
|
||||
lib_lowprintf(" MAMXFL: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_MAMXFLH), enc_rdbreg(priv, ENC_MAMXFLL));
|
||||
lib_lowprintf(" MAADR: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
enc_rdbreg(priv, ENC_MAADR1), enc_rdbreg(priv, ENC_MAADR2),
|
||||
enc_rdbreg(priv, ENC_MAADR3), enc_rdbreg(priv, ENC_MAADR4),
|
||||
enc_rdbreg(priv, ENC_MAADR5), enc_rdbreg(priv, ENC_MAADR6));
|
||||
lowsyslog("Rx Registers:\n");
|
||||
lowsyslog(" EIE: %02x EIR: %02x\n",
|
||||
enc_rdgreg(priv, ENC_EIE), enc_rdgreg(priv, ENC_EIR));
|
||||
lowsyslog(" ESTAT: %02x ECON1: %02x ECON2: %02x\n",
|
||||
enc_rdgreg(priv, ENC_ESTAT), enc_rdgreg(priv, ENC_ECON1),
|
||||
enc_rdgreg(priv, ENC_ECON2));
|
||||
lowsyslog(" ERXST: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ERXSTH), enc_rdbreg(priv, ENC_ERXSTL));
|
||||
lowsyslog(" ERXND: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ERXNDH), enc_rdbreg(priv, ENC_ERXNDL));
|
||||
lowsyslog(" ERXRDPT: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ERXRDPTH), enc_rdbreg(priv, ENC_ERXRDPTL));
|
||||
lowsyslog(" ERXFCON: %02x EPKTCNT: %02x\n",
|
||||
enc_rdbreg(priv, ENC_ERXFCON), enc_rdbreg(priv, ENC_EPKTCNT));
|
||||
lowsyslog(" MACON1: %02x MACON3: %02x\n",
|
||||
enc_rdbreg(priv, ENC_MACON1), enc_rdbreg(priv, ENC_MACON3));
|
||||
lowsyslog(" MAMXFL: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_MAMXFLH), enc_rdbreg(priv, ENC_MAMXFLL));
|
||||
lowsyslog(" MAADR: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
enc_rdbreg(priv, ENC_MAADR1), enc_rdbreg(priv, ENC_MAADR2),
|
||||
enc_rdbreg(priv, ENC_MAADR3), enc_rdbreg(priv, ENC_MAADR4),
|
||||
enc_rdbreg(priv, ENC_MAADR5), enc_rdbreg(priv, ENC_MAADR6));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0 /* Sometimes useful */
|
||||
static void enc_txdump(FAR struct enc_driver_s *priv)
|
||||
{
|
||||
lib_lowprintf("Tx Registers:\n");
|
||||
lib_lowprintf(" EIE: %02x EIR: %02x ESTAT: %02x\n",
|
||||
enc_rdgreg(priv, ENC_EIE), enc_rdgreg(priv, ENC_EIR),);
|
||||
lib_lowprintf(" ESTAT: %02x ECON1: %02x\n",
|
||||
enc_rdgreg(priv, ENC_ESTAT), enc_rdgreg(priv, ENC_ECON1));
|
||||
lib_lowprintf(" ETXST: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ETXSTH), enc_rdbreg(priv, ENC_ETXSTL));
|
||||
lib_lowprintf(" ETXND: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ETXNDH), enc_rdbreg(priv, ENC_ETXNDL));
|
||||
lib_lowprintf(" MACON1: %02x MACON3: %02x MACON4: %02x\n",
|
||||
enc_rdbreg(priv, ENC_MACON1), enc_rdbreg(priv, ENC_MACON3),
|
||||
enc_rdbreg(priv, ENC_MACON4));
|
||||
lib_lowprintf(" MACON1: %02x MACON3: %02x MACON4: %02x\n",
|
||||
enc_rdbreg(priv, ENC_MACON1), enc_rdbreg(priv, ENC_MACON3),
|
||||
enc_rdbreg(priv, ENC_MACON4));
|
||||
lib_lowprintf(" MABBIPG: %02x MAIPG %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_MABBIPG), enc_rdbreg(priv, ENC_MAIPGH),
|
||||
enc_rdbreg(priv, ENC_MAIPGL));
|
||||
lib_lowprintf(" MACLCON1: %02x MACLCON2: %02x\n",
|
||||
enc_rdbreg(priv, ENC_MACLCON1), enc_rdbreg(priv, ENC_MACLCON2));
|
||||
lib_lowprintf(" MAMXFL: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_MAMXFLH), enc_rdbreg(priv, ENC_MAMXFLL));
|
||||
lowsyslog("Tx Registers:\n");
|
||||
lowsyslog(" EIE: %02x EIR: %02x ESTAT: %02x\n",
|
||||
enc_rdgreg(priv, ENC_EIE), enc_rdgreg(priv, ENC_EIR),);
|
||||
lowsyslog(" ESTAT: %02x ECON1: %02x\n",
|
||||
enc_rdgreg(priv, ENC_ESTAT), enc_rdgreg(priv, ENC_ECON1));
|
||||
lowsyslog(" ETXST: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ETXSTH), enc_rdbreg(priv, ENC_ETXSTL));
|
||||
lowsyslog(" ETXND: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_ETXNDH), enc_rdbreg(priv, ENC_ETXNDL));
|
||||
lowsyslog(" MACON1: %02x MACON3: %02x MACON4: %02x\n",
|
||||
enc_rdbreg(priv, ENC_MACON1), enc_rdbreg(priv, ENC_MACON3),
|
||||
enc_rdbreg(priv, ENC_MACON4));
|
||||
lowsyslog(" MACON1: %02x MACON3: %02x MACON4: %02x\n",
|
||||
enc_rdbreg(priv, ENC_MACON1), enc_rdbreg(priv, ENC_MACON3),
|
||||
enc_rdbreg(priv, ENC_MACON4));
|
||||
lowsyslog(" MABBIPG: %02x MAIPG %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_MABBIPG), enc_rdbreg(priv, ENC_MAIPGH),
|
||||
enc_rdbreg(priv, ENC_MAIPGL));
|
||||
lowsyslog(" MACLCON1: %02x MACLCON2: %02x\n",
|
||||
enc_rdbreg(priv, ENC_MACLCON1), enc_rdbreg(priv, ENC_MACLCON2));
|
||||
lowsyslog(" MAMXFL: %02x %02x\n",
|
||||
enc_rdbreg(priv, ENC_MAMXFLH), enc_rdbreg(priv, ENC_MAMXFLL));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -10,6 +10,9 @@ config DEV_LOWCONSOLE
|
||||
---help---
|
||||
Use the simple, low-level, write-only serial console driver (minimal support)
|
||||
|
||||
config SERIAL_REMOVABLE
|
||||
bool
|
||||
|
||||
config 16550_UART
|
||||
bool "16550 UART Chip support"
|
||||
default n
|
||||
|
||||
+206
-15
@@ -1,7 +1,7 @@
|
||||
/************************************************************************************
|
||||
* drivers/serial/serial.c
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -158,7 +158,11 @@ static void uart_pollnotify(FAR uart_dev_t *dev, pollevent_t eventset)
|
||||
struct pollfd *fds = dev->fds[i];
|
||||
if (fds)
|
||||
{
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
fds->revents |= ((fds->events | (POLLERR|POLLHUP)) & eventset);
|
||||
#else
|
||||
fds->revents |= (fds->events & eventset);
|
||||
#endif
|
||||
if (fds->revents != 0)
|
||||
{
|
||||
fvdbg("Report events: %02x\n", fds->revents);
|
||||
@@ -208,18 +212,40 @@ static int uart_putxmitchar(FAR uart_dev_t *dev, int ch)
|
||||
*/
|
||||
|
||||
flags = irqsave();
|
||||
dev->xmitwaiting = true;
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
/* Check if the removable device is no longer connected while we
|
||||
* have interrupts off. We do not want the transition to occur
|
||||
* as a race condition before we begin the wait.
|
||||
*/
|
||||
|
||||
if (dev->disconnected)
|
||||
{
|
||||
irqrestore(flags);
|
||||
return -ENOTCONN;
|
||||
}
|
||||
#endif
|
||||
/* Wait for some characters to be sent from the buffer with the TX
|
||||
* interrupt enabled. When the TX interrupt is enabled, uart_xmitchars
|
||||
* should execute and remove some of the data from the TX buffer.
|
||||
*/
|
||||
|
||||
dev->xmitwaiting = true;
|
||||
uart_enabletxint(dev);
|
||||
ret = uart_takesem(&dev->xmitsem, true);
|
||||
uart_disabletxint(dev);
|
||||
irqrestore(flags);
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
/* Check if the removable device was disconnected while we were
|
||||
* waiting.
|
||||
*/
|
||||
|
||||
if (dev->disconnected)
|
||||
{
|
||||
return -ENOTCONN;
|
||||
}
|
||||
#endif
|
||||
/* Check if we were awakened by signal. */
|
||||
|
||||
if (ret < 0)
|
||||
@@ -288,6 +314,17 @@ static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, size_t
|
||||
|
||||
if (up_interrupt_context() || getpid() == 0)
|
||||
{
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
/* If the removable device is no longer connected, refuse to write to
|
||||
* the device.
|
||||
*/
|
||||
|
||||
if (dev->disconnected)
|
||||
{
|
||||
return -ENOTCONN;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* up_putc() will be used to generate the output in a busy-wait loop.
|
||||
* up_putc() is only available for the console device.
|
||||
*/
|
||||
@@ -317,6 +354,20 @@ static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, size_t
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
/* If the removable device is no longer connected, refuse to write to the
|
||||
* device. This check occurs after taking the xmit.sem because the
|
||||
* disconnection event might have occurred while we were waiting for
|
||||
* access to the transmit buffers.
|
||||
*/
|
||||
|
||||
if (dev->disconnected)
|
||||
{
|
||||
uart_givesem(&dev->xmit.sem);
|
||||
return -ENOTCONN;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Loop while we still have data to copy to the transmit buffer.
|
||||
* we add data to the head of the buffer; uart_xmitchars takes the
|
||||
* data from the end of the buffer.
|
||||
@@ -392,9 +443,13 @@ static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, size_t
|
||||
|
||||
uart_givesem(&dev->xmit.sem);
|
||||
|
||||
/* Were we interrupted by a signal? That should be the only condition that
|
||||
* uart_putxmitchar() should return an error.
|
||||
*/
|
||||
/* uart_putxmitchar() might return an error under one of two
|
||||
* conditions: (1) The wait for buffer space might have been
|
||||
* interrupted by a signal (ret should be -EINTR), or (2) if
|
||||
* CONFIG_SERIAL_REMOVABLE is defined, then uart_putxmitchar()
|
||||
* might also return if the serial device was disconnected
|
||||
* (wtih -ENOTCONN).
|
||||
*/
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
@@ -413,11 +468,11 @@ static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, size_t
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No data was transferred. Return -EINTR. The VFS layer will
|
||||
* set the errno value appropriately).
|
||||
/* No data was transferred. Return the negated error. The VFS layer
|
||||
* will set the errno value appropriately).
|
||||
*/
|
||||
|
||||
nread = -EINTR;
|
||||
nread = -ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -458,6 +513,22 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
|
||||
|
||||
while (recvd < buflen)
|
||||
{
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
/* If the removable device is no longer connected, refuse to read any
|
||||
* further from the device.
|
||||
*/
|
||||
|
||||
if (dev->disconnected)
|
||||
{
|
||||
if (recvd == 0)
|
||||
{
|
||||
recvd = -ENOTCONN;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check if there is more data to return in the circular buffer.
|
||||
* NOTE: Rx interrupt handling logic may aynchronously increment
|
||||
* the head index but must not modify the tail index. The tail
|
||||
@@ -548,6 +619,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
|
||||
{
|
||||
recvd = -EAGAIN;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
#else
|
||||
@@ -599,20 +671,41 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
|
||||
*/
|
||||
|
||||
flags = irqsave();
|
||||
dev->recvwaiting = true;
|
||||
uart_enablerxint(dev);
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
/* Check if the removable device is no longer connected while
|
||||
* we have interrupts off. We do not want the transition to
|
||||
* occur as a race condition before we begin the wait.
|
||||
*/
|
||||
|
||||
if (dev->disconnected)
|
||||
{
|
||||
uart_enablerxint(dev);
|
||||
irqrestore(flags);
|
||||
ret = -ENOTCONN;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/* Now wait with the Rx interrupt re-enabled. NuttX will
|
||||
* automatically re-enable global interrupts when this thread
|
||||
* goes to sleep.
|
||||
*/
|
||||
|
||||
dev->recvwaiting = true;
|
||||
uart_enablerxint(dev);
|
||||
ret = uart_takesem(&dev->recvsem, true);
|
||||
irqrestore(flags);
|
||||
|
||||
/* Was a signal received while waiting for data to be received? */
|
||||
/* Was a signal received while waiting for data to be
|
||||
* received? Was a removable device disconnected while
|
||||
* we were waiting?
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
if (ret < 0 || dev->disconnected)
|
||||
#else
|
||||
if (ret < 0)
|
||||
#endif
|
||||
{
|
||||
/* POSIX requires that we return after a signal is received.
|
||||
* If some bytes were read, we need to return the number of bytes
|
||||
@@ -626,7 +719,11 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen
|
||||
* set the errno value appropriately.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
recvd = dev->disconnected ? -ENOTCONN : -EINTR;
|
||||
#else
|
||||
recvd = -EINTR;
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -852,12 +949,12 @@ int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup)
|
||||
|
||||
if (ndx != dev->xmit.tail)
|
||||
{
|
||||
eventset |= POLLOUT;
|
||||
eventset |= (fds->events & POLLOUT);
|
||||
}
|
||||
|
||||
uart_givesem(&dev->xmit.sem);
|
||||
|
||||
/* Check if the receive buffer is empty
|
||||
/* Check if the receive buffer is empty.
|
||||
*
|
||||
* Get exclusive access to the recv buffer indices. NOTE: that we do not
|
||||
* let this wait be interrupted by a signal (we probably should, but that
|
||||
@@ -867,11 +964,20 @@ int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup)
|
||||
(void)uart_takesem(&dev->recv.sem, false);
|
||||
if (dev->recv.head != dev->recv.tail)
|
||||
{
|
||||
eventset |= POLLIN;
|
||||
eventset |= (fds->events & POLLIN);
|
||||
}
|
||||
|
||||
uart_givesem(&dev->recv.sem);
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
/* Check if a removable device has been disconnected. */
|
||||
|
||||
if (dev->disconnected)
|
||||
{
|
||||
eventset |= (POLLERR|POLLHUP);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (eventset)
|
||||
{
|
||||
uart_pollnotify(dev, eventset);
|
||||
@@ -971,6 +1077,7 @@ static int uart_close(FAR struct file *filep)
|
||||
{
|
||||
uart_shutdown(dev); /* Disable the UART */
|
||||
}
|
||||
|
||||
irqrestore(flags);
|
||||
|
||||
uart_givesem(&dev->closesem);
|
||||
@@ -1004,6 +1111,19 @@ static int uart_open(FAR struct file *filep)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
/* If the removable device is no longer connected, refuse to open the
|
||||
* device. We check this after obtaining the close semaphore because
|
||||
* we might have been waiting when the device was disconnected.
|
||||
*/
|
||||
|
||||
if (dev->disconnected)
|
||||
{
|
||||
ret = -ENOTCONN;
|
||||
goto errout_with_sem;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Start up serial port */
|
||||
/* Increment the count of references to the device. */
|
||||
|
||||
@@ -1145,10 +1265,12 @@ int uart_register(FAR const char *path, FAR uart_dev_t *dev)
|
||||
|
||||
void uart_datareceived(FAR uart_dev_t *dev)
|
||||
{
|
||||
/* Awaken any awaiting read() operations */
|
||||
/* Is there a thread waiting for read data? */
|
||||
|
||||
if (dev->recvwaiting)
|
||||
{
|
||||
/* Yes... wake it up */
|
||||
|
||||
dev->recvwaiting = false;
|
||||
(void)sem_post(&dev->recvsem);
|
||||
}
|
||||
@@ -1172,8 +1294,12 @@ void uart_datareceived(FAR uart_dev_t *dev)
|
||||
|
||||
void uart_datasent(FAR uart_dev_t *dev)
|
||||
{
|
||||
/* Is there a thread waiting for space in xmit.buffer? */
|
||||
|
||||
if (dev->xmitwaiting)
|
||||
{
|
||||
/* Yes... wake it up */
|
||||
|
||||
dev->xmitwaiting = false;
|
||||
(void)sem_post(&dev->xmitsem);
|
||||
}
|
||||
@@ -1183,4 +1309,69 @@ void uart_datasent(FAR uart_dev_t *dev)
|
||||
uart_pollnotify(dev, POLLOUT);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: uart_connected
|
||||
*
|
||||
* Description:
|
||||
* Serial devices (like USB serial) can be removed. In that case, the "upper
|
||||
* half" serial driver must be informed that there is no longer a valid serial
|
||||
* channel associated with the driver.
|
||||
*
|
||||
* In this case, the driver will terminate all pending transfers wint ENOTCONN and
|
||||
* will refuse all further transactions while the "lower half" is disconnected.
|
||||
* The driver will continue to be registered, but will be in an unusable state.
|
||||
*
|
||||
* Conversely, the "upper half" serial driver needs to know when the serial
|
||||
* device is reconnected so that it can resume normal operations.
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* This function may be called from an interrupt handler.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
void uart_connected(FAR uart_dev_t *dev, bool connected)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
/* Is the device disconnected? */
|
||||
|
||||
flags = irqsave();
|
||||
dev->disconnected = !connected;
|
||||
if (!connected)
|
||||
{
|
||||
/* Yes.. wake up all waiting threads. Each thread should detect the
|
||||
* disconnection and return the ENOTCONN error.
|
||||
*/
|
||||
|
||||
/* Is there a thread waiting for space in xmit.buffer? */
|
||||
|
||||
if (dev->xmitwaiting)
|
||||
{
|
||||
/* Yes... wake it up */
|
||||
|
||||
dev->xmitwaiting = false;
|
||||
(void)sem_post(&dev->xmitsem);
|
||||
}
|
||||
|
||||
/* Is there a thread waiting for read data? */
|
||||
|
||||
if (dev->recvwaiting)
|
||||
{
|
||||
/* Yes... wake it up */
|
||||
|
||||
dev->recvwaiting = false;
|
||||
(void)sem_post(&dev->recvsem);
|
||||
}
|
||||
|
||||
/* Notify all poll/select waiters that and hangup occurred */
|
||||
|
||||
uart_pollnotify(dev, (POLLERR|POLLHUP));
|
||||
}
|
||||
|
||||
irqrestore(flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -726,10 +726,10 @@ int ramlog_sysloginit(void)
|
||||
*
|
||||
* Description:
|
||||
* This is the low-level system logging interface. The debugging/syslogging
|
||||
* interfaces are lib_rawprintf() and lib_lowprinf(). The difference is
|
||||
* the lib_rawprintf() writes to fd=1 (stdout) and lib_lowprintf() uses
|
||||
* interfaces are syslog() and lowsyslog(). The difference is that
|
||||
* the syslog() internface writes to fd=1 (stdout) whereas lowsyslog() uses
|
||||
* a lower level interface that works from interrupt handlers. This
|
||||
* function is a a low-level interface used to implement lib_lowprintf()
|
||||
* function is a a low-level interface used to implement lowsyslog()
|
||||
* when CONFIG_RAMLOG_SYSLOG=y and CONFIG_SYSLOG=y
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@@ -148,12 +148,21 @@ config COMPOSITE_VERSIONNO
|
||||
endif
|
||||
|
||||
menuconfig PL2303
|
||||
bool "Emulates the Prolific PL2303 serial/USB converter"
|
||||
bool "Prolific PL2303 serial/USB converter emulation"
|
||||
default n
|
||||
select SERIAL_REMOVABLE
|
||||
---help---
|
||||
This logic emulates the Prolific PL2303 serial/USB converter
|
||||
|
||||
if PL2303
|
||||
|
||||
config PL2303_CONSOLE
|
||||
bool "PL2303 console device"
|
||||
default n
|
||||
---help---
|
||||
Register the USB device as /dev/console so that is will be used
|
||||
as the console device.
|
||||
|
||||
config PL2303_EPINTIN
|
||||
int "Logical endpoint numbers"
|
||||
default 1
|
||||
@@ -208,18 +217,27 @@ config PL2303_VENDORSTR
|
||||
|
||||
config PL2303_PRODUCTSTR
|
||||
string "Product string"
|
||||
default "USBdev Serial"
|
||||
default "PL2303 Emulation"
|
||||
endif
|
||||
|
||||
menuconfig CDCACM
|
||||
bool "USB Modem (CDC ACM) support"
|
||||
default n
|
||||
select SERIAL_REMOVABLE
|
||||
---help---
|
||||
Enables USB Modem (CDC ACM) support
|
||||
|
||||
if CDCACM
|
||||
|
||||
config CDCACM_CONSOLE
|
||||
bool "CDC/ACM console device"
|
||||
default n
|
||||
---help---
|
||||
Register the USB device as /dev/console so that is will be used
|
||||
as the console device.
|
||||
|
||||
config CDCACM_COMPOSITE
|
||||
bool "CDCACM composite support"
|
||||
bool "CDC/ACM composite support"
|
||||
default n
|
||||
depends on USBDEV_COMPOSITE
|
||||
---help---
|
||||
@@ -256,10 +274,10 @@ config CDCACM_EP0MAXPACKET
|
||||
|
||||
config CDCACM_EPINTIN
|
||||
int "Hardware endpoint that supports interrupt IN operation"
|
||||
default 2
|
||||
default 1
|
||||
---help---
|
||||
The logical 7-bit address of a hardware endpoint that supports
|
||||
interrupt IN operation. Default 2.
|
||||
interrupt IN operation. Default 1.
|
||||
|
||||
config CDCACM_EPINTIN_FSSIZE
|
||||
int "Endpoint in full speed size"
|
||||
@@ -277,10 +295,10 @@ config CDCACM_EPINTIN_HSSIZE
|
||||
|
||||
config CDCACM_EPBULKOUT
|
||||
int "Endpoint bulk out"
|
||||
default 0
|
||||
default 3
|
||||
---help---
|
||||
The logical 7-bit address of a hardware endpoint that supports
|
||||
bulk OUT operation
|
||||
bulk OUT operation. Default: 3
|
||||
|
||||
config CDCACM_EPBULKOUT_FSSIZE
|
||||
int "Endpoint bulk out full speed size"
|
||||
@@ -298,10 +316,10 @@ config CDCACM_EPBULKOUT_HSSIZE
|
||||
|
||||
config CDCACM_EPBULKIN
|
||||
int "Endpoint bulk in"
|
||||
default 0
|
||||
default 2
|
||||
---help---
|
||||
The logical 7-bit address of a hardware endpoint that supports
|
||||
bulk IN operation
|
||||
bulk IN operation. Default: 2
|
||||
|
||||
config CDCACM_EPBULKIN_FSSIZE
|
||||
int "Endpoint bulk in full speed size"
|
||||
@@ -336,7 +354,7 @@ config CDCACM_RXBUFSIZE
|
||||
Size of the serial receive/transmit buffers
|
||||
|
||||
config CDCACM_TXBUFSIZE
|
||||
bool "Transmit buffer size"
|
||||
int "Transmit buffer size"
|
||||
default 256
|
||||
---help---
|
||||
Size of the serial receive/transmit buffers
|
||||
@@ -364,7 +382,7 @@ config CDCACM_VENDORSTR
|
||||
|
||||
config CDCACM_PRODUCTSTR
|
||||
string "Product string"
|
||||
default "USBdev Serial"
|
||||
default "CDC/ACM Serial"
|
||||
endif
|
||||
|
||||
menuconfig USBMSC
|
||||
@@ -479,8 +497,8 @@ config USBMSC_PRODUCTID
|
||||
default 0x00
|
||||
|
||||
config USBMSC_PRODUCTSTR
|
||||
string "Mass stroage product string"
|
||||
default "Mass stroage"
|
||||
string "Mass storage product string"
|
||||
default "Mass Storage"
|
||||
|
||||
config USBMSC_VERSIONNO
|
||||
hex "USB MSC Version Number"
|
||||
|
||||
+127
-10
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* drivers/usbdev/cdcacm.c
|
||||
*
|
||||
* Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2011-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -188,6 +188,12 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
size_t outlen);
|
||||
static void cdcacm_disconnect(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev);
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
static void cdcacm_suspend(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev);
|
||||
static void cdcacm_resume(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev);
|
||||
#endif
|
||||
|
||||
/* UART Operations **********************************************************/
|
||||
|
||||
@@ -211,8 +217,13 @@ static const struct usbdevclass_driverops_s g_driverops =
|
||||
cdcacm_unbind, /* unbind */
|
||||
cdcacm_setup, /* setup */
|
||||
cdcacm_disconnect, /* disconnect */
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
cdcacm_suspend, /* suspend */
|
||||
cdcacm_resume, /* resume */
|
||||
#else
|
||||
NULL, /* suspend */
|
||||
NULL, /* resume */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Serial port **************************************************************/
|
||||
@@ -570,6 +581,14 @@ static void cdcacm_resetconfig(FAR struct cdcacm_dev_s *priv)
|
||||
|
||||
priv->config = CDCACM_CONFIGIDNONE;
|
||||
|
||||
/* Inform the "upper half" driver that there is no (functional) USB
|
||||
* connection.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
uart_connected(&priv->serdev, false);
|
||||
#endif
|
||||
|
||||
/* Disable endpoints. This should force completion of all pending
|
||||
* transfers.
|
||||
*/
|
||||
@@ -731,10 +750,20 @@ static int cdcacm_setconfig(FAR struct cdcacm_dev_s *priv, uint8_t config)
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSUBMIT), (uint16_t)-ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
priv->nrdq++;
|
||||
}
|
||||
|
||||
/* We are successfully configured */
|
||||
|
||||
priv->config = config;
|
||||
|
||||
/* Inform the "upper half" driver that we are "open for business" */
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
uart_connected(&priv->serdev, true);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
|
||||
errout:
|
||||
@@ -823,6 +852,7 @@ static void cdcacm_rdcomplete(FAR struct usbdev_ep_s *ep,
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSUBMIT), (uint16_t)-req->result);
|
||||
}
|
||||
|
||||
irqrestore(flags);
|
||||
}
|
||||
|
||||
@@ -932,6 +962,7 @@ static int cdcacm_bind(FAR struct usbdevclass_driver_s *driver,
|
||||
ret = -ENOMEM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
priv->ctrlreq->callback = cdcacm_ep0incomplete;
|
||||
|
||||
/* Pre-allocate all endpoints... the endpoints will not be functional
|
||||
@@ -1575,12 +1606,20 @@ static void cdcacm_disconnect(FAR struct usbdevclass_driver_s *driver,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Reset the configuration */
|
||||
/* Inform the "upper half serial driver that we have lost the USB serial
|
||||
* connection.
|
||||
*/
|
||||
|
||||
flags = irqsave();
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
uart_connected(&priv->serdev, false);
|
||||
#endif
|
||||
|
||||
/* Reset the configuration */
|
||||
|
||||
cdcacm_resetconfig(priv);
|
||||
|
||||
/* Clear out all data in the circular buffer */
|
||||
/* Clear out all outgoing data in the circular buffer */
|
||||
|
||||
priv->serdev.xmit.head = 0;
|
||||
priv->serdev.xmit.tail = 0;
|
||||
@@ -1595,6 +1634,79 @@ static void cdcacm_disconnect(FAR struct usbdevclass_driver_s *driver,
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cdcacm_suspend
|
||||
*
|
||||
* Description:
|
||||
* Handle the USB suspend event.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
static void cdcacm_suspend(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev)
|
||||
{
|
||||
FAR struct cdcacm_dev_s *priv;
|
||||
|
||||
usbtrace(TRACE_CLASSSUSPEND, 0);
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
if (!driver || !dev)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Extract reference to private data */
|
||||
|
||||
priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
|
||||
|
||||
/* And let the "upper half" driver now that we are suspended */
|
||||
|
||||
uart_connected(&priv->serdev, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cdcacm_resume
|
||||
*
|
||||
* Description:
|
||||
* Handle the USB resume event.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
static void cdcacm_resume(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev)
|
||||
{
|
||||
FAR struct cdcacm_dev_s *priv;
|
||||
|
||||
usbtrace(TRACE_CLASSRESUME, 0);
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
if (!driver || !dev)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Extract reference to private data */
|
||||
|
||||
priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
|
||||
|
||||
/* Are we still configured? */
|
||||
|
||||
if (priv->config != CDCACM_CONFIGIDNONE)
|
||||
{
|
||||
/* Yes.. let the "upper half" know that have resumed */
|
||||
|
||||
uart_connected(&priv->serdev, true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Serial Device Methods
|
||||
****************************************************************************/
|
||||
@@ -2045,12 +2157,17 @@ int cdcacm_classobject(int minor, FAR struct usbdevclass_driver_s **classdev)
|
||||
|
||||
/* Initialize the serial driver sub-structure */
|
||||
|
||||
priv->serdev.recv.size = CONFIG_CDCACM_RXBUFSIZE;
|
||||
priv->serdev.recv.buffer = priv->rxbuffer;
|
||||
priv->serdev.xmit.size = CONFIG_CDCACM_TXBUFSIZE;
|
||||
priv->serdev.xmit.buffer = priv->txbuffer;
|
||||
priv->serdev.ops = &g_uartops;
|
||||
priv->serdev.priv = priv;
|
||||
/* The initial state is disconnected */
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
priv->serdev.disconnected = true;
|
||||
#endif
|
||||
priv->serdev.recv.size = CONFIG_CDCACM_RXBUFSIZE;
|
||||
priv->serdev.recv.buffer = priv->rxbuffer;
|
||||
priv->serdev.xmit.size = CONFIG_CDCACM_TXBUFSIZE;
|
||||
priv->serdev.xmit.buffer = priv->txbuffer;
|
||||
priv->serdev.ops = &g_uartops;
|
||||
priv->serdev.priv = priv;
|
||||
|
||||
/* Initialize the USB class driver structure */
|
||||
|
||||
@@ -2148,7 +2265,7 @@ int cdcacm_initialize(int minor, FAR void **handle)
|
||||
*
|
||||
* Description:
|
||||
* Un-initialize the USB storage class driver. This function is used
|
||||
* internally by the USB composite driver to unitialized the CDC/ACM
|
||||
* internally by the USB composite driver to unitialize the CDC/ACM
|
||||
* driver. This same interface is available (with an untyped input
|
||||
* parameter) when the CDC/ACM driver is used standalone.
|
||||
*
|
||||
|
||||
@@ -343,6 +343,12 @@ static int usbclass_setup(FAR struct usbdevclass_driver_s *driver,
|
||||
size_t outlen);
|
||||
static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev);
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
static void usbclass_suspend(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev);
|
||||
static void usbclass_resume(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev);
|
||||
#endif
|
||||
|
||||
/* Serial port *************************************************************/
|
||||
|
||||
@@ -366,8 +372,13 @@ static const struct usbdevclass_driverops_s g_driverops =
|
||||
usbclass_unbind, /* unbind */
|
||||
usbclass_setup, /* setup */
|
||||
usbclass_disconnect, /* disconnect */
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
usbclass_suspend, /* suspend */
|
||||
usbclass_resume, /* resume */
|
||||
#else
|
||||
NULL, /* suspend */
|
||||
NULL, /* resume */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Serial port *************************************************************/
|
||||
@@ -983,6 +994,14 @@ static void usbclass_resetconfig(FAR struct pl2303_dev_s *priv)
|
||||
|
||||
priv->config = PL2303_CONFIGIDNONE;
|
||||
|
||||
/* Inform the "upper half" driver that there is no (functional) USB
|
||||
* connection.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
uart_connected(&priv->serdev, false);
|
||||
#endif
|
||||
|
||||
/* Disable endpoints. This should force completion of all pending
|
||||
* transfers.
|
||||
*/
|
||||
@@ -1112,10 +1131,20 @@ static int usbclass_setconfig(FAR struct pl2303_dev_s *priv, uint8_t config)
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSUBMIT), (uint16_t)-ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
priv->nrdq++;
|
||||
}
|
||||
|
||||
/* We are successfully configured */
|
||||
|
||||
priv->config = config;
|
||||
|
||||
/* Inform the "upper half" driver that we are "open for business" */
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
uart_connected(&priv->serdev, true);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
|
||||
errout:
|
||||
@@ -1844,12 +1873,20 @@ static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Reset the configuration */
|
||||
/* Inform the "upper half serial driver that we have lost the USB serial
|
||||
* connection.
|
||||
*/
|
||||
|
||||
flags = irqsave();
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
uart_connected(&priv->serdev, false);
|
||||
#endif
|
||||
|
||||
/* Reset the configuration */
|
||||
|
||||
usbclass_resetconfig(priv);
|
||||
|
||||
/* Clear out all data in the circular buffer */
|
||||
/* Clear out all outgoing data in the circular buffer */
|
||||
|
||||
priv->serdev.xmit.head = 0;
|
||||
priv->serdev.xmit.tail = 0;
|
||||
@@ -1862,6 +1899,79 @@ static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver,
|
||||
DEV_CONNECT(dev);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbclass_suspend
|
||||
*
|
||||
* Description:
|
||||
* Handle the USB suspend event.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
static void usbclass_suspend(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev)
|
||||
{
|
||||
FAR struct cdcacm_dev_s *priv;
|
||||
|
||||
usbtrace(TRACE_CLASSSUSPEND, 0);
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
if (!driver || !dev)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Extract reference to private data */
|
||||
|
||||
priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
|
||||
|
||||
/* And let the "upper half" driver now that we are suspended */
|
||||
|
||||
uart_connected(&priv->serdev, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: usbclass_resume
|
||||
*
|
||||
* Description:
|
||||
* Handle the USB resume event.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
static void usbclass_resume(FAR struct usbdevclass_driver_s *driver,
|
||||
FAR struct usbdev_s *dev)
|
||||
{
|
||||
FAR struct cdcacm_dev_s *priv;
|
||||
|
||||
usbtrace(TRACE_CLASSRESUME, 0);
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
if (!driver || !dev)
|
||||
{
|
||||
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Extract reference to private data */
|
||||
|
||||
priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
|
||||
|
||||
/* Are we still configured? */
|
||||
|
||||
if (priv->config != PL2303_CONFIGIDNONE)
|
||||
{
|
||||
/* Yes.. let the "upper half" know that have resumed */
|
||||
|
||||
uart_connected(&priv->serdev, true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Serial Device Methods
|
||||
****************************************************************************/
|
||||
@@ -2185,12 +2295,15 @@ int usbdev_serialinitialize(int minor)
|
||||
|
||||
/* Initialize the serial driver sub-structure */
|
||||
|
||||
priv->serdev.recv.size = CONFIG_PL2303_RXBUFSIZE;
|
||||
priv->serdev.recv.buffer = priv->rxbuffer;
|
||||
priv->serdev.xmit.size = CONFIG_PL2303_TXBUFSIZE;
|
||||
priv->serdev.xmit.buffer = priv->txbuffer;
|
||||
priv->serdev.ops = &g_uartops;
|
||||
priv->serdev.priv = priv;
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
priv->serdev.disconnected = true;
|
||||
#endif
|
||||
priv->serdev.recv.size = CONFIG_PL2303_RXBUFSIZE;
|
||||
priv->serdev.recv.buffer = priv->rxbuffer;
|
||||
priv->serdev.xmit.size = CONFIG_PL2303_TXBUFSIZE;
|
||||
priv->serdev.xmit.buffer = priv->txbuffer;
|
||||
priv->serdev.ops = &g_uartops;
|
||||
priv->serdev.priv = priv;
|
||||
|
||||
/* Initialize the USB class driver structure */
|
||||
|
||||
|
||||
@@ -168,9 +168,9 @@ void usbtrace(uint16_t event, uint16_t value)
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Just print the data using lib_lowprintf */
|
||||
/* Just print the data using lowsyslog */
|
||||
|
||||
usbtrace_trprintf((trprintf_t)lib_lowprintf, event, value);
|
||||
usbtrace_trprintf((trprintf_t)lowsyslog, event, value);
|
||||
#endif
|
||||
}
|
||||
irqrestore(flags);
|
||||
|
||||
@@ -199,9 +199,9 @@
|
||||
#ifdef CONFIG_CPP_HAVE_VARARGS
|
||||
# ifdef CONFIG_DEBUG
|
||||
# ifdef CONFIG_ARCH_LOWPUTC
|
||||
# define dbgprintf(format, arg...) lib_lowprintf(format, ##arg)
|
||||
# define dbgprintf(format, arg...) lowsyslog(format, ##arg)
|
||||
# else
|
||||
# define dbgprintf(format, arg...) lib_rawprintf(format, ##arg)
|
||||
# define dbgprintf(format, arg...) syslog(format, ##arg)
|
||||
# endif
|
||||
# else
|
||||
# define dbgprintf(x...)
|
||||
@@ -209,9 +209,9 @@
|
||||
#else
|
||||
# ifdef CONFIG_DEBUG
|
||||
# ifdef CONFIG_ARCH_LOWPUTC
|
||||
# define dbgprintf lib_lowprintf
|
||||
# define dbgprintf lowsyslog
|
||||
# else
|
||||
# define dbgprintf lib_rawprintf
|
||||
# define dbgprintf syslog
|
||||
# endif
|
||||
# else
|
||||
# define dbgprintf (void)
|
||||
|
||||
+30
-12
@@ -5,6 +5,10 @@
|
||||
|
||||
comment "File system configuration"
|
||||
|
||||
config DISABLE_MOUNTPOINT
|
||||
bool "Disable support for mount points"
|
||||
default n
|
||||
|
||||
source fs/mmap/Kconfig
|
||||
source fs/fat/Kconfig
|
||||
source fs/nfs/Kconfig
|
||||
@@ -14,29 +18,43 @@ source fs/binfs/Kconfig
|
||||
|
||||
comment "System Logging"
|
||||
|
||||
config SYSLOG
|
||||
bool "System logging"
|
||||
config SYSLOG_ENABLE
|
||||
bool "Enable SYSLOG Controls"
|
||||
default n
|
||||
---help---
|
||||
Enables generic system logging features.
|
||||
Support an interface called syslog_enable to dynamically enable or
|
||||
disable SYSLOG output. Default: SYSLOG output is always enabled.
|
||||
|
||||
config SYSLOG_DEVPATH
|
||||
string "System log device"
|
||||
default "/dev/syslog"
|
||||
depends on SYSLOG
|
||||
config SYSLOG
|
||||
bool "Advanced SYSLOG features"
|
||||
default n
|
||||
---help---
|
||||
The full path to the system logging device. For the RAMLOG SYSLOG device,
|
||||
this is normally "/dev/ramlog". For character SYSLOG devices, it should be
|
||||
some other existing character device (or file) supported by the configuration
|
||||
(such as "/dev/ttyS1")/
|
||||
Enables generic system logging features. NOTE: This setting is not
|
||||
required to enable system logging. If this feature is not enable
|
||||
system logging will still be available and will log to the system
|
||||
console (like printf()). This setting is required to enable
|
||||
customization of the basic system loggin capability.
|
||||
|
||||
if SYSLOG
|
||||
|
||||
config SYSLOG_CHAR
|
||||
bool "System log character device support"
|
||||
default y
|
||||
depends on SYSLOG
|
||||
---help---
|
||||
Enable the generic character device for the SYSLOG. The full path to the
|
||||
SYSLOG device is provided by SYSLOG_DEVPATH. A valid character device (or
|
||||
file) must exist at this path. It will by opened by syslog_initialize.
|
||||
|
||||
Do not enable more than one SYSLOG device.
|
||||
|
||||
config SYSLOG_DEVPATH
|
||||
string "System log device"
|
||||
default "/dev/syslog"
|
||||
depends on SYSLOG_CHAR
|
||||
---help---
|
||||
The full path to the system logging device. For the RAMLOG SYSLOG device,
|
||||
this is normally "/dev/ramlog". For character SYSLOG devices, it should be
|
||||
some other existing character device (or file) supported by the configuration
|
||||
(such as "/dev/ttyS1")/
|
||||
|
||||
endif
|
||||
|
||||
@@ -406,7 +406,7 @@ mkfatfs_clustersearchlimits(FAR struct fat_format_s *fmt, FAR struct fat_var_s *
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mkfatfs_try12
|
||||
* Name: mkfatfs_tryfat12
|
||||
*
|
||||
* Description:
|
||||
* Try to define a FAT12 filesystem on the device using the candidate
|
||||
@@ -462,7 +462,7 @@ mkfatfs_tryfat12(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var,
|
||||
* FAT12 (remembering that two FAT cluster slots are reserved).
|
||||
*/
|
||||
|
||||
if (config->fc_nclusters > maxnclusters - 2)
|
||||
if (config->fc_nclusters + 2 > maxnclusters)
|
||||
{
|
||||
fvdbg("Too many clusters for FAT12\n");
|
||||
return -ENFILE;
|
||||
@@ -472,7 +472,7 @@ mkfatfs_tryfat12(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var,
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mkfatfs_try16
|
||||
* Name: mkfatfs_tryfat16
|
||||
*
|
||||
* Description:
|
||||
* Try to define a FAT16 filesystem on the device using the candidate
|
||||
@@ -532,7 +532,7 @@ mkfatfs_tryfat16(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var,
|
||||
* be confused as a FAT12 at mount time.
|
||||
*/
|
||||
|
||||
if ((config->fc_nclusters > maxnclusters - 2) ||
|
||||
if ((config->fc_nclusters + 2 > maxnclusters) ||
|
||||
(config->fc_nclusters < FAT_MINCLUST16))
|
||||
{
|
||||
fvdbg("Too few or too many clusters for FAT16\n");
|
||||
@@ -543,7 +543,7 @@ mkfatfs_tryfat16(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var,
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mkfatfs_try32
|
||||
* Name: mkfatfs_tryfat32
|
||||
*
|
||||
* Description:
|
||||
* Try to define a FAT32 filesystem on the device using the candidate
|
||||
@@ -587,7 +587,7 @@ mkfatfs_tryfat32(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var,
|
||||
* maxnclusters = nfatsects * sectorsize / 4 - 2
|
||||
*/
|
||||
|
||||
maxnclusters = (config->fc_nfatsects >> (var->fv_sectshift - 2));
|
||||
maxnclusters = (config->fc_nfatsects << (var->fv_sectshift - 2));
|
||||
if (maxnclusters > FAT_MAXCLUST32)
|
||||
{
|
||||
maxnclusters = FAT_MAXCLUST32;
|
||||
@@ -599,7 +599,7 @@ mkfatfs_tryfat32(FAR struct fat_format_s *fmt, FAR struct fat_var_s *var,
|
||||
* FAT32 (remembering that two FAT cluster slots are reserved).
|
||||
*/
|
||||
|
||||
if ((config->fc_nclusters > maxnclusters - 3) ||
|
||||
if ((config->fc_nclusters + 3 > maxnclusters) ||
|
||||
(config->fc_nclusters < FAT_MINCLUST32 && fmt->ff_fattype != 32))
|
||||
{
|
||||
fvdbg("Too few or too many clusters for FAT32\n");
|
||||
|
||||
@@ -381,6 +381,7 @@ static int fat_close(FAR struct file *filep)
|
||||
{
|
||||
struct inode *inode;
|
||||
struct fat_file_s *ff;
|
||||
struct fat_mountpt_s *fs;
|
||||
int ret = OK;
|
||||
|
||||
/* Sanity checks */
|
||||
@@ -391,6 +392,7 @@ static int fat_close(FAR struct file *filep)
|
||||
|
||||
ff = filep->f_priv;
|
||||
inode = filep->f_inode;
|
||||
fs = inode->i_private;
|
||||
|
||||
/* Do not check if the mount is healthy. We must support closing of
|
||||
* the file even when there is healthy mount.
|
||||
@@ -408,6 +410,7 @@ static int fat_close(FAR struct file *filep)
|
||||
|
||||
if (ff->ff_buffer)
|
||||
{
|
||||
(void)fs; /* Unused if fat_io_free == free(). */
|
||||
fat_io_free(ff->ff_buffer, fs->fs_hwsectorsize);
|
||||
}
|
||||
|
||||
|
||||
@@ -106,8 +106,8 @@ static int fat_checkfsinfo(struct fat_mountpt_s *fs)
|
||||
FSI_GETSTRUCTSIG(fs->fs_buffer) == 0x61417272 &&
|
||||
FSI_GETTRAILSIG(fs->fs_buffer) == BOOT_SIGNATURE32)
|
||||
{
|
||||
fs->fs_fsinextfree = FSI_GETFREECOUNT(fs->fs_buffer);
|
||||
fs->fs_fsifreecount = FSI_GETNXTFREE(fs->fs_buffer);
|
||||
fs->fs_fsifreecount = FSI_GETFREECOUNT(fs->fs_buffer);
|
||||
fs->fs_fsinextfree = FSI_GETNXTFREE(fs->fs_buffer);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* fs/fs_fdopen.c
|
||||
*
|
||||
* Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -68,9 +68,11 @@ static inline int fs_checkfd(FAR _TCB *tcb, int fd, int oflags)
|
||||
FAR struct filelist *flist;
|
||||
FAR struct inode *inode;
|
||||
|
||||
/* Get the file list from the TCB */
|
||||
DEBUGASSERT(tcb && tcb->group);
|
||||
|
||||
flist = tcb->filelist;
|
||||
/* Get the file list from the task group */
|
||||
|
||||
flist = &tcb->group->tg_filelist;
|
||||
|
||||
/* Get the inode associated with the file descriptor. This should
|
||||
* normally be the case if fd >= 0. But not in the case where the
|
||||
@@ -142,6 +144,7 @@ FAR struct file_struct *fs_fdopen(int fd, int oflags, FAR _TCB *tcb)
|
||||
{
|
||||
tcb = sched_self();
|
||||
}
|
||||
DEBUGASSERT(tcb && tcb->group);
|
||||
|
||||
/* Verify that this is a valid file/socket descriptor and that the
|
||||
* requested access can be support.
|
||||
@@ -189,9 +192,9 @@ FAR struct file_struct *fs_fdopen(int fd, int oflags, FAR _TCB *tcb)
|
||||
|
||||
/* Get the stream list from the TCB */
|
||||
|
||||
slist = tcb->streams;
|
||||
slist = &tcb->group->tg_streamlist;
|
||||
|
||||
/* Find an unallocated FILE structure in the stream list */
|
||||
/* Find an unallocated FILE structure in the stream list */
|
||||
|
||||
ret = sem_wait(&slist->sl_sem);
|
||||
if (ret != OK)
|
||||
|
||||
+21
-84
@@ -155,56 +155,19 @@ void files_initialize(void)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: files_alloclist
|
||||
* Name: files_initlist
|
||||
*
|
||||
* Description: Allocate a list of files for a new task
|
||||
* Description: Initializes the list of files for a new task
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct filelist *files_alloclist(void)
|
||||
void files_initlist(FAR struct filelist *list)
|
||||
{
|
||||
FAR struct filelist *list;
|
||||
list = (FAR struct filelist*)kzalloc(sizeof(struct filelist));
|
||||
if (list)
|
||||
{
|
||||
/* Start with a reference count of one */
|
||||
DEBUGASSERT(list);
|
||||
|
||||
list->fl_crefs = 1;
|
||||
/* Initialize the list access mutex */
|
||||
|
||||
/* Initialize the list access mutex */
|
||||
|
||||
(void)sem_init(&list->fl_sem, 0, 1);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: files_addreflist
|
||||
*
|
||||
* Description:
|
||||
* Increase the reference count on a file list
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int files_addreflist(FAR struct filelist *list)
|
||||
{
|
||||
if (list)
|
||||
{
|
||||
/* Increment the reference count on the list.
|
||||
* NOTE: that we disable interrupts to do this
|
||||
* (vs. taking the list semaphore). We do this
|
||||
* because file cleanup operations often must be
|
||||
* done from the IDLE task which cannot wait
|
||||
* on semaphores.
|
||||
*/
|
||||
|
||||
register irqstate_t flags = irqsave();
|
||||
list->fl_crefs++;
|
||||
irqrestore(flags);
|
||||
}
|
||||
|
||||
return OK;
|
||||
(void)sem_init(&list->fl_sem, 0, 1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -215,51 +178,25 @@ int files_addreflist(FAR struct filelist *list)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int files_releaselist(FAR struct filelist *list)
|
||||
void files_releaselist(FAR struct filelist *list)
|
||||
{
|
||||
int crefs;
|
||||
if (list)
|
||||
int i;
|
||||
|
||||
DEBUGASSERT(list);
|
||||
|
||||
/* Close each file descriptor .. Normally, you would need take the list
|
||||
* semaphore, but it is safe to ignore the semaphore in this context because
|
||||
* there should not be any references in this context.
|
||||
*/
|
||||
|
||||
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||
{
|
||||
/* Decrement the reference count on the list.
|
||||
* NOTE: that we disable interrupts to do this
|
||||
* (vs. taking the list semaphore). We do this
|
||||
* because file cleanup operations often must be
|
||||
* done from the IDLE task which cannot wait
|
||||
* on semaphores.
|
||||
*/
|
||||
|
||||
register irqstate_t flags = irqsave();
|
||||
crefs = --(list->fl_crefs);
|
||||
irqrestore(flags);
|
||||
|
||||
/* If the count decrements to zero, then there is no reference
|
||||
* to the structure and it should be deallocated. Since there
|
||||
* are references, it would be an error if any task still held
|
||||
* a reference to the list's semaphore.
|
||||
*/
|
||||
|
||||
if (crefs <= 0)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Close each file descriptor .. Normally, you would need
|
||||
* take the list semaphore, but it is safe to ignore the
|
||||
* semaphore in this context because there are no references
|
||||
*/
|
||||
|
||||
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||
{
|
||||
(void)_files_close(&list->fl_files[i]);
|
||||
}
|
||||
|
||||
/* Destroy the semaphore and release the filelist */
|
||||
|
||||
(void)sem_destroy(&list->fl_sem);
|
||||
sched_free(list);
|
||||
}
|
||||
(void)_files_close(&list->fl_files[i]);
|
||||
}
|
||||
|
||||
return OK;
|
||||
/* Destroy the semaphore */
|
||||
|
||||
(void)sem_destroy(&list->fl_sem);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
+40
-19
@@ -42,6 +42,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <semaphore.h>
|
||||
@@ -167,8 +168,10 @@ static inline int syslog_takesem(void)
|
||||
|
||||
static inline void syslog_givesem(void)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG
|
||||
pid_t me = getpid();
|
||||
DEBUGASSERT(g_sysdev.sl_holder == me);
|
||||
#endif
|
||||
|
||||
/* Relinquish the semaphore */
|
||||
|
||||
@@ -265,7 +268,7 @@ int syslog_initialize(void)
|
||||
{
|
||||
/* The inode was not found. In this case, we will attempt to re-open
|
||||
* the device repeatedly. The assumption is that the device path is
|
||||
* value but that the driver has not yet been registered.
|
||||
* valid but that the driver has not yet been registered.
|
||||
*/
|
||||
|
||||
g_sysdev.sl_state = SYSLOG_REOPEN;
|
||||
@@ -282,7 +285,7 @@ int syslog_initialize(void)
|
||||
if (!INODE_IS_DRIVER(inode))
|
||||
#endif
|
||||
{
|
||||
ret = ENXIO;
|
||||
ret = -ENXIO;
|
||||
goto errout_with_inode;
|
||||
}
|
||||
|
||||
@@ -290,7 +293,7 @@ int syslog_initialize(void)
|
||||
|
||||
if (!inode->u.i_ops || !inode->u.i_ops->write)
|
||||
{
|
||||
return -EACCES;
|
||||
ret = -EACCES;
|
||||
goto errout_with_inode;
|
||||
}
|
||||
|
||||
@@ -346,8 +349,8 @@ int syslog_initialize(void)
|
||||
return OK;
|
||||
|
||||
errout_with_inode:
|
||||
g_sysdev.sl_state = SYSLOG_FAILURE;
|
||||
inode_release(inode);
|
||||
g_sysdev.sl_state = SYSLOG_FAILURE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -356,16 +359,18 @@ int syslog_initialize(void)
|
||||
*
|
||||
* Description:
|
||||
* This is the low-level system logging interface. The debugging/syslogging
|
||||
* interfaces are lib_rawprintf() and lib_lowprinf(). The difference is
|
||||
* the lib_rawprintf() writes to fd=1 (stdout) and lib_lowprintf() uses
|
||||
* interfaces are syslog() and lowsyslog(). The difference is is that
|
||||
* the syslog() function writes to fd=1 (stdout) whereas lowsyslog() uses
|
||||
* a lower level interface that works from interrupt handlers. This
|
||||
* function is a a low-level interface used to implement lib_lowprintf().
|
||||
* function is a a low-level interface used to implement lowsyslog().
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int syslog_putc(int ch)
|
||||
{
|
||||
ssize_t nbytes;
|
||||
uint8_t uch;
|
||||
int errcode;
|
||||
int ret;
|
||||
|
||||
/* Ignore any output:
|
||||
@@ -382,7 +387,10 @@ int syslog_putc(int ch)
|
||||
* (4) Any debug output generated from interrupt handlers. A disadvantage
|
||||
* of using the generic character device for the SYSLOG is that it
|
||||
* cannot handle debug output generated from interrupt level handlers.
|
||||
* (5) If an irrecoverable failure occurred during initialization. In
|
||||
* (5) Any debug output generated from the IDLE loop. The character
|
||||
* driver interface is blocking and the IDLE thread is not permitted
|
||||
* to block.
|
||||
* (6) If an irrecoverable failure occurred during initialization. In
|
||||
* this case, we won't ever bother to try again (ever).
|
||||
*
|
||||
* NOTE: That the third case is different. It applies only to the thread
|
||||
@@ -390,11 +398,12 @@ int syslog_putc(int ch)
|
||||
* that is why that case is handled in syslog_semtake().
|
||||
*/
|
||||
|
||||
/* Case (4) */
|
||||
/* Cases (4) and (5) */
|
||||
|
||||
if (up_interrupt_context())
|
||||
if (up_interrupt_context() || getpid() == 0)
|
||||
{
|
||||
return -ENOSYS; /* Not supported */
|
||||
errcode = ENOSYS;
|
||||
goto errout_with_errcode;
|
||||
}
|
||||
|
||||
/* We can save checks in the usual case: That after the SYSLOG device
|
||||
@@ -408,14 +417,16 @@ int syslog_putc(int ch)
|
||||
if (g_sysdev.sl_state == SYSLOG_UNINITIALIZED ||
|
||||
g_sysdev.sl_state == SYSLOG_INITIALIZING)
|
||||
{
|
||||
return -EAGAIN; /* Can't access the SYSLOG now... maybe next time? */
|
||||
errcode = EAGAIN; /* Can't access the SYSLOG now... maybe next time? */
|
||||
goto errout_with_errcode;
|
||||
}
|
||||
|
||||
/* Case (5) */
|
||||
/* Case (6) */
|
||||
|
||||
if (g_sysdev.sl_state == SYSLOG_FAILURE)
|
||||
{
|
||||
return -ENXIO; /* There is no SYSLOG device */
|
||||
errcode = ENXIO; /* There is no SYSLOG device */
|
||||
goto errout_with_errcode;
|
||||
}
|
||||
|
||||
/* syslog_initialize() is called as soon as enough of the operating
|
||||
@@ -443,7 +454,8 @@ int syslog_putc(int ch)
|
||||
if (ret < 0)
|
||||
{
|
||||
sched_unlock();
|
||||
return ret;
|
||||
errcode = -ret;
|
||||
goto errout_with_errcode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,7 +483,8 @@ int syslog_putc(int ch)
|
||||
* way, we are outta here.
|
||||
*/
|
||||
|
||||
return ret;
|
||||
errcode = -ret;
|
||||
goto errout_with_errcode;
|
||||
}
|
||||
|
||||
/* Pre-pend a newline with a carriage return. */
|
||||
@@ -497,19 +510,27 @@ int syslog_putc(int ch)
|
||||
{
|
||||
/* Write the non-newline character (and don't flush) */
|
||||
|
||||
nbytes = syslog_write(&ch, 1);
|
||||
uch = (uint8_t)ch;
|
||||
nbytes = syslog_write(&uch, 1);
|
||||
}
|
||||
|
||||
syslog_givesem();
|
||||
|
||||
/* Check if the write was successful */
|
||||
/* Check if the write was successful. If not, nbytes will be
|
||||
* a negated errno value.
|
||||
*/
|
||||
|
||||
if (nbytes < 0)
|
||||
{
|
||||
return nbytes;
|
||||
errcode = -ret;
|
||||
goto errout_with_errcode;
|
||||
}
|
||||
|
||||
return ch;
|
||||
|
||||
errout_with_errcode:
|
||||
set_errno(errcode);
|
||||
return EOF;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SYSLOG && CONFIG_SYSLOG_CHAR */
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
*/
|
||||
|
||||
#undef fdbg
|
||||
#define fdbg lib_rawprintf
|
||||
#define fdbg syslog
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
|
||||
@@ -242,7 +242,7 @@ static FAR const struct nx_fontpackage_s *g_fontpackages[] =
|
||||
* Name: nxf_getglyphset
|
||||
*
|
||||
* Description:
|
||||
* Return information about the font set containtined he selected
|
||||
* Return information about the font set contained in the selected
|
||||
* character encoding.
|
||||
*
|
||||
* Input Parameters:
|
||||
|
||||
+13
-8
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* include/assert.h
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -100,23 +100,28 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Global Function Prototypes
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_HAVE_FILENAME
|
||||
EXTERN void up_assert(FAR const uint8_t *filename, int linenum);
|
||||
EXTERN void up_assert_code(FAR const uint8_t *filename, int linenum,
|
||||
int errcode);
|
||||
void up_assert(FAR const uint8_t *filename, int linenum) noreturn_function;
|
||||
void up_assert_code(FAR const uint8_t *filename, int linenum, int errcode)
|
||||
noreturn_function;
|
||||
#else
|
||||
EXTERN void up_assert(void);
|
||||
EXTERN void up_assert_code(int errcode);
|
||||
void up_assert(void) noreturn_function;
|
||||
void up_assert_code(int errcode) noreturn_function;
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
|
||||
+12
-25
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* include/debug.h
|
||||
*
|
||||
* Copyright (C) 2007-2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2011, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -43,7 +43,7 @@
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/compiler.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <syslog.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
@@ -104,22 +104,22 @@
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
# define dbg(format, arg...) \
|
||||
lib_rawprintf(EXTRA_FMT format EXTRA_ARG, ##arg)
|
||||
syslog(EXTRA_FMT format EXTRA_ARG, ##arg)
|
||||
|
||||
# ifdef CONFIG_ARCH_LOWPUTC
|
||||
# define lldbg(format, arg...) \
|
||||
lib_lowprintf(EXTRA_FMT format EXTRA_ARG, ##arg)
|
||||
lowsyslog(EXTRA_FMT format EXTRA_ARG, ##arg)
|
||||
# else
|
||||
# define lldbg(x...)
|
||||
# endif
|
||||
|
||||
# ifdef CONFIG_DEBUG_VERBOSE
|
||||
# define vdbg(format, arg...) \
|
||||
lib_rawprintf(EXTRA_FMT format EXTRA_ARG, ##arg)
|
||||
syslog(EXTRA_FMT format EXTRA_ARG, ##arg)
|
||||
|
||||
# ifdef CONFIG_ARCH_LOWPUTC
|
||||
# define llvdbg(format, arg...) \
|
||||
lib_lowprintf(EXTRA_FMT format EXTRA_ARG, ##arg)
|
||||
lowsyslog(EXTRA_FMT format EXTRA_ARG, ##arg)
|
||||
# else
|
||||
# define llvdbg(x...)
|
||||
# endif
|
||||
@@ -576,29 +576,16 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* These low-level debug APIs are provided by the NuttX library. If the
|
||||
* cross-compiler's pre-processor supports a variable number of macro
|
||||
* arguments, then the macros below will map all debug statements to one
|
||||
* or the other of the following.
|
||||
*/
|
||||
|
||||
int lib_rawprintf(FAR const char *format, ...);
|
||||
|
||||
#ifdef CONFIG_ARCH_LOWPUTC
|
||||
int lib_lowprintf(FAR const char *format, ...);
|
||||
#endif
|
||||
|
||||
/* Dump a buffer of data */
|
||||
|
||||
void lib_dumpbuffer(FAR const char *msg, FAR const uint8_t *buffer, unsigned int buflen);
|
||||
|
||||
/* Enable or disable debug output */
|
||||
|
||||
#ifdef CONFIG_DEBUG_ENABLE
|
||||
void dbg_enable(bool enable);
|
||||
#endif
|
||||
|
||||
/* If the cross-compiler's pre-processor does not support variable length
|
||||
/* The system logging interfaces are pnormally accessed via the macros
|
||||
* provided above. If the cross-compiler's C pre-processor supports a
|
||||
* variable number of macro arguments, then those macros below will map all
|
||||
* debug statements to the logging interfaces declared in syslog.h.
|
||||
*
|
||||
* If the cross-compiler's pre-processor does not support variable length
|
||||
* arguments, then these additional APIs will be built.
|
||||
*/
|
||||
|
||||
|
||||
+38
-52
@@ -240,7 +240,6 @@ struct file
|
||||
struct filelist
|
||||
{
|
||||
sem_t fl_sem; /* Manage access to the file list */
|
||||
int16_t fl_crefs; /* Reference count */
|
||||
struct file fl_files[CONFIG_NFILE_DESCRIPTORS];
|
||||
};
|
||||
#endif
|
||||
@@ -294,7 +293,6 @@ struct file_struct
|
||||
|
||||
struct streamlist
|
||||
{
|
||||
int sl_crefs; /* Reference count */
|
||||
sem_t sl_sem; /* For thread safety */
|
||||
struct file_struct sl_streams[CONFIG_NFILE_STREAMS];
|
||||
};
|
||||
@@ -318,7 +316,8 @@ typedef int (*foreach_mountpoint_t)(FAR const char *mountpoint,
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
@@ -333,7 +332,7 @@ extern "C" {
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN void weak_function fs_initialize(void);
|
||||
void weak_function fs_initialize(void);
|
||||
|
||||
/* fs_foreachmountpoint.c ***************************************************/
|
||||
/****************************************************************************
|
||||
@@ -357,7 +356,7 @@ EXTERN void weak_function fs_initialize(void);
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_MOUNTPOUNT
|
||||
EXTERN int foreach_mountpoint(foreach_mountpoint_t handler, FAR void *arg);
|
||||
int foreach_mountpoint(foreach_mountpoint_t handler, FAR void *arg);
|
||||
#endif
|
||||
|
||||
/* fs_registerdriver.c ******************************************************/
|
||||
@@ -384,9 +383,8 @@ EXTERN int foreach_mountpoint(foreach_mountpoint_t handler, FAR void *arg);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN int register_driver(const char *path,
|
||||
const struct file_operations *fops,
|
||||
mode_t mode, void *priv);
|
||||
int register_driver(FAR const char *path, FAR const struct file_operations *fops,
|
||||
mode_t mode, FAR void *priv);
|
||||
|
||||
/* fs_registerblockdriver.c *************************************************/
|
||||
/****************************************************************************
|
||||
@@ -412,9 +410,9 @@ EXTERN int register_driver(const char *path,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN int register_blockdriver(const char *path,
|
||||
const struct block_operations *bops,
|
||||
mode_t mode, void *priv);
|
||||
int register_blockdriver(FAR const char *path,
|
||||
FAR const struct block_operations *bops, mode_t mode,
|
||||
FAR void *priv);
|
||||
|
||||
/* fs_unregisterdriver.c ****************************************************/
|
||||
/****************************************************************************
|
||||
@@ -425,7 +423,7 @@ EXTERN int register_blockdriver(const char *path,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN int unregister_driver(const char *path);
|
||||
int unregister_driver(const char *path);
|
||||
|
||||
/* fs_unregisterblockdriver.c ***********************************************/
|
||||
/****************************************************************************
|
||||
@@ -436,7 +434,7 @@ EXTERN int unregister_driver(const char *path);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN int unregister_blockdriver(const char *path);
|
||||
int unregister_blockdriver(const char *path);
|
||||
|
||||
/* fs_open.c ****************************************************************/
|
||||
/****************************************************************************
|
||||
@@ -447,30 +445,19 @@ EXTERN int unregister_blockdriver(const char *path);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN int inode_checkflags(FAR struct inode *inode, int oflags);
|
||||
int inode_checkflags(FAR struct inode *inode, int oflags);
|
||||
|
||||
/* fs_files.c ***************************************************************/
|
||||
/****************************************************************************
|
||||
* Name: files_alloclist
|
||||
*
|
||||
* Description: Allocate a list of files for a new task
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
EXTERN FAR struct filelist *files_alloclist(void);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: files_addreflist
|
||||
* Name: files_initlist
|
||||
*
|
||||
* Description:
|
||||
* Increase the reference count on a file list
|
||||
* Initializes the list of files for a new task
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
EXTERN int files_addreflist(FAR struct filelist *list);
|
||||
void files_initlist(FAR struct filelist *list);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
@@ -482,7 +469,7 @@ EXTERN int files_addreflist(FAR struct filelist *list);
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
EXTERN int files_releaselist(FAR struct filelist *list);
|
||||
void files_releaselist(FAR struct filelist *list);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
@@ -495,7 +482,7 @@ EXTERN int files_releaselist(FAR struct filelist *list);
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
EXTERN int files_dup(FAR struct file *filep1, FAR struct file *filep2);
|
||||
int files_dup(FAR struct file *filep1, FAR struct file *filep2);
|
||||
#endif
|
||||
|
||||
/* fs_filedup.c *************************************************************/
|
||||
@@ -515,7 +502,7 @@ EXTERN int files_dup(FAR struct file *filep1, FAR struct file *filep2);
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
EXTERN int file_dup(int fd, int minfd);
|
||||
int file_dup(int fd, int minfd);
|
||||
#endif
|
||||
|
||||
/* fs_filedup2.c ************************************************************/
|
||||
@@ -535,7 +522,7 @@ EXTERN int file_dup(int fd, int minfd);
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
#if defined(CONFIG_NET) && CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
EXTERN int file_dup2(int fd1, int fd2);
|
||||
int file_dup2(int fd1, int fd2);
|
||||
#else
|
||||
# define file_dup2(fd1, fd2) dup2(fd1, fd2)
|
||||
#endif
|
||||
@@ -566,8 +553,8 @@ EXTERN int file_dup2(int fd1, int fd2);
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
EXTERN int open_blockdriver(FAR const char *pathname, int mountflags,
|
||||
FAR struct inode **ppinode);
|
||||
int open_blockdriver(FAR const char *pathname, int mountflags,
|
||||
FAR struct inode **ppinode);
|
||||
#endif
|
||||
|
||||
/* fs_closeblockdriver.c ****************************************************/
|
||||
@@ -589,7 +576,7 @@ EXTERN int open_blockdriver(FAR const char *pathname, int mountflags,
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
EXTERN int close_blockdriver(FAR struct inode *inode);
|
||||
int close_blockdriver(FAR struct inode *inode);
|
||||
#endif
|
||||
|
||||
/* fs_fdopen.c **************************************************************/
|
||||
@@ -609,7 +596,7 @@ typedef struct _TCB _TCB;
|
||||
#define __TCB_DEFINED__
|
||||
#endif
|
||||
|
||||
EXTERN FAR struct file_struct *fs_fdopen(int fd, int oflags, FAR _TCB *tcb);
|
||||
FAR struct file_struct *fs_fdopen(int fd, int oflags, FAR _TCB *tcb);
|
||||
#endif
|
||||
|
||||
/* lib/stdio/lib_fflush.c **************************************************/
|
||||
@@ -623,7 +610,7 @@ EXTERN FAR struct file_struct *fs_fdopen(int fd, int oflags, FAR _TCB *tcb);
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NFILE_STREAMS > 0
|
||||
EXTERN int lib_flushall(FAR struct streamlist *list);
|
||||
int lib_flushall(FAR struct streamlist *list);
|
||||
#endif
|
||||
|
||||
/* drivers/dev_null.c *******************************************************/
|
||||
@@ -635,7 +622,7 @@ EXTERN int lib_flushall(FAR struct streamlist *list);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN void devnull_register(void);
|
||||
void devnull_register(void);
|
||||
|
||||
/* drivers/dev_zero.c *******************************************************/
|
||||
/****************************************************************************
|
||||
@@ -646,7 +633,7 @@ EXTERN void devnull_register(void);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN void devzero_register(void);
|
||||
void devzero_register(void);
|
||||
|
||||
/* drivers/loop.c ***********************************************************/
|
||||
/****************************************************************************
|
||||
@@ -658,8 +645,8 @@ EXTERN void devzero_register(void);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN int losetup(FAR const char *devname, FAR const char *filename,
|
||||
uint16_t sectsize, off_t offset, bool readonly);
|
||||
int losetup(FAR const char *devname, FAR const char *filename,
|
||||
uint16_t sectsize, off_t offset, bool readonly);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: loteardown
|
||||
@@ -669,7 +656,7 @@ EXTERN int losetup(FAR const char *devname, FAR const char *filename,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN int loteardown(FAR const char *devname);
|
||||
int loteardown(FAR const char *devname);
|
||||
|
||||
/* drivers/bch/bchdev_register.c ********************************************/
|
||||
/****************************************************************************
|
||||
@@ -681,8 +668,8 @@ EXTERN int loteardown(FAR const char *devname);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN int bchdev_register(FAR const char *blkdev, FAR const char *chardev,
|
||||
bool readonly);
|
||||
int bchdev_register(FAR const char *blkdev, FAR const char *chardev,
|
||||
bool readonly);
|
||||
|
||||
/* drivers/bch/bchdev_unregister.c ******************************************/
|
||||
/****************************************************************************
|
||||
@@ -694,7 +681,7 @@ EXTERN int bchdev_register(FAR const char *blkdev, FAR const char *chardev,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN int bchdev_unregister(FAR const char *chardev);
|
||||
int bchdev_unregister(FAR const char *chardev);
|
||||
|
||||
/* Low level, direct access. NOTE: low-level access and character driver access
|
||||
* are incompatible. One and only one access method should be implemented.
|
||||
@@ -710,8 +697,7 @@ EXTERN int bchdev_unregister(FAR const char *chardev);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN int bchlib_setup(FAR const char *blkdev, bool readonly,
|
||||
FAR void **handle);
|
||||
int bchlib_setup(FAR const char *blkdev, bool readonly, FAR void **handle);
|
||||
|
||||
/* drivers/bch/bchlib_teardown.c ********************************************/
|
||||
/****************************************************************************
|
||||
@@ -723,7 +709,7 @@ EXTERN int bchlib_setup(FAR const char *blkdev, bool readonly,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN int bchlib_teardown(FAR void *handle);
|
||||
int bchlib_teardown(FAR void *handle);
|
||||
|
||||
/* drivers/bch/bchlib_read.c ************************************************/
|
||||
/****************************************************************************
|
||||
@@ -735,8 +721,8 @@ EXTERN int bchlib_teardown(FAR void *handle);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN ssize_t bchlib_read(FAR void *handle, FAR char *buffer, size_t offset,
|
||||
size_t len);
|
||||
ssize_t bchlib_read(FAR void *handle, FAR char *buffer, size_t offset,
|
||||
size_t len);
|
||||
|
||||
/* drivers/bch/bchlib_write.c ***********************************************/
|
||||
/****************************************************************************
|
||||
@@ -748,8 +734,8 @@ EXTERN ssize_t bchlib_read(FAR void *handle, FAR char *buffer, size_t offset,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN ssize_t bchlib_write(FAR void *handle, FAR const char *buffer,
|
||||
size_t offset, size_t len);
|
||||
ssize_t bchlib_write(FAR void *handle, FAR const char *buffer, size_t offset,
|
||||
size_t len);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* include/nuttx/lib.h
|
||||
* Non-standard, internal APIs available in lib/.
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2012-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -67,11 +67,10 @@ extern "C" {
|
||||
|
||||
/* Functions contained in lib_init.c ****************************************/
|
||||
|
||||
EXTERN void weak_function lib_initialize(void);
|
||||
void weak_function lib_initialize(void);
|
||||
#if CONFIG_NFILE_STREAMS > 0
|
||||
EXTERN FAR struct streamlist *lib_alloclist(void);
|
||||
EXTERN void lib_addreflist(FAR struct streamlist *list);
|
||||
EXTERN void lib_releaselist(FAR struct streamlist *list);
|
||||
void lib_streaminit(FAR struct streamlist *list);
|
||||
void lib_releaselist(FAR struct streamlist *list);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* include/nuttx/net/net.h
|
||||
*
|
||||
* Copyright (C) 2007, 2009-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -106,7 +106,6 @@ struct socket
|
||||
struct socketlist
|
||||
{
|
||||
sem_t sl_sem; /* Manage access to the socket list */
|
||||
int16_t sl_crefs; /* Reference count */
|
||||
struct socket sl_sockets[CONFIG_NSOCKET_DESCRIPTORS];
|
||||
};
|
||||
#endif
|
||||
@@ -117,110 +116,114 @@ struct uip_driver_s; /* Forward reference. See nuttx/net/uip/uip-arch.h */
|
||||
typedef int (*netdev_callback_t)(FAR struct uip_driver_s *dev, void *arg);
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* net_checksd.c *************************************************************/
|
||||
/* Check if the socket descriptor is valid for the provided TCB and if it
|
||||
* supports the requested access.
|
||||
*/
|
||||
|
||||
EXTERN int net_checksd(int fd, int oflags);
|
||||
int net_checksd(int fd, int oflags);
|
||||
|
||||
/* net_sockets.c *************************************************************/
|
||||
/* There interfaces are called only from OS scheduling and iniialization logic
|
||||
* under sched/
|
||||
*/
|
||||
|
||||
EXTERN void weak_function net_initialize(void);
|
||||
EXTERN FAR struct socketlist *net_alloclist(void);
|
||||
EXTERN int net_addreflist(FAR struct socketlist *list);
|
||||
EXTERN int net_releaselist(FAR struct socketlist *list);
|
||||
void weak_function net_initialize(void);
|
||||
void net_initlist(FAR struct socketlist *list);
|
||||
void net_releaselist(FAR struct socketlist *list);
|
||||
|
||||
/* Given a socket descriptor, return the underly NuttX-specific socket
|
||||
* structure.
|
||||
*/
|
||||
|
||||
EXTERN FAR struct socket *sockfd_socket(int sockfd);
|
||||
FAR struct socket *sockfd_socket(int sockfd);
|
||||
|
||||
/* socket.c ******************************************************************/
|
||||
/* socket using underlying socket structure */
|
||||
|
||||
EXTERN int psock_socket(int domain, int type, int protocol,
|
||||
FAR struct socket *psock);
|
||||
int psock_socket(int domain, int type, int protocol, FAR struct socket *psock);
|
||||
|
||||
/* net_close.c ***************************************************************/
|
||||
/* The standard close() operation redirects operations on socket descriptors
|
||||
* to this function.
|
||||
*/
|
||||
|
||||
EXTERN int net_close(int sockfd);
|
||||
int net_close(int sockfd);
|
||||
|
||||
/* Performs the close operation on a socket instance */
|
||||
|
||||
EXTERN int psock_close(FAR struct socket *psock);
|
||||
int psock_close(FAR struct socket *psock);
|
||||
|
||||
/* net_close.c ***************************************************************/
|
||||
/* Performs the bind() operation on a socket instance */
|
||||
|
||||
EXTERN int psock_bind(FAR struct socket *psock,
|
||||
FAR const struct sockaddr *addr, socklen_t addrlen);
|
||||
int psock_bind(FAR struct socket *psock, FAR const struct sockaddr *addr,
|
||||
socklen_t addrlen);
|
||||
|
||||
/* connect.c *****************************************************************/
|
||||
/* Performs the connect() operation on a socket instance */
|
||||
|
||||
EXTERN int psock_connect(FAR struct socket *psock,
|
||||
FAR const struct sockaddr *addr, socklen_t addrlen);
|
||||
int psock_connect(FAR struct socket *psock, FAR const struct sockaddr *addr,
|
||||
socklen_t addrlen);
|
||||
|
||||
/* send.c ********************************************************************/
|
||||
/* Send using underlying socket structure */
|
||||
|
||||
EXTERN ssize_t psock_send(FAR struct socket *psock, const void *buf,
|
||||
size_t len, int flags);
|
||||
ssize_t psock_send(FAR struct socket *psock, const void *buf, size_t len,
|
||||
int flags);
|
||||
|
||||
/* sendto.c ******************************************************************/
|
||||
/* Sendto using underlying socket structure */
|
||||
|
||||
EXTERN ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
|
||||
size_t len, int flags, FAR const struct sockaddr *to,
|
||||
socklen_t tolen);
|
||||
ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
|
||||
size_t len, int flags, FAR const struct sockaddr *to,
|
||||
socklen_t tolen);
|
||||
|
||||
/* recvfrom.c ****************************************************************/
|
||||
/* recvfrom using the underlying socket structure */
|
||||
|
||||
EXTERN ssize_t psock_recvfrom(FAR struct socket *psock, FAR void *buf,
|
||||
size_t len, int flags,FAR struct sockaddr *from,
|
||||
FAR socklen_t *fromlen);
|
||||
ssize_t psock_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
||||
int flags,FAR struct sockaddr *from,
|
||||
FAR socklen_t *fromlen);
|
||||
|
||||
/* recv using the underlying socket structure */
|
||||
|
||||
#define psock_recv(psock,buf,len,flags) psock_recvfrom(psock,buf,len,flags,NULL,0)
|
||||
#define psock_recv(psock,buf,len,flags) \
|
||||
psock_recvfrom(psock,buf,len,flags,NULL,0)
|
||||
|
||||
/* getsockopt.c **************************************************************/
|
||||
/* getsockopt using the underlying socket structure */
|
||||
|
||||
EXTERN int psock_getsockopt(FAR struct socket *psock, int level, int option,
|
||||
FAR void *value, FAR socklen_t *value_len);
|
||||
int psock_getsockopt(FAR struct socket *psock, int level, int option,
|
||||
FAR void *value, FAR socklen_t *value_len);
|
||||
|
||||
/* setsockopt.c **************************************************************/
|
||||
/* setsockopt using the underlying socket structure */
|
||||
|
||||
EXTERN int psock_setsockopt(FAR struct socket *psock, int level, int option,
|
||||
FAR const void *value, socklen_t value_len);
|
||||
int psock_setsockopt(FAR struct socket *psock, int level, int option,
|
||||
FAR const void *value, socklen_t value_len);
|
||||
|
||||
/* net_ioctl.c ***************************************************************/
|
||||
/* The standard ioctl() operation redirects operations on socket descriptors
|
||||
* to this function.
|
||||
*/
|
||||
|
||||
EXTERN int netdev_ioctl(int sockfd, int cmd, unsigned long arg);
|
||||
int netdev_ioctl(int sockfd, int cmd, unsigned long arg);
|
||||
|
||||
/* net_poll.c ****************************************************************/
|
||||
/* The standard poll() operation redirects operations on socket descriptors
|
||||
@@ -229,7 +232,9 @@ EXTERN int netdev_ioctl(int sockfd, int cmd, unsigned long arg);
|
||||
|
||||
#ifndef CONFIG_DISABLE_POLL
|
||||
struct pollfd; /* Forward reference -- see poll.h */
|
||||
EXTERN int net_poll(int sockfd, struct pollfd *fds, bool setup);
|
||||
|
||||
int psock_poll(FAR struct socket *psock, struct pollfd *fds, bool setup);
|
||||
int net_poll(int sockfd, struct pollfd *fds, bool setup);
|
||||
#endif
|
||||
|
||||
/* net_dup.c *****************************************************************/
|
||||
@@ -237,7 +242,7 @@ EXTERN int net_poll(int sockfd, struct pollfd *fds, bool setup);
|
||||
* this function
|
||||
*/
|
||||
|
||||
EXTERN int net_dup(int sockfd, int minsd);
|
||||
int net_dup(int sockfd, int minsd);
|
||||
|
||||
/* net_dup2.c ****************************************************************/
|
||||
/* The standard dup2() operation redirects operations on socket descriptors to
|
||||
@@ -245,7 +250,7 @@ EXTERN int net_dup(int sockfd, int minsd);
|
||||
*/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
EXTERN int net_dup2(int sockfd1, int sockfd2);
|
||||
int net_dup2(int sockfd1, int sockfd2);
|
||||
#else
|
||||
# define net_dup2(sockfd1, sockfd2) dup2(sockfd1, sockfd2)
|
||||
#endif
|
||||
@@ -253,12 +258,12 @@ EXTERN int net_dup2(int sockfd1, int sockfd2);
|
||||
/* net_clone.c ***************************************************************/
|
||||
/* Performs the low level, common portion of net_dup() and net_dup2() */
|
||||
|
||||
EXTERN int net_clone(FAR struct socket *psock1, FAR struct socket *psock2);
|
||||
int net_clone(FAR struct socket *psock1, FAR struct socket *psock2);
|
||||
|
||||
/* net_vfcntl.c **************************************************************/
|
||||
/* Performs fcntl operations on socket */
|
||||
|
||||
EXTERN int net_vfcntl(int sockfd, int cmd, va_list ap);
|
||||
int net_vfcntl(int sockfd, int cmd, va_list ap);
|
||||
|
||||
/* netdev-register.c *********************************************************/
|
||||
/* This function is called by network interface device drivers to inform the
|
||||
@@ -267,23 +272,23 @@ EXTERN int net_vfcntl(int sockfd, int cmd, va_list ap);
|
||||
* addresses
|
||||
*/
|
||||
|
||||
EXTERN int netdev_register(FAR struct uip_driver_s *dev);
|
||||
int netdev_register(FAR struct uip_driver_s *dev);
|
||||
|
||||
/* netdev-unregister.c *********************************************************/
|
||||
/* Unregister a network device driver. */
|
||||
|
||||
EXTERN int netdev_unregister(FAR struct uip_driver_s *dev);
|
||||
int netdev_unregister(FAR struct uip_driver_s *dev);
|
||||
|
||||
/* net_foreach.c ************************************************************/
|
||||
/* Enumerates all registered network devices */
|
||||
|
||||
EXTERN int netdev_foreach(netdev_callback_t callback, void *arg);
|
||||
int netdev_foreach(netdev_callback_t callback, void *arg);
|
||||
|
||||
/* drivers/net/slip.c ******************************************************/
|
||||
/* Instantiate a SLIP network interface. */
|
||||
|
||||
#ifdef CONFIG_NET_SLIP
|
||||
EXTERN int slip_initialize(int intf, const char *devname);
|
||||
int slip_initialize(int intf, const char *devname);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
|
||||
+157
-42
@@ -52,19 +52,55 @@
|
||||
#include <time.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/net/net.h>
|
||||
|
||||
/********************************************************************************
|
||||
* Pre-processor Definitions
|
||||
********************************************************************************/
|
||||
/* Configuration ****************************************************************/
|
||||
/* Task groups currently only supported for retention of child status */
|
||||
|
||||
/* Task Management Definitins ***************************************************/
|
||||
#undef HAVE_TASK_GROUP
|
||||
#undef HAVE_GROUP_MEMBERS
|
||||
|
||||
/* We need a group an group members if we are supportint the parent/child
|
||||
* relationship.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS)
|
||||
# define HAVE_TASK_GROUP 1
|
||||
# define HAVE_GROUP_MEMBERS 1
|
||||
|
||||
/* We need a group (but not members) if any other resources are shared within
|
||||
* a task group.
|
||||
*/
|
||||
|
||||
#else
|
||||
# if !defined(CONFIG_DISABLE_ENVIRON)
|
||||
# define HAVE_TASK_GROUP 1
|
||||
# elif CONFIG_NFILE_DESCRIPTORS > 0
|
||||
# define HAVE_TASK_GROUP 1
|
||||
# elif CONFIG_NFILE_STREAMS > 0
|
||||
# define HAVE_TASK_GROUP 1
|
||||
# elif CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
# define HAVE_TASK_GROUP 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* In any event, we don't need group members if support for pthreads is disabled */
|
||||
|
||||
#ifdef CONFIG_DISABLE_PTHREAD
|
||||
# undef HAVE_GROUP_MEMBERS
|
||||
#endif
|
||||
|
||||
/* Task Management Definitions **************************************************/
|
||||
|
||||
/* This is the maximum number of times that a lock can be set */
|
||||
|
||||
#define MAX_LOCK_COUNT 127
|
||||
|
||||
/* Values for the _TCB flags flag bits */
|
||||
/* Values for the _TCB flags bits */
|
||||
|
||||
#define TCB_FLAG_TTYPE_SHIFT (0) /* Bits 0-1: thread type */
|
||||
#define TCB_FLAG_TTYPE_MASK (3 << TCB_FLAG_TTYPE_SHIFT)
|
||||
@@ -74,7 +110,11 @@
|
||||
#define TCB_FLAG_NONCANCELABLE (1 << 2) /* Bit 2: Pthread is non-cancelable */
|
||||
#define TCB_FLAG_CANCEL_PENDING (1 << 3) /* Bit 3: Pthread cancel is pending */
|
||||
#define TCB_FLAG_ROUND_ROBIN (1 << 4) /* Bit 4: Round robin sched enabled */
|
||||
#define TCB_FLAG_NOCLDWAIT (1 << 5) /* Bit 5: Do not retain child exit status */
|
||||
#define TCB_FLAG_EXIT_PROCESSING (1 << 5) /* Bit 5: Exitting */
|
||||
|
||||
/* Values for struct task_group tg_flags */
|
||||
|
||||
#define GROUP_FLAG_NOCLDWAIT (1 << 0) /* Bit 0: Do not retain child exit status */
|
||||
|
||||
/* Values for struct child_status_s ch_flags */
|
||||
|
||||
@@ -143,7 +183,13 @@ union entry_u
|
||||
};
|
||||
typedef union entry_u entry_t;
|
||||
|
||||
/* These is the types of the functions that are executed with exit() is called
|
||||
/* This is the type of the function called at task startup */
|
||||
|
||||
#ifdef CONFIG_SCHED_STARTHOOK
|
||||
typedef CODE void (*starthook_t)(FAR void *arg);
|
||||
#endif
|
||||
|
||||
/* These are the types of the functions that are executed with exit() is called
|
||||
* (if registered via atexit() on on_exit()).
|
||||
*/
|
||||
|
||||
@@ -159,20 +205,7 @@ typedef CODE void (*onexitfunc_t)(int exitcode, FAR void *arg);
|
||||
|
||||
typedef struct msgq_s msgq_t;
|
||||
|
||||
/* The structure used to maintain environment variables */
|
||||
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
struct environ_s
|
||||
{
|
||||
unsigned int ev_crefs; /* Reference count used when environment
|
||||
* is shared by threads */
|
||||
size_t ev_alloc; /* Number of bytes allocated in environment */
|
||||
char ev_env[1]; /* Environment strings */
|
||||
};
|
||||
typedef struct environ_s environ_t;
|
||||
# define SIZEOF_ENVIRON_T(alloc) (sizeof(environ_t) + alloc - 1)
|
||||
#endif
|
||||
|
||||
/* struct child_status_s *********************************************************/
|
||||
/* This structure is used to maintin information about child tasks.
|
||||
* pthreads work differently, they have join information. This is
|
||||
* only for child tasks.
|
||||
@@ -189,6 +222,7 @@ struct child_status_s
|
||||
};
|
||||
#endif
|
||||
|
||||
/* struct dspace_s ***************************************************************/
|
||||
/* This structure describes a reference counted D-Space region. This must be a
|
||||
* separately allocated "break-away" structure that can be owned by a task and
|
||||
* any pthreads created by the task.
|
||||
@@ -214,6 +248,88 @@ struct dspace_s
|
||||
};
|
||||
#endif
|
||||
|
||||
/* struct task_group_s ***********************************************************/
|
||||
/* All threads created by pthread_create belong in the same task group (along with
|
||||
* the thread of the original task). struct task_group_s is a shared, "breakaway"
|
||||
* structure referenced by each TCB.
|
||||
*
|
||||
* This structure should contain *all* resources shared by tasks and threads that
|
||||
* belong to the same task group:
|
||||
*
|
||||
* Child exit status
|
||||
* Environment varibles
|
||||
* PIC data space and address environments
|
||||
* File descriptors
|
||||
* FILE streams
|
||||
* Sockets
|
||||
*
|
||||
* Currenty, however, this implementation only applies to child exit status.
|
||||
*
|
||||
* Each instance of struct task_group_s is reference counted. Each instance is
|
||||
* created with a reference count of one. The reference incremeneted when each
|
||||
* thread joins the group and decremented when each thread exits, leaving the
|
||||
* group. When the refernce count decrements to zero, the struc task_group_s
|
||||
* is free.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_TASK_GROUP
|
||||
struct task_group_s
|
||||
{
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
struct task_group_s *flink; /* Supports a singly linked list */
|
||||
gid_t tg_gid; /* The ID of this task group */
|
||||
gid_t tg_pgid; /* The ID of the parent task group */
|
||||
#endif
|
||||
uint8_t tg_flags; /* See GROUP_FLAG_* definitions */
|
||||
|
||||
/* Group membership ***********************************************************/
|
||||
|
||||
uint8_t tg_nmembers; /* Number of members in the group */
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
uint8_t tg_mxmembers; /* Number of members in allocation */
|
||||
FAR pid_t *tg_members; /* Members of the group */
|
||||
#endif
|
||||
|
||||
/* Child exit status **********************************************************/
|
||||
|
||||
#if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS)
|
||||
FAR struct child_status_s *tg_children; /* Head of a list of child status */
|
||||
#endif
|
||||
|
||||
/* Environment variables ******************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
size_t tg_envsize; /* Size of environment string allocation */
|
||||
FAR char *tg_envp; /* Allocated environment strings */
|
||||
#endif
|
||||
|
||||
/* PIC data space and address environments ************************************/
|
||||
/* Logically the PIC data space belongs here (see struct dspace_s). The
|
||||
* current logic needs review: There are differences in the away that the
|
||||
* life of the PIC data is managed.
|
||||
*/
|
||||
|
||||
/* File descriptors ***********************************************************/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
struct filelist tg_filelist; /* Maps file descriptor to file */
|
||||
#endif
|
||||
|
||||
/* FILE streams ***************************************************************/
|
||||
|
||||
#if CONFIG_NFILE_STREAMS > 0
|
||||
struct streamlist tg_streamlist; /* Holds C buffered I/O info */
|
||||
#endif /* CONFIG_NFILE_STREAMS */
|
||||
|
||||
/* Sockets ********************************************************************/
|
||||
|
||||
#if CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
struct socketlist tg_socketlist; /* Maps socket descriptor to socket */
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
/* _TCB **************************************************************************/
|
||||
/* This is the task control block (TCB). Each task or thread is represented by
|
||||
* a TCB. The TCB is the heart of the NuttX task-control logic.
|
||||
*/
|
||||
@@ -225,20 +341,33 @@ struct _TCB
|
||||
FAR struct _TCB *flink; /* Doubly linked list */
|
||||
FAR struct _TCB *blink;
|
||||
|
||||
/* Task Group *****************************************************************/
|
||||
|
||||
#ifdef HAVE_TASK_GROUP
|
||||
FAR struct task_group_s *group; /* Pointer to shared task group data */
|
||||
#endif
|
||||
|
||||
/* Task Management Fields *****************************************************/
|
||||
|
||||
pid_t pid; /* This is the ID of the thread */
|
||||
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT /* Support parent-child relationship */
|
||||
pid_t parent; /* This is the ID of the parent thread */
|
||||
#ifdef CONFIG_SCHED_CHILD_STATUS /* Retain child thread status */
|
||||
FAR struct child_status_s *children; /* Head of a list of child status */
|
||||
#else
|
||||
#ifndef HAVE_GROUP_MEMBERS /* Don't know pids of group members */
|
||||
pid_t ppid; /* This is the ID of the parent thread */
|
||||
#ifndef CONFIG_SCHED_CHILD_STATUS /* Retain child thread status */
|
||||
uint16_t nchildren; /* This is the number active children */
|
||||
#endif
|
||||
#endif
|
||||
#endif /* CONFIG_SCHED_HAVE_PARENT */
|
||||
|
||||
start_t start; /* Thread start function */
|
||||
entry_t entry; /* Entry Point into the thread */
|
||||
|
||||
#ifdef CONFIG_SCHED_STARTHOOK
|
||||
starthook_t starthook; /* Task startup function */
|
||||
FAR void *starthookarg; /* The argument passed to the function */
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SCHED_ATEXIT) && !defined(CONFIG_SCHED_ONEXIT)
|
||||
# if defined(CONFIG_SCHED_ATEXIT_MAX) && CONFIG_SCHED_ATEXIT_MAX > 1
|
||||
atexitfunc_t atexitfunc[CONFIG_SCHED_ATEXIT_MAX];
|
||||
@@ -289,10 +418,6 @@ struct _TCB
|
||||
uint8_t init_priority; /* Initial priority of the task */
|
||||
char *argv[CONFIG_MAX_TASK_ARGS+1]; /* Name+start-up parameters */
|
||||
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
FAR environ_t *envp; /* Environment variables */
|
||||
#endif
|
||||
|
||||
/* Stack-Related Fields *******************************************************/
|
||||
|
||||
#ifndef CONFIG_CUSTOM_STACK
|
||||
@@ -344,22 +469,6 @@ struct _TCB
|
||||
|
||||
int pterrno; /* Current per-thread errno */
|
||||
|
||||
/* File system support ********************************************************/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
FAR struct filelist *filelist; /* Maps file descriptor to file */
|
||||
#endif
|
||||
|
||||
#if CONFIG_NFILE_STREAMS > 0
|
||||
FAR struct streamlist *streams; /* Holds C buffered I/O info */
|
||||
#endif
|
||||
|
||||
/* Network socket *************************************************************/
|
||||
|
||||
#if CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
FAR struct socketlist *sockets; /* Maps file descriptor to file */
|
||||
#endif
|
||||
|
||||
/* State save areas ***********************************************************/
|
||||
/* The form and content of these fields are processor-specific. */
|
||||
|
||||
@@ -421,6 +530,12 @@ FAR struct streamlist *sched_getstreams(void);
|
||||
FAR struct socketlist *sched_getsockets(void);
|
||||
#endif /* CONFIG_NSOCKET_DESCRIPTORS */
|
||||
|
||||
/* Setup up a start hook */
|
||||
|
||||
#ifdef CONFIG_SCHED_STARTHOOK
|
||||
void task_starthook(FAR _TCB *tcb, starthook_t starthook, FAR void *arg);
|
||||
#endif
|
||||
|
||||
/* Internal vfork support.The overall sequence is:
|
||||
*
|
||||
* 1) User code calls vfork(). vfork() is provided in architecture-specific
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/************************************************************************************
|
||||
* include/nuttx/serial/serial.h
|
||||
*
|
||||
* Copyright (C) 2007-2008, 2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2008, 2012-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -49,6 +49,7 @@
|
||||
#ifdef CONFIG_SERIAL_TERMIOS
|
||||
# include <termios.h>
|
||||
#endif
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
/************************************************************************************
|
||||
@@ -193,20 +194,23 @@ struct uart_ops_s
|
||||
|
||||
struct uart_dev_s
|
||||
{
|
||||
uint8_t open_count; /* Number of times the device has been opened */
|
||||
volatile bool xmitwaiting; /* true: User waiting for space in xmit.buffer */
|
||||
volatile bool recvwaiting; /* true: User waiting for data in recv.buffer */
|
||||
bool isconsole; /* true: This is the serial console */
|
||||
sem_t closesem; /* Locks out new open while close is in progress */
|
||||
sem_t xmitsem; /* Wakeup user waiting for space in xmit.buffer */
|
||||
sem_t recvsem; /* Wakeup user waiting for data in recv.buffer */
|
||||
#ifndef CONFIG_DISABLE_POLL
|
||||
sem_t pollsem; /* Manages exclusive access to fds[] */
|
||||
uint8_t open_count; /* Number of times the device has been opened */
|
||||
volatile bool xmitwaiting; /* true: User waiting for space in xmit.buffer */
|
||||
volatile bool recvwaiting; /* true: User waiting for data in recv.buffer */
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
volatile bool disconnected; /* true: Removable device is not connected */
|
||||
#endif
|
||||
struct uart_buffer_s xmit; /* Describes transmit buffer */
|
||||
struct uart_buffer_s recv; /* Describes receive buffer */
|
||||
FAR const struct uart_ops_s *ops; /* Arch-specific operations */
|
||||
FAR void *priv; /* Used by the arch-specific logic */
|
||||
bool isconsole; /* true: This is the serial console */
|
||||
sem_t closesem; /* Locks out new open while close is in progress */
|
||||
sem_t xmitsem; /* Wakeup user waiting for space in xmit.buffer */
|
||||
sem_t recvsem; /* Wakeup user waiting for data in recv.buffer */
|
||||
#ifndef CONFIG_DISABLE_POLL
|
||||
sem_t pollsem; /* Manages exclusive access to fds[] */
|
||||
#endif
|
||||
struct uart_buffer_s xmit; /* Describes transmit buffer */
|
||||
struct uart_buffer_s recv; /* Describes receive buffer */
|
||||
FAR const struct uart_ops_s *ops; /* Arch-specific operations */
|
||||
FAR void *priv; /* Used by the arch-specific logic */
|
||||
|
||||
/* The following is a list if poll structures of threads waiting for
|
||||
* driver events. The 'struct pollfd' reference for each open is also
|
||||
@@ -226,24 +230,26 @@ struct uart_dev_s
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
typedef struct uart_dev_s uart_dev_t;
|
||||
|
||||
/************************************************************************************
|
||||
* Public Data
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: uart_register
|
||||
*
|
||||
@@ -252,7 +258,7 @@ extern "C" {
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
EXTERN int uart_register(FAR const char *path, FAR uart_dev_t *dev);
|
||||
int uart_register(FAR const char *path, FAR uart_dev_t *dev);
|
||||
|
||||
/************************************************************************************
|
||||
* Name: uart_xmitchars
|
||||
@@ -265,7 +271,7 @@ EXTERN int uart_register(FAR const char *path, FAR uart_dev_t *dev);
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
EXTERN void uart_xmitchars(FAR uart_dev_t *dev);
|
||||
void uart_xmitchars(FAR uart_dev_t *dev);
|
||||
|
||||
/************************************************************************************
|
||||
* Name: uart_receivechars
|
||||
@@ -278,7 +284,7 @@ EXTERN void uart_xmitchars(FAR uart_dev_t *dev);
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
EXTERN void uart_recvchars(FAR uart_dev_t *dev);
|
||||
void uart_recvchars(FAR uart_dev_t *dev);
|
||||
|
||||
/************************************************************************************
|
||||
* Name: uart_datareceived
|
||||
@@ -290,7 +296,7 @@ EXTERN void uart_recvchars(FAR uart_dev_t *dev);
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
EXTERN void uart_datareceived(FAR uart_dev_t *dev);
|
||||
void uart_datareceived(FAR uart_dev_t *dev);
|
||||
|
||||
/************************************************************************************
|
||||
* Name: uart_datasent
|
||||
@@ -303,7 +309,31 @@ EXTERN void uart_datareceived(FAR uart_dev_t *dev);
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
EXTERN void uart_datasent(FAR uart_dev_t *dev);
|
||||
void uart_datasent(FAR uart_dev_t *dev);
|
||||
|
||||
/************************************************************************************
|
||||
* Name: uart_connected
|
||||
*
|
||||
* Description:
|
||||
* Serial devices (like USB serial) can be removed. In that case, the "upper
|
||||
* half" serial driver must be informed that there is no longer a valid serial
|
||||
* channel associated with the driver.
|
||||
*
|
||||
* In this case, the driver will terminate all pending transfers wint ENOTCONN and
|
||||
* will refuse all further transactions while the "lower half" is disconnected.
|
||||
* The driver will continue to be registered, but will be in an unusable state.
|
||||
*
|
||||
* Conversely, the "upper half" serial driver needs to know when the serial
|
||||
* device is reconnected so that it can resume normal operations.
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* This function may be called from an interrupt handler.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SERIAL_REMOVABLE
|
||||
void uart_connected(FAR uart_dev_t *dev, bool connected);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
|
||||
@@ -116,10 +116,10 @@ EXTERN int syslog_initialize(void);
|
||||
*
|
||||
* Description:
|
||||
* This is the low-level system logging interface. The debugging/syslogging
|
||||
* interfaces are lib_rawprintf() and lib_lowprinf(). The difference is
|
||||
* the lib_rawprintf() writes to fd=1 (stdout) and lib_lowprintf() uses
|
||||
* interfaces are syslog() and lowsyslog(). The difference is that
|
||||
* the syslog() internface writes to fd=1 (stdout) whereas lowsyslog() uses
|
||||
* a lower level interface that works from interrupt handlers. This
|
||||
* function is a a low-level interface used to implement lib_lowprintf().
|
||||
* function is a a low-level interface used to implement lowsyslog().
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
* Endpoint 0 max packet size. Default 64.
|
||||
* CONFIG_CDCACM_EPINTIN
|
||||
* The logical 7-bit address of a hardware endpoint that supports
|
||||
* interrupt IN operation. Default 2.
|
||||
* interrupt IN operation. Default 1.
|
||||
* CONFIG_CDCACM_EPINTIN_FSSIZE
|
||||
* Max package size for the interrupt IN endpoint if full speed mode.
|
||||
* Default 64.
|
||||
@@ -63,7 +63,7 @@
|
||||
* Default 64.
|
||||
* CONFIG_CDCACM_EPBULKOUT
|
||||
* The logical 7-bit address of a hardware endpoint that supports
|
||||
* bulk OUT operation
|
||||
* bulk OUT operation. Default: 3
|
||||
* CONFIG_CDCACM_EPBULKOUT_FSSIZE
|
||||
* Max package size for the bulk OUT endpoint if full speed mode.
|
||||
* Default 64.
|
||||
@@ -72,7 +72,7 @@
|
||||
* Default 512.
|
||||
* CONFIG_CDCACM_EPBULKIN
|
||||
* The logical 7-bit address of a hardware endpoint that supports
|
||||
* bulk IN operation
|
||||
* bulk IN operation. Default: 2
|
||||
* CONFIG_CDCACM_EPBULKIN_FSSIZE
|
||||
* Max package size for the bulk IN endpoint if full speed mode.
|
||||
* Default 64.
|
||||
@@ -107,7 +107,7 @@
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_CDCACM_EPINTIN
|
||||
# define CONFIG_CDCACM_EPINTIN 2
|
||||
# define CONFIG_CDCACM_EPINTIN 1
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_CDCACM_EPINTIN_FSSIZE
|
||||
@@ -124,7 +124,7 @@
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_CDCACM_EPBULKIN
|
||||
# define CONFIG_CDCACM_EPBULKIN 3
|
||||
# define CONFIG_CDCACM_EPBULKIN 2
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_CDCACM_EPBULKIN_FSSIZE
|
||||
@@ -141,7 +141,7 @@
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_CDCACM_EPBULKOUT
|
||||
# define CONFIG_CDCACM_EPBULKOUT 4
|
||||
# define CONFIG_CDCACM_EPBULKOUT 3
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_CDCACM_EPBULKOUT_FSSIZE
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
#define TRACE_DEVUNINIT TRACE_EVENT(TRACE_INIT_ID, 0x0002)
|
||||
#define TRACE_DEVREGISTER TRACE_EVENT(TRACE_INIT_ID, 0x0003)
|
||||
#define TRACE_DEVUNREGISTER TRACE_EVENT(TRACE_INIT_ID, 0x0004)
|
||||
#define TRACE_DEVINIT_USER TRACE_EVENT(TRACE_INIT_ID, 0x0005) /* First user-defined */
|
||||
|
||||
/* API calls (see usbdev.h) */
|
||||
|
||||
@@ -117,6 +118,7 @@
|
||||
#define TRACE_EPCANCEL TRACE_EVENT(TRACE_EP_ID, 0x0008)
|
||||
#define TRACE_EPSTALL TRACE_EVENT(TRACE_EP_ID, 0x0009)
|
||||
#define TRACE_EPRESUME TRACE_EVENT(TRACE_EP_ID, 0x000a)
|
||||
#define TRACE_EPAPI_USER TRACE_EVENT(TRACE_EP_ID, 0x000b) /* First user-defined */
|
||||
|
||||
#define TRACE_DEVALLOCEP TRACE_EVENT(TRACE_DEV_ID, 0x0001)
|
||||
#define TRACE_DEVFREEEP TRACE_EVENT(TRACE_DEV_ID, 0x0002)
|
||||
@@ -124,6 +126,7 @@
|
||||
#define TRACE_DEVWAKEUP TRACE_EVENT(TRACE_DEV_ID, 0x0004)
|
||||
#define TRACE_DEVSELFPOWERED TRACE_EVENT(TRACE_DEV_ID, 0x0005)
|
||||
#define TRACE_DEVPULLUP TRACE_EVENT(TRACE_DEV_ID, 0x0006)
|
||||
#define TRACE_DEVAPI_USER TRACE_EVENT(TRACE_DEV_ID, 0x0007) /* First user-defined */
|
||||
|
||||
#define TRACE_CLASSBIND TRACE_EVENT(TRACE_CLASS_ID, 0x0001)
|
||||
#define TRACE_CLASSUNBIND TRACE_EVENT(TRACE_CLASS_ID, 0x0002)
|
||||
@@ -135,6 +138,8 @@
|
||||
#define TRACE_CLASSRDCOMPLETE TRACE_EVENT(TRACE_CLASS_ID, 0x0007)
|
||||
#define TRACE_CLASSWRCOMPLETE TRACE_EVENT(TRACE_CLASS_ID, 0x0008)
|
||||
|
||||
#define TRACE_CLASSAPI_USER TRACE_EVENT(TRACE_CLASS_ID, 0x0009) /* First user-defined */
|
||||
|
||||
#define TRACE_CLASSAPI(id) TRACE_EVENT(TRACE_CLASSAPI_ID, id)
|
||||
|
||||
#define TRACE_CLASSSTATE(id) TRACE_EVENT(TRACE_CLASSSTATE_ID, id)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* eched/env_dupenv.c
|
||||
* include/syslog.h
|
||||
*
|
||||
* Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -33,80 +33,62 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_SYSLOG_H
|
||||
#define __INCLUDE_SYSLOG_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
||||
#include "os_internal.h"
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
* Public Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: dupenv
|
||||
*
|
||||
* Description:
|
||||
* Copy the internal environment structure of a task. This is the action
|
||||
* that is performed when a new task is created: The new task has a private,
|
||||
* exact duplicate of the parent task's environment.
|
||||
*
|
||||
* Parameters:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* A pointer to a newly allocated copy of the specified TCB's environment
|
||||
* structure with reference count equal to one.
|
||||
*
|
||||
* Assumptions:
|
||||
* Not called from an interrupt handler.
|
||||
*
|
||||
* Public Variables
|
||||
****************************************************************************/
|
||||
|
||||
FAR environ_t *dupenv(FAR _TCB *ptcb)
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
environ_t *envp = NULL;
|
||||
#endif
|
||||
|
||||
/* Pre-emption must be disabled throughout the following because the
|
||||
* environment may be shared.
|
||||
*/
|
||||
/* These low-level debug APIs are provided by the NuttX library. These are
|
||||
* normally accessed via the macros in debug.h. If the cross-compiler's
|
||||
* C pre-processor supports a variable number of macro arguments, then those
|
||||
* macros below will map all debug statements to one or the other of the
|
||||
* following.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
int syslog(FAR const char *format, ...);
|
||||
int vsyslog(const char *src, va_list ap);
|
||||
|
||||
/* Does the parent task have an environment? */
|
||||
#ifdef CONFIG_ARCH_LOWPUTC
|
||||
int lowsyslog(FAR const char *format, ...);
|
||||
int lowvsyslog(const char *src, va_list ap);
|
||||
#endif
|
||||
|
||||
if (ptcb->envp)
|
||||
{
|
||||
/* Yes..The parent task has an environment, duplicate it */
|
||||
/* Enable or disable syslog output */
|
||||
|
||||
size_t envlen = ptcb->envp->ev_alloc
|
||||
envp = (environ_t*)kmalloc(SIZEOF_ENVIRON_T( envlen ));
|
||||
if (envp)
|
||||
{
|
||||
envp->ev_crefs = 1;
|
||||
envp->ev_alloc = envlen;
|
||||
memcmp( envp->ev_env, ptcb->envp->ev_env, envlen );
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_SYSLOG_ENABLE
|
||||
void syslog_enable(bool enable);
|
||||
#endif
|
||||
|
||||
sched_unlock();
|
||||
return envp;
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_DISABLE_ENVIRON */
|
||||
|
||||
|
||||
|
||||
#endif /* __INCLUDE_SYSLOG_H */
|
||||
+3
-3
@@ -16,7 +16,6 @@
|
||||
"crc32","crc32.h","","uint32_t","FAR const uint8_t *","size_t"
|
||||
"crc32part","crc32.h","","uint32_t","FAR const uint8_t *","size_t","uint32_t"
|
||||
"dbg","debug.h","!defined(CONFIG_CPP_HAVE_VARARGS) && defined(CONFIG_DEBUG)","int","const char *","..."
|
||||
"dbg_enable","debug.h","defined(CONFIG_DEBUG_ENABLE)","void","bool"
|
||||
"dirname","libgen.h","","FAR char","FAR char *"
|
||||
"dq_addafter","queue.h","","void","FAR dq_entry_t *","FAR dq_entry_t *","FAR dq_queue_t *"
|
||||
"dq_addbefore","queue.h","","void","FAR dq_entry_t *","FAR dq_entry_t *","FAR dq_queue_t *"
|
||||
@@ -59,11 +58,10 @@
|
||||
"inet_pton","arpa/inet.h","","int","int","FAR const char *","FAR void *"
|
||||
"labs","stdlib.h","","long int","long int"
|
||||
"lib_dumpbuffer","debug.h","","void","FAR const char *","FAR const uint8_t *","unsigned int"
|
||||
"lib_lowprintf","debug.h","","int","FAR const char *","..."
|
||||
"lib_rawprintf","debug.h","","int","FAR const char *","..."
|
||||
"llabs","stdlib.h","defined(CONFIG_HAVE_LONG_LONG)","long long int","long long int"
|
||||
"lldbg","debug.h","!defined(CONFIG_CPP_HAVE_VARARGS) && defined(CONFIG_DEBUG) && defined(CONFIG_ARCH_LOWPUTC)","int","const char *","..."
|
||||
"llvdbg","debug.h","!defined(CONFIG_CPP_HAVE_VARARGS) && defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_VERBOSE) && defined(CONFIG_ARCH_LOWPUTC)","int","const char *","..."
|
||||
"lowsyslog","syslog.h","","int","FAR const char *","..."
|
||||
"match","","","int","const char *","const char *"
|
||||
"memccpy","string.h","","FAR void","FAR void *","FAR const void *","int c","size_t"
|
||||
"memchr","string.h","","FAR void","FAR const void *","int c","size_t"
|
||||
@@ -154,6 +152,8 @@
|
||||
"strtoll","stdlib.h","defined(CONFIG_HAVE_LONG_LONG)","long long","const char *nptr","char **endptr","int base"
|
||||
"strtoul","stdlib.h","","unsigned long","const char *","char **","int"
|
||||
"strtoull","stdlib.h","defined(CONFIG_HAVE_LONG_LONG)","unsigned long long","const char *","char **","int"
|
||||
"syslog","syslog.h","","int","FAR const char *","..."
|
||||
"syslog_enable","syslog.h","defined(CONFIG_SYSLOG_ENABLE)","void","bool"
|
||||
"tcflush","termios.h","CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_SERIAL_TERMIOS)","int","int","int"
|
||||
"tcgetattr","termios.h","CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_SERIAL_TERMIOS)","int","int","FAR struct termios *"
|
||||
"tcsetattr","termios.h","CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_SERIAL_TERMIOS)","int","int","int","FAR const struct termios *"
|
||||
|
||||
|
+18
-18
@@ -50,8 +50,8 @@
|
||||
|
||||
/* Debug output is initially disabled */
|
||||
|
||||
#ifdef CONFIG_DEBUG_ENABLE
|
||||
bool g_dbgenable;
|
||||
#ifdef CONFIG_SYSLOG_ENABLE
|
||||
bool g_syslogenable;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
@@ -59,17 +59,17 @@ bool g_dbgenable;
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: dbg_enable
|
||||
* Name: syslog_enable
|
||||
*
|
||||
* Description:
|
||||
* Enable or disable debug output.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_ENABLE
|
||||
void dbg_enable(bool enable)
|
||||
#ifdef CONFIG_SYSLOG_ENABLE
|
||||
void syslog_enable(bool enable)
|
||||
{
|
||||
g_dbgenable = enable;
|
||||
g_syslogenable = enable;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -89,13 +89,13 @@ int dbg(const char *format, ...)
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_DEBUG_ENABLE
|
||||
#ifdef CONFIG_SYSLOG_ENABLE
|
||||
ret = 0;
|
||||
if (g_dbgenable)
|
||||
if (g_syslogenable)
|
||||
#endif
|
||||
{
|
||||
va_start(ap, format);
|
||||
ret = lib_rawvprintf(format, ap);
|
||||
ret = vsyslog(format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
@@ -108,13 +108,13 @@ int lldbg(const char *format, ...)
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_DEBUG_ENABLE
|
||||
#ifdef CONFIG_SYSLOG_ENABLE
|
||||
ret = 0;
|
||||
if (g_dbgenable)
|
||||
if (g_syslogenable)
|
||||
#endif
|
||||
{
|
||||
va_start(ap, format);
|
||||
ret = lib_lowvprintf(format, ap);
|
||||
ret = lowvsyslog(format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
@@ -128,13 +128,13 @@ int vdbg(const char *format, ...)
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_DEBUG_ENABLE
|
||||
#ifdef CONFIG_SYSLOG_ENABLE
|
||||
ret = 0;
|
||||
if (g_dbgenable)
|
||||
if (g_syslogenable)
|
||||
#endif
|
||||
{
|
||||
va_start(ap, format);
|
||||
ret = lib_rawvprintf(format, ap);
|
||||
ret = vsyslog(format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
@@ -147,13 +147,13 @@ int llvdbg(const char *format, ...)
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_DEBUG_ENABLE
|
||||
#ifdef CONFIG_SYSLOG_ENABLE
|
||||
ret = 0;
|
||||
if (g_dbgenable)
|
||||
if (g_syslogenable)
|
||||
#endif
|
||||
{
|
||||
va_start(ap, format);
|
||||
ret = lib_lowvprintf(format, ap);
|
||||
ret = lowvsyslog(format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,15 +51,15 @@
|
||||
|
||||
#ifdef CONFIG_CPP_HAVE_VARARGS
|
||||
# ifdef CONFIG_ARCH_LOWPUTC
|
||||
# define message(format, arg...) lib_lowprintf(format, ##arg)
|
||||
# define message(format, arg...) lowsyslog(format, ##arg)
|
||||
# else
|
||||
# define message(format, arg...) lib_rawprintf(format, ##arg)
|
||||
# define message(format, arg...) syslog(format, ##arg)
|
||||
# endif
|
||||
#else
|
||||
# ifdef CONFIG_ARCH_LOWPUTC
|
||||
# define message lib_lowprintf
|
||||
# define message lowsyslog
|
||||
# else
|
||||
# define message lib_rawprintf
|
||||
# define message syslog
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
+40
-98
@@ -1,7 +1,7 @@
|
||||
/************************************************************
|
||||
* libc/misc/lib_init.c
|
||||
*
|
||||
* Copyright (C) 2007, 2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2011, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -76,69 +76,35 @@ void weak_const_function lib_initialize(void)
|
||||
}
|
||||
|
||||
#if CONFIG_NFILE_STREAMS > 0
|
||||
/* The following function is called when a new TCB is allocated. It
|
||||
* creates the streamlist instance that is stored in the TCB.
|
||||
/* The following function is called when a new task is allocated. It
|
||||
* intializes the streamlist instance that is stored in the task group.
|
||||
*/
|
||||
|
||||
FAR struct streamlist *lib_alloclist(void)
|
||||
void lib_streaminit(FAR struct streamlist *list)
|
||||
{
|
||||
FAR struct streamlist *list;
|
||||
list = (FAR struct streamlist*)lib_zalloc(sizeof(struct streamlist));
|
||||
if (list)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
/* Start with a reference count of one */
|
||||
/* Initialize the list access mutex */
|
||||
|
||||
list->sl_crefs = 1;
|
||||
(void)sem_init(&list->sl_sem, 0, 1);
|
||||
|
||||
/* Initialize the list access mutex */
|
||||
/* Initialize each FILE structure */
|
||||
|
||||
(void)sem_init(&list->sl_sem, 0, 1);
|
||||
for (i = 0; i < CONFIG_NFILE_STREAMS; i++)
|
||||
{
|
||||
/* Clear the IOB */
|
||||
|
||||
/* Initialize each FILE structure */
|
||||
memset(&list->sl_streams[i], 0, sizeof(FILE));
|
||||
|
||||
for (i = 0; i < CONFIG_NFILE_STREAMS; i++)
|
||||
{
|
||||
/* Clear the IOB */
|
||||
/* Indicate not opened */
|
||||
|
||||
memset(&list->sl_streams[i], 0, sizeof(FILE));
|
||||
list->sl_streams[i].fs_filedes = -1;
|
||||
|
||||
/* Indicate not opened */
|
||||
/* Initialize the stream semaphore to one to support one-at-
|
||||
* a-time access to private data sets.
|
||||
*/
|
||||
|
||||
list->sl_streams[i].fs_filedes = -1;
|
||||
|
||||
/* Initialize the stream semaphore to one to support one-at-
|
||||
* a-time access to private data sets.
|
||||
*/
|
||||
|
||||
lib_sem_initialize(&list->sl_streams[i]);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
/* This function is called when a TCB is closed (such as with
|
||||
* pthread_create(). It increases the reference count on the stream
|
||||
* list.
|
||||
*/
|
||||
|
||||
void lib_addreflist(FAR struct streamlist *list)
|
||||
{
|
||||
if (list)
|
||||
{
|
||||
/* Increment the reference count on the list.
|
||||
* NOTE: that we disable interrupts to do this
|
||||
* (vs. taking the list semaphore). We do this
|
||||
* because file cleanup operations often must be
|
||||
* done from the IDLE task which cannot wait
|
||||
* on semaphores.
|
||||
*/
|
||||
|
||||
register irqstate_t flags = irqsave();
|
||||
list->sl_crefs++;
|
||||
irqrestore(flags);
|
||||
lib_sem_initialize(&list->sl_streams[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,57 +115,33 @@ void lib_addreflist(FAR struct streamlist *list)
|
||||
|
||||
void lib_releaselist(FAR struct streamlist *list)
|
||||
{
|
||||
int crefs;
|
||||
if (list)
|
||||
#if CONFIG_STDIO_BUFFER_SIZE > 0
|
||||
int i;
|
||||
#endif
|
||||
|
||||
DEBUGASSERT(list);
|
||||
|
||||
/* Destroy the semaphore and release the filelist */
|
||||
|
||||
(void)sem_destroy(&list->sl_sem);
|
||||
|
||||
/* Release each stream in the list */
|
||||
|
||||
#if CONFIG_STDIO_BUFFER_SIZE > 0
|
||||
for (i = 0; i < CONFIG_NFILE_STREAMS; i++)
|
||||
{
|
||||
/* Decrement the reference count on the list.
|
||||
* NOTE: that we disable interrupts to do this
|
||||
* (vs. taking the list semaphore). We do this
|
||||
* because file cleanup operations often must be
|
||||
* done from the IDLE task which cannot wait
|
||||
* on semaphores.
|
||||
*/
|
||||
/* Destroy the semaphore that protects the IO buffer */
|
||||
|
||||
register irqstate_t flags = irqsave();
|
||||
crefs = --(list->sl_crefs);
|
||||
irqrestore(flags);
|
||||
(void)sem_destroy(&list->sl_streams[i].fs_sem);
|
||||
|
||||
/* If the count decrements to zero, then there is no reference
|
||||
* to the structure and it should be deallocated. Since there
|
||||
* are references, it would be an error if any task still held
|
||||
* a reference to the list's semaphore.
|
||||
*/
|
||||
/* Release the IO buffer */
|
||||
|
||||
if (crefs <= 0)
|
||||
{
|
||||
#if CONFIG_STDIO_BUFFER_SIZE > 0
|
||||
int i;
|
||||
if (list->sl_streams[i].fs_bufstart)
|
||||
{
|
||||
sched_free(list->sl_streams[i].fs_bufstart);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Destroy the semaphore and release the filelist */
|
||||
|
||||
(void)sem_destroy(&list->sl_sem);
|
||||
|
||||
/* Release each stream in the list */
|
||||
|
||||
#if CONFIG_STDIO_BUFFER_SIZE > 0
|
||||
for (i = 0; i < CONFIG_NFILE_STREAMS; i++)
|
||||
{
|
||||
/* Destroy the semaphore that protects the IO buffer */
|
||||
|
||||
(void)sem_destroy(&list->sl_streams[i].fs_sem);
|
||||
|
||||
/* Release the IO buffer */
|
||||
if (list->sl_streams[i].fs_bufstart)
|
||||
{
|
||||
sched_free(list->sl_streams[i].fs_bufstart);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Finally, release the list itself */
|
||||
|
||||
sched_free(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NFILE_STREAMS */
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
# This first group of C files do not depend on having file descriptors or
|
||||
# C streams.
|
||||
|
||||
CSRCS += lib_fileno.c lib_printf.c lib_rawprintf.c lib_lowprintf.c \
|
||||
CSRCS += lib_fileno.c lib_printf.c lib_syslog.c lib_lowsyslog.c\
|
||||
lib_sprintf.c lib_asprintf.c lib_snprintf.c lib_libsprintf.c \
|
||||
lib_vsprintf.c lib_avsprintf.c lib_vsnprintf.c lib_libvsprintf.c \
|
||||
lib_meminstream.c lib_memoutstream.c lib_lowinstream.c \
|
||||
|
||||
@@ -150,7 +150,7 @@ char *fgets(FAR char *buf, int buflen, FILE *stream)
|
||||
if (ch == '\n')
|
||||
#elif defined(CONFIG_EOL_IS_CR)
|
||||
if (ch == '\r')
|
||||
#else /* elif CONFIG_EOL_IS_EITHER_CRLF */
|
||||
#else /* elif defined(CONFIG_EOL_IS_EITHER_CRLF) */
|
||||
if (ch == '\n' || ch == '\r')
|
||||
#endif
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* libc/stdio/lib_libflushall.c
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* libc/stdio/lib_libfread.c
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -88,7 +88,9 @@ ssize_t lib_fread(FAR void *ptr, size_t count, FAR FILE *stream)
|
||||
{
|
||||
unsigned char *dest = (unsigned char*)ptr;
|
||||
ssize_t bytes_read;
|
||||
#if CONFIG_STDIO_BUFFER_SIZE > 0
|
||||
int ret;
|
||||
#endif
|
||||
|
||||
/* Make sure that reading from this stream is allowed */
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* libc/stdio/lib_lowprintf.c
|
||||
* libc/stdio/lib_lowsyslog.c
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
@@ -38,8 +38,10 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "lib_internal.h"
|
||||
|
||||
/* This interface can only be used from within the kernel */
|
||||
@@ -83,12 +85,12 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lib_lowvprintf
|
||||
* Name: lowvsyslog
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_ARCH_LOWPUTC) || defined(CONFIG_SYSLOG)
|
||||
|
||||
int lib_lowvprintf(const char *fmt, va_list ap)
|
||||
int lowvsyslog(const char *fmt, va_list ap)
|
||||
{
|
||||
struct lib_outstream_s stream;
|
||||
|
||||
@@ -103,21 +105,21 @@ int lib_lowvprintf(const char *fmt, va_list ap)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lib_lowprintf
|
||||
* Name: lowsyslog
|
||||
****************************************************************************/
|
||||
|
||||
int lib_lowprintf(const char *fmt, ...)
|
||||
int lowsyslog(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_DEBUG_ENABLE
|
||||
#ifdef CONFIG_SYSLOG_ENABLE
|
||||
ret = 0;
|
||||
if (g_dbgenable)
|
||||
if (g_syslogenable)
|
||||
#endif
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
ret = lib_lowvprintf(fmt, ap);
|
||||
ret = lowvsyslog(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
@@ -93,9 +93,9 @@ int printf(const char *fmt, ...)
|
||||
#if CONFIG_NFILE_STREAMS > 0
|
||||
ret = vfprintf(stdout, fmt, ap);
|
||||
#elif CONFIG_NFILE_DESCRIPTORS > 0
|
||||
ret = lib_rawvprintf(fmt, ap);
|
||||
ret = vsyslog(fmt, ap);
|
||||
#elif defined(CONFIG_ARCH_LOWPUTC)
|
||||
ret = lib_lowvprintf(fmt, ap);
|
||||
ret = lowvsyslog(fmt, ap);
|
||||
#else
|
||||
# ifdef CONFIG_CPP_HAVE_WARNING
|
||||
# warning "printf has no data sink"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* libc/stdio/lib_rawprintf.c
|
||||
* libc/stdio/lib_syslog.c
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -37,8 +37,11 @@
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <debug.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "lib_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
@@ -85,10 +88,10 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lib_rawvprintf
|
||||
* Name: vsyslog
|
||||
****************************************************************************/
|
||||
|
||||
int lib_rawvprintf(const char *fmt, va_list ap)
|
||||
int vsyslog(const char *fmt, va_list ap)
|
||||
{
|
||||
#if defined(CONFIG_SYSLOG)
|
||||
|
||||
@@ -129,21 +132,21 @@ int lib_rawvprintf(const char *fmt, va_list ap)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lib_rawprintf
|
||||
* Name: syslog
|
||||
****************************************************************************/
|
||||
|
||||
int lib_rawprintf(const char *fmt, ...)
|
||||
int syslog(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_DEBUG_ENABLE
|
||||
#ifdef CONFIG_SYSLOG_ENABLE
|
||||
ret = 0;
|
||||
if (g_dbgenable)
|
||||
if (g_syslogenable)
|
||||
#endif
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
ret = lib_rawvprintf(fmt, ap);
|
||||
ret = vsyslog(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
@@ -71,22 +71,23 @@ static void syslogstream_putc(FAR struct lib_outstream_s *this, int ch)
|
||||
|
||||
do
|
||||
{
|
||||
/* Write the character to the supported logging device */
|
||||
/* Write the character to the supported logging device. On failure,
|
||||
* syslog_putc returns EOF with the errno value set;
|
||||
*/
|
||||
|
||||
ret = syslog_putc(ch);
|
||||
if (ret == OK)
|
||||
if (ret != EOF)
|
||||
{
|
||||
this->nput++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* On failure syslog_putc will return a negated errno value. The
|
||||
* errno variable will not be set. The special value -EINTR means that
|
||||
* syslog_putc() was awakened by a signal. This is not a real error and
|
||||
* must be ignored in this context.
|
||||
/* The special errno value -EINTR means that syslog_putc() was
|
||||
* awakened by a signal. This is not a real error and must be
|
||||
* ignored in this context.
|
||||
*/
|
||||
}
|
||||
while (ret == -EINTR);
|
||||
while (errno == -EINTR);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
+120
-56
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* net/net_poll.c
|
||||
*
|
||||
* Copyright (C) 2008-2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2008-2009, 2011-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -46,11 +46,13 @@
|
||||
#include <stdlib.h>
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/net/uip/uip.h>
|
||||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include <uip/uip_internal.h>
|
||||
|
||||
@@ -75,6 +77,14 @@
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
/* This is an allocated container that holds the poll-related information */
|
||||
|
||||
struct net_poll_s
|
||||
{
|
||||
FAR struct socket *psock; /* Needed to handle loss of connection */
|
||||
struct pollfd *fds; /* Needed to handle poll events */
|
||||
FAR struct uip_callback_s *cb; /* Needed to teardown the poll */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
@@ -101,16 +111,18 @@
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef HAVE_NETPOLL
|
||||
static uint16_t poll_interrupt(struct uip_driver_s *dev, FAR void *conn,
|
||||
static uint16_t poll_interrupt(FAR struct uip_driver_s *dev, FAR void *conn,
|
||||
FAR void *pvpriv, uint16_t flags)
|
||||
{
|
||||
FAR struct pollfd *fds = (FAR struct pollfd *)pvpriv;
|
||||
FAR struct net_poll_s *info = (FAR struct net_poll_s *)pvpriv;
|
||||
|
||||
nllvdbg("flags: %04x\n", flags);
|
||||
|
||||
DEBUGASSERT(!info || (info->psock && info->fds));
|
||||
|
||||
/* 'priv' might be null in some race conditions (?) */
|
||||
|
||||
if (fds)
|
||||
if (info)
|
||||
{
|
||||
pollevent_t eventset = 0;
|
||||
|
||||
@@ -118,24 +130,23 @@ static uint16_t poll_interrupt(struct uip_driver_s *dev, FAR void *conn,
|
||||
|
||||
if ((flags & (UIP_NEWDATA|UIP_BACKLOG)) != 0)
|
||||
{
|
||||
eventset |= POLLIN & fds->events;
|
||||
eventset |= POLLIN & info->fds->events;
|
||||
}
|
||||
|
||||
/* A poll is a sign that we are free to send data. */
|
||||
|
||||
if ((flags & UIP_POLL) != 0)
|
||||
{
|
||||
eventset |= (POLLOUT & fds->events);
|
||||
eventset |= (POLLOUT & info->fds->events);
|
||||
}
|
||||
|
||||
/* Check for a loss of connection events.
|
||||
*
|
||||
* REVISIT: Need to call net_lostconnection() here, but don't have
|
||||
* the psock instance. What should we do?
|
||||
*/
|
||||
/* Check for a loss of connection events. */
|
||||
|
||||
if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
|
||||
{
|
||||
/* Make the the connection has been lost */
|
||||
|
||||
net_lostconnection(info->psock, flags);
|
||||
eventset |= (POLLERR | POLLHUP);
|
||||
}
|
||||
|
||||
@@ -143,8 +154,8 @@ static uint16_t poll_interrupt(struct uip_driver_s *dev, FAR void *conn,
|
||||
|
||||
if (eventset)
|
||||
{
|
||||
fds->revents |= eventset;
|
||||
sem_post(fds->sem);
|
||||
info->fds->revents |= eventset;
|
||||
sem_post(info->fds->sem);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,9 +180,11 @@ static uint16_t poll_interrupt(struct uip_driver_s *dev, FAR void *conn,
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef HAVE_NETPOLL
|
||||
static inline int net_pollsetup(FAR struct socket *psock, struct pollfd *fds)
|
||||
static inline int net_pollsetup(FAR struct socket *psock,
|
||||
FAR struct pollfd *fds)
|
||||
{
|
||||
FAR struct uip_conn *conn = psock->s_conn;
|
||||
FAR struct net_poll_s *info;
|
||||
FAR struct uip_callback_s *cb;
|
||||
uip_lock_t flags;
|
||||
int ret;
|
||||
@@ -185,6 +198,14 @@ static inline int net_pollsetup(FAR struct socket *psock, struct pollfd *fds)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate a container to hold the poll information */
|
||||
|
||||
info = (FAR struct net_poll_s *)kmalloc(sizeof(struct net_poll_s));
|
||||
if (!info)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Some of the following must be atomic */
|
||||
|
||||
flags = uip_lock();
|
||||
@@ -195,18 +216,29 @@ static inline int net_pollsetup(FAR struct socket *psock, struct pollfd *fds)
|
||||
if (!cb)
|
||||
{
|
||||
ret = -EBUSY;
|
||||
goto errout_with_irq;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
/* Initialize the callback structure */
|
||||
/* Initialize the poll info container */
|
||||
|
||||
info->psock = psock;
|
||||
info->fds = fds;
|
||||
info->cb = cb;
|
||||
|
||||
/* Initialize the callback structure. Save the reference to the info
|
||||
* structure as callback private data so that it will be available during
|
||||
* callback processing.
|
||||
*/
|
||||
|
||||
cb->flags = (UIP_NEWDATA|UIP_BACKLOG|UIP_POLL|UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT);
|
||||
cb->priv = (FAR void *)fds;
|
||||
cb->priv = (FAR void *)info;
|
||||
cb->event = poll_interrupt;
|
||||
|
||||
/* Save the nps reference in the poll structure for use at teardown as well */
|
||||
/* Save the reference in the poll info structure as fds private as well
|
||||
* for use durring poll teardown as well.
|
||||
*/
|
||||
|
||||
fds->priv = (FAR void *)cb;
|
||||
fds->priv = (FAR void *)info;
|
||||
|
||||
#ifdef CONFIG_NET_TCPBACKLOG
|
||||
/* Check for read data or backlogged connection availability now */
|
||||
@@ -240,7 +272,8 @@ static inline int net_pollsetup(FAR struct socket *psock, struct pollfd *fds)
|
||||
uip_unlock(flags);
|
||||
return OK;
|
||||
|
||||
errout_with_irq:
|
||||
errout_with_lock:
|
||||
kfree(info);
|
||||
uip_unlock(flags);
|
||||
return ret;
|
||||
}
|
||||
@@ -261,10 +294,11 @@ errout_with_irq:
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef HAVE_NETPOLL
|
||||
static inline int net_pollteardown(FAR struct socket *psock, struct pollfd *fds)
|
||||
static inline int net_pollteardown(FAR struct socket *psock,
|
||||
FAR struct pollfd *fds)
|
||||
{
|
||||
FAR struct uip_conn *conn = psock->s_conn;
|
||||
FAR struct uip_callback_s *cb;
|
||||
FAR struct net_poll_s *info;
|
||||
uip_lock_t flags;
|
||||
|
||||
/* Sanity check */
|
||||
@@ -278,18 +312,23 @@ static inline int net_pollteardown(FAR struct socket *psock, struct pollfd *fds)
|
||||
|
||||
/* Recover the socket descriptor poll state info from the poll structure */
|
||||
|
||||
cb = (FAR struct uip_callback_s *)fds->priv;
|
||||
if (cb)
|
||||
info = (FAR struct net_poll_s *)fds->priv;
|
||||
DEBUGASSERT(info && info->fds && info->cb);
|
||||
if (info)
|
||||
{
|
||||
/* Release the callback */
|
||||
|
||||
flags = uip_lock();
|
||||
uip_tcpcallbackfree(conn, cb);
|
||||
uip_tcpcallbackfree(conn, info->cb);
|
||||
uip_unlock(flags);
|
||||
|
||||
/* Release the poll/select data slot */
|
||||
|
||||
fds->priv = NULL;
|
||||
info->fds->priv = NULL;
|
||||
|
||||
/* Then free the poll info container */
|
||||
|
||||
kfree(info);
|
||||
}
|
||||
|
||||
return OK;
|
||||
@@ -300,6 +339,57 @@ static inline int net_pollteardown(FAR struct socket *psock, struct pollfd *fds)
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Function: net_poll
|
||||
*
|
||||
* Description:
|
||||
* The standard poll() operation redirects operations on socket descriptors
|
||||
* to this function.
|
||||
*
|
||||
* Input Parameters:
|
||||
* psock - An instance of the internal socket structure.
|
||||
* fds - The structure describing the events to be monitored, OR NULL if
|
||||
* this is a request to stop monitoring events.
|
||||
* setup - true: Setup up the poll; false: Teardown the poll
|
||||
*
|
||||
* Returned Value:
|
||||
* 0: Success; Negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_DISABLE_POLL) && defined(HAVE_NETPOLL)
|
||||
int psock_poll(FAR struct socket *psock, FAR struct pollfd *fds, bool setup)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
/* poll() not supported for UDP */
|
||||
|
||||
if (psock->s_type != SOCK_STREAM)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check if we are setting up or tearing down the poll */
|
||||
|
||||
if (setup)
|
||||
{
|
||||
/* Perform the TCP/IP poll() setup */
|
||||
|
||||
ret = net_pollsetup(psock, fds);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Perform the TCP/IP poll() teardown */
|
||||
|
||||
ret = net_pollteardown(psock, fds);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: net_poll
|
||||
*
|
||||
@@ -325,7 +415,6 @@ int net_poll(int sockfd, struct pollfd *fds, bool setup)
|
||||
return -ENOSYS;
|
||||
#else
|
||||
FAR struct socket *psock;
|
||||
int ret;
|
||||
|
||||
/* Get the underlying socket structure and verify that the sockfd
|
||||
* corresponds to valid, allocated socket
|
||||
@@ -334,37 +423,12 @@ int net_poll(int sockfd, struct pollfd *fds, bool setup)
|
||||
psock = sockfd_socket(sockfd);
|
||||
if (!psock || psock->s_crefs <= 0)
|
||||
{
|
||||
ret = -EBADF;
|
||||
goto errout;
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_UDP
|
||||
/* poll() not supported for UDP */
|
||||
/* Then let psock_poll() do the heavy lifting */
|
||||
|
||||
if (psock->s_type != SOCK_STREAM)
|
||||
{
|
||||
ret = -ENOSYS;
|
||||
goto errout;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check if we are setting up or tearing down the poll */
|
||||
|
||||
if (setup)
|
||||
{
|
||||
/* Perform the TCP/IP poll() setup */
|
||||
|
||||
ret = net_pollsetup(psock, fds);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Perform the TCP/IP poll() teardown */
|
||||
|
||||
ret = net_pollteardown(psock, fds);
|
||||
}
|
||||
|
||||
errout:
|
||||
return ret;
|
||||
return psock_poll(psock, fds, setup);
|
||||
#endif /* HAVE_NETPOLL */
|
||||
}
|
||||
#endif /* !CONFIG_DISABLE_POLL */
|
||||
|
||||
+20
-82
@@ -116,99 +116,37 @@ void net_initialize(void)
|
||||
|
||||
#if CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
|
||||
/* Allocate a list of files for a new task */
|
||||
/* Initialize a list of sockets for a new task */
|
||||
|
||||
FAR struct socketlist *net_alloclist(void)
|
||||
void net_initlist(FAR struct socketlist *list)
|
||||
{
|
||||
FAR struct socketlist *list;
|
||||
list = (FAR struct socketlist*)kzalloc(sizeof(struct socketlist));
|
||||
if (list)
|
||||
{
|
||||
/* Start with a reference count of one */
|
||||
/* Initialize the list access mutex */
|
||||
|
||||
list->sl_crefs = 1;
|
||||
|
||||
/* Initialize the list access mutex */
|
||||
|
||||
(void)sem_init(&list->sl_sem, 0, 1);
|
||||
}
|
||||
return list;
|
||||
(void)sem_init(&list->sl_sem, 0, 1);
|
||||
}
|
||||
|
||||
/* Increase the reference count on a file list */
|
||||
/* Release release resources held by the socket list */
|
||||
|
||||
int net_addreflist(FAR struct socketlist *list)
|
||||
void net_releaselist(FAR struct socketlist *list)
|
||||
{
|
||||
if (list)
|
||||
{
|
||||
/* Increment the reference count on the list.
|
||||
* NOTE: that we disable interrupts to do this
|
||||
* (vs. taking the list semaphore). We do this
|
||||
* because file cleanup operations often must be
|
||||
* done from the IDLE task which cannot wait
|
||||
* on semaphores.
|
||||
*/
|
||||
|
||||
register uip_lock_t flags = uip_lock();
|
||||
list->sl_crefs++;
|
||||
uip_unlock(flags);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Release a reference to the file list */
|
||||
|
||||
int net_releaselist(FAR struct socketlist *list)
|
||||
{
|
||||
int crefs;
|
||||
int ndx;
|
||||
|
||||
if (list)
|
||||
DEBUGASSERT(list);
|
||||
|
||||
/* Close each open socket in the list. */
|
||||
|
||||
for (ndx = 0; ndx < CONFIG_NSOCKET_DESCRIPTORS; ndx++)
|
||||
{
|
||||
/* Decrement the reference count on the list.
|
||||
* NOTE: that we disable interrupts to do this
|
||||
* (vs. taking the list semaphore). We do this
|
||||
* because file cleanup operations often must be
|
||||
* done from the IDLE task which cannot wait
|
||||
* on semaphores.
|
||||
*/
|
||||
|
||||
uip_lock_t flags = uip_lock();
|
||||
crefs = --(list->sl_crefs);
|
||||
uip_unlock(flags);
|
||||
|
||||
/* If the count decrements to zero, then there is no reference
|
||||
* to the structure and it should be deallocated. Since there
|
||||
* are references, it would be an error if any task still held
|
||||
* a reference to the list's semaphore.
|
||||
*/
|
||||
|
||||
if (crefs <= 0)
|
||||
{
|
||||
/* Close each open socket in the list
|
||||
* REVISIT: psock_close() will attempt to use semaphores.
|
||||
* If we actually are in the IDLE thread, then could this cause
|
||||
* problems? Probably not, if the task has exited and crefs is
|
||||
* zero, then there probably could not be a contender for the
|
||||
* semaphore.
|
||||
*/
|
||||
|
||||
for (ndx = 0; ndx < CONFIG_NSOCKET_DESCRIPTORS; ndx++)
|
||||
{
|
||||
FAR struct socket *psock = &list->sl_sockets[ndx];
|
||||
if (psock->s_crefs > 0)
|
||||
{
|
||||
(void)psock_close(psock);
|
||||
}
|
||||
}
|
||||
|
||||
/* Destroy the semaphore and release the filelist */
|
||||
|
||||
(void)sem_destroy(&list->sl_sem);
|
||||
sched_free(list);
|
||||
}
|
||||
FAR struct socket *psock = &list->sl_sockets[ndx];
|
||||
if (psock->s_crefs > 0)
|
||||
{
|
||||
(void)psock_close(psock);
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
|
||||
/* Destroy the semaphore */
|
||||
|
||||
(void)sem_destroy(&list->sl_sem);
|
||||
}
|
||||
|
||||
int sockfd_allocate(int minsd)
|
||||
|
||||
+1
-1
@@ -448,7 +448,7 @@ end_wait:
|
||||
* equivalent to sendto(sockfd,buf,len,flags,NULL,0).
|
||||
*
|
||||
* Parameters:
|
||||
* psock And instance of the internal socket structure.
|
||||
* psock An instance of the internal socket structure.
|
||||
* buf Data to send
|
||||
* len Length of data to send
|
||||
* flags Send flags
|
||||
|
||||
+17
-10
@@ -124,6 +124,13 @@ config PREALLOC_CHILDSTATUS
|
||||
sa.sa_flags = SA_NOCLDWAIT;
|
||||
int ret = sigaction(SIGCHLD, &sa, NULL);
|
||||
|
||||
config DEBUG_CHILDSTATUS
|
||||
bool "Enable Child Status Debug Output"
|
||||
default n
|
||||
depends on SCHED_CHILD_STATUS && DEBUG
|
||||
---help---
|
||||
Very detailed... I am sure that you do not want this.
|
||||
|
||||
config JULIAN_TIME
|
||||
bool "Enables Julian time conversions"
|
||||
default n
|
||||
@@ -289,6 +296,16 @@ config SCHED_WAITPID
|
||||
compliant) and will enable the waitid() and wait() interfaces as
|
||||
well.
|
||||
|
||||
config SCHED_STARTHOOK
|
||||
bool "Enable startup hook"
|
||||
default n
|
||||
---help---
|
||||
Enable a non-standard, internal OS API call task_starthook().
|
||||
task_starthook() registers a function that will be called on task
|
||||
startup before that actual task entry point is called. The
|
||||
starthook is useful, for example, for setting up automatic
|
||||
configuration of C++ constructors.
|
||||
|
||||
config SCHED_ATEXIT
|
||||
bool "Enable atexit() API"
|
||||
default n
|
||||
@@ -379,21 +396,11 @@ config DISABLE_MQUEUE
|
||||
depends on DISABLE_OS_API
|
||||
default n
|
||||
|
||||
config DISABLE_MOUNTPOINT
|
||||
bool "Disable support for mount points"
|
||||
depends on DISABLE_OS_API
|
||||
default n
|
||||
|
||||
config DISABLE_ENVIRON
|
||||
bool "Disable environment variable support"
|
||||
depends on DISABLE_OS_API
|
||||
default n
|
||||
|
||||
config DISABLE_POLL
|
||||
bool "Disable driver poll interfaces"
|
||||
depends on DISABLE_OS_API
|
||||
default n
|
||||
|
||||
if !DISABLE_SIGNALS
|
||||
comment "Signal Numbers"
|
||||
|
||||
|
||||
+23
-13
@@ -39,9 +39,7 @@ ASRCS =
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
|
||||
MISC_SRCS = os_start.c os_bringup.c errno_getptr.c errno_get.c errno_set.c
|
||||
MISC_SRCS += sched_garbage.c sched_setupstreams.c sched_getfiles.c sched_getsockets.c
|
||||
MISC_SRCS += sched_getstreams.c sched_setupidlefiles.c sched_setuptaskfiles.c
|
||||
MISC_SRCS += sched_setuppthreadfiles.c sched_releasefiles.c
|
||||
MISC_SRCS += sched_garbage.c sched_getfiles.c sched_getsockets.c sched_getstreams.c
|
||||
|
||||
TSK_SRCS = prctl.c task_create.c task_init.c task_setup.c task_activate.c
|
||||
TSK_SRCS += task_start.c task_delete.c task_deletecurrent.c task_exithook.c
|
||||
@@ -56,6 +54,10 @@ TSK_SRCS += task_posixspawn.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SCHED_STARTHOOK),y)
|
||||
TSK_SRCS += task_starthook.c
|
||||
endif
|
||||
|
||||
SCHED_SRCS = sched_setparam.c sched_setpriority.c sched_getparam.c
|
||||
SCHED_SRCS += sched_setscheduler.c sched_getscheduler.c
|
||||
SCHED_SRCS += sched_yield.c sched_rrgetinterval.c sched_foreach.c
|
||||
@@ -73,13 +75,6 @@ ifeq ($(CONFIG_PRIORITY_INHERITANCE),y)
|
||||
SCHED_SRCS += sched_reprioritize.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SCHED_HAVE_PARENT),y)
|
||||
SCHED_SRCS += task_reparent.c
|
||||
ifeq ($(CONFIG_SCHED_CHILD_STATUS),y)
|
||||
SCHED_SRCS += task_childstatus.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SCHED_WAITPID),y)
|
||||
SCHED_SRCS += sched_waitpid.c
|
||||
ifeq ($(CONFIG_SCHED_HAVE_PARENT),y)
|
||||
@@ -87,7 +82,21 @@ SCHED_SRCS += sched_waitid.c sched_wait.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ENV_SRCS = env_getenvironptr.c env_dup.c env_share.c env_release.c
|
||||
GRP_SRCS = group_create.c group_join.c group_leave.c group_find.c
|
||||
GRP_SRCS += group_setupstreams.c group_setupidlefiles.c group_setuptaskfiles.c
|
||||
|
||||
ifeq ($(CONFIG_SCHED_HAVE_PARENT),y)
|
||||
GRP_SRCS += task_reparent.c
|
||||
ifeq ($(CONFIG_SCHED_CHILD_STATUS),y)
|
||||
GRP_SRCS += group_childstatus.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
|
||||
GRP_SRCS += group_signal.c
|
||||
endif
|
||||
|
||||
ENV_SRCS = env_getenvironptr.c env_dup.c env_release.c
|
||||
ENV_SRCS += env_findvar.c env_removevar.c
|
||||
ENV_SRCS += env_clearenv.c env_getenv.c env_putenv.c env_setenv.c env_unsetenv.c
|
||||
|
||||
@@ -169,8 +178,9 @@ IRQ_SRCS = irq_initialize.c irq_attach.c irq_dispatch.c irq_unexpectedisr.c
|
||||
KMM_SRCS = kmm_initialize.c kmm_addregion.c kmm_semaphore.c
|
||||
KMM_SRCS = kmm_kmalloc.c kmm_kzalloc.c kmm_krealloc.c kmm_kfree.c
|
||||
|
||||
CSRCS = $(MISC_SRCS) $(TSK_SRCS) $(SCHED_SRCS) $(WDOG_SRCS) $(TIME_SRCS) \
|
||||
$(SEM_SRCS) $(TIMER_SRCS) $(WORK_SRCS) $(PGFILL_SRCS) $(IRQ_SRCS)
|
||||
CSRCS = $(MISC_SRCS) $(TSK_SRCS) $(GRP_SRCS) $(SCHED_SRCS) $(WDOG_SRCS)
|
||||
CSRCS += $(TIME_SRCS) $(SEM_SRCS) $(TIMER_SRCS) $(WORK_SRCS) $(PGFILL_SRCS)
|
||||
CSRCS += $(IRQ_SRCS)
|
||||
|
||||
ifneq ($(CONFIG_DISABLE_CLOCK),y)
|
||||
CSRCS += $(CLOCK_SRCS)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* sched/env_clearenv.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -74,7 +74,11 @@
|
||||
|
||||
int clearenv(void)
|
||||
{
|
||||
return env_release((FAR _TCB*)g_readytorun.head);
|
||||
FAR _TCB *tcb = (FAR _TCB*)g_readytorun.head;
|
||||
DEBUGASSERT(tcb->group);
|
||||
|
||||
env_release(tcb->group);
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DISABLE_ENVIRON */
|
||||
|
||||
+32
-40
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* sched/env_dup.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009, 2011, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -68,8 +68,8 @@
|
||||
* exact duplicate of the parent task's environment.
|
||||
*
|
||||
* Parameters:
|
||||
* ptcb The tcb to receive the newly allocated copy of the parspecifiedent
|
||||
* TCB's environment structure with reference count equal to one
|
||||
* group The child task group to receive the newly allocated copy of the
|
||||
* parent task groups environment structure.
|
||||
*
|
||||
* Return Value:
|
||||
* zero on success
|
||||
@@ -79,50 +79,42 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int env_dup(FAR _TCB *ptcb)
|
||||
int env_dup(FAR struct task_group_s *group)
|
||||
{
|
||||
FAR _TCB *ptcb = (FAR _TCB*)g_readytorun.head;
|
||||
FAR char *envp = NULL;
|
||||
size_t envlen;
|
||||
int ret = OK;
|
||||
if (!ptcb )
|
||||
|
||||
DEBUGASSERT(group && ptcb && ptcb->group);
|
||||
|
||||
/* Pre-emption must be disabled throughout the following because the
|
||||
* environment may be shared.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Does the parent task have an environment? */
|
||||
|
||||
if (ptcb->group && ptcb->group->tg_envp)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
FAR _TCB *parent = (FAR _TCB*)g_readytorun.head;
|
||||
environ_t *envp = NULL;
|
||||
/* Yes..The parent task has an environment, duplicate it */
|
||||
|
||||
/* Pre-emption must be disabled throughout the following because the
|
||||
* environment may be shared.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Does the parent task have an environment? */
|
||||
|
||||
if (parent->envp)
|
||||
envlen = ptcb->group->tg_envsize;
|
||||
envp = (FAR char *)kmalloc(envlen);
|
||||
if (!envp)
|
||||
{
|
||||
/* Yes..The parent task has an environment, duplicate it */
|
||||
|
||||
size_t envlen = parent->envp->ev_alloc;
|
||||
envp = (environ_t*)kmalloc(SIZEOF_ENVIRON_T( envlen ));
|
||||
if (!envp)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
else
|
||||
{
|
||||
envp->ev_crefs = 1;
|
||||
envp->ev_alloc = envlen;
|
||||
memcpy( envp->ev_env, parent->envp->ev_env, envlen );
|
||||
}
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
else
|
||||
{
|
||||
group->tg_envsize = envlen;
|
||||
group->tg_envp = envp;
|
||||
memcpy(envp, ptcb->group->tg_envp, envlen);
|
||||
}
|
||||
}
|
||||
|
||||
/* Save the cloned environment in the new TCB */
|
||||
|
||||
ptcb->envp = envp;
|
||||
sched_unlock();
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+13
-20
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* sched/env_findvar.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -85,7 +85,7 @@ static bool env_cmpname(const char *pszname, const char *peqname)
|
||||
* specified name.
|
||||
*
|
||||
* Parameters:
|
||||
* envp The environment structre to be searched.
|
||||
* group The task group containging environment array to be searched.
|
||||
* pname The variable name to find
|
||||
*
|
||||
* Return Value:
|
||||
@@ -97,32 +97,25 @@ static bool env_cmpname(const char *pszname, const char *peqname)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR char *env_findvar(environ_t *envp, const char *pname)
|
||||
FAR char *env_findvar(FAR struct task_group_s *group, const char *pname)
|
||||
{
|
||||
char *ret = NULL;
|
||||
char *ptr;
|
||||
char *end;
|
||||
|
||||
/* Verify input parameters */
|
||||
|
||||
if (envp && pname)
|
||||
{
|
||||
char *ptr;
|
||||
char *end = &envp->ev_env[envp->ev_alloc];
|
||||
DEBUGASSERT(group && pname);
|
||||
|
||||
/* Search for a name=value string with matching name */
|
||||
/* Search for a name=value string with matching name */
|
||||
|
||||
for (ptr = envp->ev_env;
|
||||
ptr < end && !env_cmpname( pname, ptr);
|
||||
ptr += (strlen(ptr) + 1));
|
||||
end = &group->tg_envp[group->tg_envsize];
|
||||
for (ptr = group->tg_envp;
|
||||
ptr < end && !env_cmpname(pname, ptr);
|
||||
ptr += (strlen(ptr) + 1));
|
||||
|
||||
/* Check for success */
|
||||
/* Check for success */
|
||||
|
||||
if (ptr < end)
|
||||
{
|
||||
ret = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return (ptr < end) ? ptr : NULL;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DISABLE_ENVIRON */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* env_getenv.c
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2008, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -77,10 +77,10 @@
|
||||
|
||||
FAR char *getenv(const char *name)
|
||||
{
|
||||
FAR _TCB *rtcb;
|
||||
FAR environ_t *envp;
|
||||
FAR char *pvar;
|
||||
FAR char *pvalue = NULL;
|
||||
FAR _TCB *rtcb;
|
||||
FAR struct task_group_s *group;
|
||||
FAR char *pvar;
|
||||
FAR char *pvalue = NULL;
|
||||
int ret = OK;
|
||||
|
||||
/* Verify that a string was passed */
|
||||
@@ -95,11 +95,11 @@ FAR char *getenv(const char *name)
|
||||
|
||||
sched_lock();
|
||||
rtcb = (FAR _TCB*)g_readytorun.head;
|
||||
envp = rtcb->envp;
|
||||
group = rtcb->group;
|
||||
|
||||
/* Check if the variable exists */
|
||||
|
||||
if ( !envp || (pvar = env_findvar(envp, name)) == NULL)
|
||||
if ( !group || (pvar = env_findvar(group, name)) == NULL)
|
||||
{
|
||||
ret = ENOENT;
|
||||
goto errout_with_lock;
|
||||
|
||||
+17
-19
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* sched/env_internal.h
|
||||
*
|
||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -49,10 +49,9 @@
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DISABLE_ENVIRON
|
||||
# define env_dup(ptcb) (0)
|
||||
# define env_share(ptcb) (0)
|
||||
# define env_release(ptcb) (0)
|
||||
#endif
|
||||
# define env_dup(group) (0)
|
||||
# define env_release(group) (0)
|
||||
#else
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Declarations
|
||||
@@ -62,34 +61,33 @@
|
||||
* Public Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
/* functions used by the task/pthread creation and destruction logic */
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN int env_dup(FAR _TCB *ptcb);
|
||||
EXTERN int env_share(FAR _TCB *ptcb);
|
||||
EXTERN int env_release(FAR _TCB *ptcb);
|
||||
/* Functions used by the task/pthread creation and destruction logic */
|
||||
|
||||
/* functions used internally by the environment handling logic */
|
||||
int env_dup(FAR struct task_group_s *group);
|
||||
void env_release(FAR struct task_group_s *group);
|
||||
|
||||
EXTERN FAR char *env_findvar(environ_t *envp, const char *pname);
|
||||
EXTERN int env_removevar(environ_t *envp, char *pvar);
|
||||
#endif
|
||||
/* Functions used internally by the environment handling logic */
|
||||
|
||||
FAR char *env_findvar(FAR struct task_group_s *group, FAR const char *pname);
|
||||
int env_removevar(FAR struct task_group_s *group, FAR char *pvar);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !CONFIG_DISABLE_ENVIRON */
|
||||
#endif /* __SCHED_ENV_INTERNAL_H */
|
||||
|
||||
|
||||
+22
-45
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* sched/env_clearenv.c
|
||||
* sched/env_release.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -58,65 +58,42 @@
|
||||
* Name: env_release
|
||||
*
|
||||
* Description:
|
||||
* The env_release() function clears the environment of all name-value
|
||||
* pairs and sets the value of the external variable environ to NULL.
|
||||
* env_release() is called only from group_leave() when the last member of
|
||||
* a task group exits. The env_release() function clears the environment
|
||||
* of all name-value pairs and sets the value of the external variable
|
||||
* environ to NULL.
|
||||
*
|
||||
* Parameters:
|
||||
* ptcb Identifies the TCB containing the environment structure
|
||||
* group Identifies the task group containing the environment structure
|
||||
* to be released.
|
||||
*
|
||||
* Return Value:
|
||||
* zero on success
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Not called from an interrupt handler
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int env_release(FAR _TCB *ptcb)
|
||||
void env_release(FAR struct task_group_s *group)
|
||||
{
|
||||
int ret = OK;
|
||||
DEBUGASSERT(group);
|
||||
|
||||
if (!ptcb)
|
||||
/* Free any allocate environment strings */
|
||||
|
||||
if (group->tg_envp)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
FAR environ_t *envp;
|
||||
/* Free the environment */
|
||||
|
||||
/* Examine the environ data in the TCB. Preemption is disabled because the
|
||||
* the environment could be shared among threads.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
envp = ptcb->envp;
|
||||
if (ptcb->envp)
|
||||
{
|
||||
/* Check the reference count on the environment structure */
|
||||
|
||||
if (envp->ev_crefs <= 1)
|
||||
{
|
||||
/* Decrementing the reference count will destroy the environment */
|
||||
|
||||
sched_free(envp);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The environment will persist after decrementing the reference
|
||||
* count */
|
||||
|
||||
envp->ev_crefs--;
|
||||
}
|
||||
|
||||
/* In any case, the environment is no longer accessible on this thread */
|
||||
|
||||
ptcb->envp = NULL;
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
sched_free(group->tg_envp);
|
||||
}
|
||||
|
||||
return ret;
|
||||
/* In any event, make sure that all environment-related varialbles in the
|
||||
* task group structure are reset to initial values.
|
||||
*/
|
||||
|
||||
group->tg_envsize = 0;
|
||||
group->tg_envp = NULL;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DISABLE_ENVIRON */
|
||||
|
||||
+32
-30
@@ -59,7 +59,7 @@
|
||||
* Remove the referenced name=value pair from the environment
|
||||
*
|
||||
* Parameters:
|
||||
* envp The environment containing the name=value pair
|
||||
* group The task group with the environment containing the name=value pair
|
||||
* pvar A pointer to the name=value pair in the restroom
|
||||
*
|
||||
* Return Value:
|
||||
@@ -72,42 +72,44 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int env_removevar(environ_t *envp, char *pvar)
|
||||
int env_removevar(FAR struct task_group_s *group, FAR char *pvar)
|
||||
{
|
||||
FAR char *end; /* Pointer to the end+1 of the environment */
|
||||
int alloc; /* Size of the allocated environment */
|
||||
int ret = ERROR;
|
||||
if (envp && pvar)
|
||||
|
||||
DEBUGASSERT(group && pvar);
|
||||
|
||||
/* Verify that the pointer lies within the environment region */
|
||||
|
||||
alloc = group->tg_envsize; /* Size of the allocated environment */
|
||||
end = &group->tg_envp[alloc]; /* Pointer to the end+1 of the environment */
|
||||
|
||||
if (pvar >= group->tg_envp && pvar < end)
|
||||
{
|
||||
/* Verify that the pointer lies within the environment region */
|
||||
/* Set up for the removal */
|
||||
|
||||
int alloc = envp->ev_alloc; /* Size of the allocated environment */
|
||||
char *end = &envp->ev_env[alloc]; /* Pointer to the end+1 of the environment */
|
||||
int len = strlen(pvar) + 1; /* Length of name=value string to remove */
|
||||
char *src = &pvar[len]; /* Address of name=value string after */
|
||||
char *dest = pvar; /* Location to move the next string */
|
||||
int count = end - src; /* Number of bytes to move (might be zero) */
|
||||
|
||||
if (pvar >= envp->ev_env && pvar < end)
|
||||
/* Move all of the environment strings after the removed one 'down.'
|
||||
* this is inefficient, but robably not high duty.
|
||||
*/
|
||||
|
||||
while (count-- > 0)
|
||||
{
|
||||
/* Set up for the removal */
|
||||
|
||||
int len = strlen(pvar) + 1; /* Length of name=value string to remove */
|
||||
char *src = &pvar[len]; /* Address of name=value string after */
|
||||
char *dest = pvar; /* Location to move the next string */
|
||||
int count = end - src; /* Number of bytes to move (might be zero) */
|
||||
|
||||
/* Move all of the environment strings after the removed one 'down.'
|
||||
* this is inefficient, but robably not high duty.
|
||||
*/
|
||||
|
||||
while (count-- > 0)
|
||||
{
|
||||
*dest++ = *src++;
|
||||
}
|
||||
|
||||
/* Then set to the new allocation size. The caller is expected to
|
||||
* call realloc at some point but we don't do that here because the
|
||||
* caller may add more stuff to the environment.
|
||||
*/
|
||||
|
||||
envp->ev_alloc -= len;
|
||||
ret = OK;
|
||||
*dest++ = *src++;
|
||||
}
|
||||
|
||||
/* Then set to the new allocation size. The caller is expected to
|
||||
* call realloc at some point but we don't do that here because the
|
||||
* caller may add more stuff to the environment.
|
||||
*/
|
||||
|
||||
group->tg_envsize -= len;
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
+29
-30
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* sched/env_setenv.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009, 2011, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -83,12 +83,14 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int setenv(const char *name, const char *value, int overwrite)
|
||||
int setenv(FAR const char *name, FAR const char *value, int overwrite)
|
||||
{
|
||||
FAR _TCB *rtcb;
|
||||
FAR environ_t *envp;
|
||||
FAR char *pvar;
|
||||
int varlen;
|
||||
FAR _TCB *rtcb;
|
||||
FAR struct task_group_s *group;
|
||||
FAR char *pvar;
|
||||
FAR char *newenvp;
|
||||
int newsize;
|
||||
int varlen;
|
||||
int ret = OK;
|
||||
|
||||
/* Verify input parameter */
|
||||
@@ -122,14 +124,15 @@ int setenv(const char *name, const char *value, int overwrite)
|
||||
/* Get a reference to the thread-private environ in the TCB.*/
|
||||
|
||||
sched_lock();
|
||||
rtcb = (FAR _TCB*)g_readytorun.head;
|
||||
envp = rtcb->envp;
|
||||
rtcb = (FAR _TCB*)g_readytorun.head;
|
||||
group = rtcb->group;
|
||||
DEBUGASSERT(group);
|
||||
|
||||
/* Check if the variable alreay exists */
|
||||
/* Check if the variable already exists */
|
||||
|
||||
if ( envp && (pvar = env_findvar(envp, name)) != NULL)
|
||||
if (group->tg_envp && (pvar = env_findvar(group, name)) != NULL)
|
||||
{
|
||||
/* It does! Do we have permission to overwrite the existing value? */
|
||||
/* It does! Do we have permission to overwrite the existing value? */
|
||||
|
||||
if (!overwrite)
|
||||
{
|
||||
@@ -144,7 +147,7 @@ int setenv(const char *name, const char *value, int overwrite)
|
||||
* the environment buffer; this will happen below.
|
||||
*/
|
||||
|
||||
(void)env_removevar(envp, pvar);
|
||||
(void)env_removevar(group, pvar);
|
||||
}
|
||||
|
||||
/* Get the size of the new name=value string. The +2 is for the '=' and for
|
||||
@@ -155,43 +158,39 @@ int setenv(const char *name, const char *value, int overwrite)
|
||||
|
||||
/* Then allocate or reallocate the environment buffer */
|
||||
|
||||
if (envp)
|
||||
if (group->tg_envp)
|
||||
{
|
||||
int alloc = envp->ev_alloc;
|
||||
environ_t *tmp = (environ_t*)krealloc(envp, SIZEOF_ENVIRON_T(alloc + varlen));
|
||||
if (!tmp)
|
||||
newsize = group->tg_envsize + varlen;
|
||||
newenvp = (FAR char *)krealloc(group->tg_envp, newsize);
|
||||
if (!newenvp)
|
||||
{
|
||||
ret = ENOMEM;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
envp = tmp;
|
||||
envp->ev_alloc = alloc + varlen;
|
||||
pvar = &envp->ev_env[alloc];
|
||||
pvar = &newenvp[group->tg_envsize];
|
||||
}
|
||||
else
|
||||
{
|
||||
envp = (environ_t*)kmalloc(SIZEOF_ENVIRON_T(varlen));
|
||||
if (!envp)
|
||||
newsize = varlen;
|
||||
newenvp = (FAR char *)kmalloc(varlen);
|
||||
if (!newenvp)
|
||||
{
|
||||
ret = ENOMEM;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
envp->ev_crefs = 1;
|
||||
envp->ev_alloc = varlen;
|
||||
pvar = envp->ev_env;
|
||||
pvar = newenvp;
|
||||
}
|
||||
|
||||
/* Save the new buffer and size */
|
||||
|
||||
group->tg_envp = newenvp;
|
||||
group->tg_envsize = newsize;
|
||||
|
||||
/* Now, put the new name=value string into the environment buffer */
|
||||
|
||||
sprintf(pvar, "%s=%s", name, value);
|
||||
|
||||
/* Save the new environment pointer (it might have changed due to allocation or
|
||||
* reallocation.
|
||||
*/
|
||||
|
||||
rtcb->envp = envp;
|
||||
sched_unlock();
|
||||
return OK;
|
||||
|
||||
|
||||
+24
-38
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* sched/env_unsetenv.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009, 2011, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -75,61 +75,47 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int unsetenv(const char *name)
|
||||
int unsetenv(FAR const char *name)
|
||||
{
|
||||
FAR _TCB *rtcb;
|
||||
FAR environ_t *envp;
|
||||
FAR char *pvar;
|
||||
FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
|
||||
FAR struct task_group_s *group = rtcb->group;
|
||||
FAR char *pvar;
|
||||
FAR char *newenvp;
|
||||
int newsize;
|
||||
int ret = OK;
|
||||
|
||||
/* Verify input parameter */
|
||||
|
||||
if (!name)
|
||||
{
|
||||
ret = EINVAL;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Get a reference to the thread-private environ in the TCB.*/
|
||||
|
||||
sched_lock();
|
||||
rtcb = (FAR _TCB*)g_readytorun.head;
|
||||
envp = rtcb->envp;
|
||||
DEBUGASSERT(name && group);
|
||||
|
||||
/* Check if the variable exists */
|
||||
|
||||
if ( envp && (pvar = env_findvar(envp, name)) != NULL)
|
||||
sched_lock();
|
||||
if (group && (pvar = env_findvar(group, name)) != NULL)
|
||||
{
|
||||
int alloc;
|
||||
environ_t *tmp;
|
||||
|
||||
/* It does! Remove the name=value pair from the environment. */
|
||||
|
||||
(void)env_removevar(envp, pvar);
|
||||
(void)env_removevar(group, pvar);
|
||||
|
||||
/* Reallocate the new environment buffer */
|
||||
|
||||
alloc = envp->ev_alloc;
|
||||
tmp = (environ_t*)krealloc(envp, SIZEOF_ENVIRON_T(alloc));
|
||||
if (!tmp)
|
||||
newsize = group->tg_envsize;
|
||||
newenvp = (FAR char *)krealloc(group->tg_envp, newsize);
|
||||
if (!newenvp)
|
||||
{
|
||||
ret = ENOMEM;
|
||||
goto errout_with_lock;
|
||||
set_errno(ENOMEM);
|
||||
ret = ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Save the new environment pointer (it might have changed due to
|
||||
* reallocation.
|
||||
*/
|
||||
|
||||
/* Save the new environment pointer (it might have changed due to reallocation. */
|
||||
|
||||
rtcb->envp = tmp;
|
||||
group->tg_envp = newenvp;
|
||||
}
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
return OK;
|
||||
|
||||
errout_with_lock:
|
||||
sched_unlock();
|
||||
errout:
|
||||
errno = ret;
|
||||
return ERROR;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DISABLE_ENVIRON */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*****************************************************************************
|
||||
* sched/task_childstatus.c
|
||||
* sched/group_childstatus.c
|
||||
*
|
||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <debug.h>
|
||||
|
||||
#include "os_internal.h"
|
||||
#include "group_internal.h"
|
||||
|
||||
#if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS)
|
||||
|
||||
@@ -91,13 +92,13 @@ static struct child_pool_s g_child_pool;
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: task_dumpchildren
|
||||
* Name: group_dumpchildren
|
||||
*
|
||||
* Description:
|
||||
* Dump all of the children when the part TCB list is modified.
|
||||
*
|
||||
* Parameters:
|
||||
* tcb - The parent TCB.
|
||||
* group - The task group containing the child status.
|
||||
*
|
||||
* Return Value:
|
||||
* None.
|
||||
@@ -108,20 +109,21 @@ static struct child_pool_s g_child_pool;
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_CHILDSTATUS
|
||||
static void task_dumpchildren(FAR _TCB *tcb, FAR const char *msg)
|
||||
static void group_dumpchildren(FAR struct task_group_s *group,
|
||||
FAR const char *msg)
|
||||
{
|
||||
FAR struct child_status_s *child;
|
||||
int i;
|
||||
|
||||
dbg("Parent TCB=%p: %s\n", tcb, msg);
|
||||
for (i = 0, child = tcb->children; child; i++, child = child->flink)
|
||||
dbg("Task group=%p: %s\n", group, msg);
|
||||
for (i = 0, child = group->tg_children; child; i++, child = child->flink)
|
||||
{
|
||||
dbg(" %d. ch_flags=%02x ch_pid=%d ch_status=%d\n",
|
||||
i, child->ch_flags, child->ch_pid, child->ch_status);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# task_dumpchildren(t,m)
|
||||
# define group_dumpchildren(t,m)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
@@ -165,7 +167,7 @@ void task_initialize(void)
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: task_allocchild
|
||||
* Name: group_allocchild
|
||||
*
|
||||
* Description:
|
||||
* Allocate a child status structure by removing the next entry from a
|
||||
@@ -184,7 +186,7 @@ void task_initialize(void)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
FAR struct child_status_s *task_allocchild(void)
|
||||
FAR struct child_status_s *group_allocchild(void)
|
||||
{
|
||||
FAR struct child_status_s *ret;
|
||||
|
||||
@@ -201,7 +203,7 @@ FAR struct child_status_s *task_allocchild(void)
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: task_freechild
|
||||
* Name: group_freechild
|
||||
*
|
||||
* Description:
|
||||
* Release a child status structure by returning it to a free list.
|
||||
@@ -218,7 +220,7 @@ FAR struct child_status_s *task_allocchild(void)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void task_freechild(FAR struct child_status_s *child)
|
||||
void group_freechild(FAR struct child_status_s *child)
|
||||
{
|
||||
/* Return the child status structure to the free list */
|
||||
|
||||
@@ -230,13 +232,13 @@ void task_freechild(FAR struct child_status_s *child)
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: task_addchild
|
||||
* Name: group_addchild
|
||||
*
|
||||
* Description:
|
||||
* Add a child status structure in the given TCB.
|
||||
*
|
||||
* Parameters:
|
||||
* tcb - The TCB of the parent task to containing the child status.
|
||||
* group - The task group for the child status.
|
||||
* child - The structure to be added
|
||||
*
|
||||
* Return Value:
|
||||
@@ -248,26 +250,27 @@ void task_freechild(FAR struct child_status_s *child)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void task_addchild(FAR _TCB *tcb, FAR struct child_status_s *child)
|
||||
void group_addchild(FAR struct task_group_s *group,
|
||||
FAR struct child_status_s *child)
|
||||
{
|
||||
/* Add the entry into the TCB list of children */
|
||||
|
||||
child->flink = tcb->children;
|
||||
tcb->children = child;
|
||||
child->flink = group->tg_children;
|
||||
group->tg_children = child;
|
||||
|
||||
task_dumpchildren(tcb, "task_addchild");
|
||||
group_dumpchildren(group, "group_addchild");
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: task_findchild
|
||||
* Name: group_findchild
|
||||
*
|
||||
* Description:
|
||||
* Find a child status structure in the given TCB. A reference to the
|
||||
* child structure is returned, but the child remains the the TCB's list
|
||||
* of children.
|
||||
* Find a child status structure in the given task group. A reference to
|
||||
* the child structure is returned, but the child remains the the group's
|
||||
* list of children.
|
||||
*
|
||||
* Parameters:
|
||||
* tcb - The TCB of the parent task to containing the child status.
|
||||
* group - The ID of the parent task group to containing the child status.
|
||||
* pid - The ID of the child to find.
|
||||
*
|
||||
* Return Value:
|
||||
@@ -280,13 +283,16 @@ void task_addchild(FAR _TCB *tcb, FAR struct child_status_s *child)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
FAR struct child_status_s *task_findchild(FAR _TCB *tcb, pid_t pid)
|
||||
FAR struct child_status_s *group_findchild(FAR struct task_group_s *group,
|
||||
pid_t pid)
|
||||
{
|
||||
FAR struct child_status_s *child;
|
||||
|
||||
DEBUGASSERT(group);
|
||||
|
||||
/* Find the status structure with the matching PID */
|
||||
|
||||
for (child = tcb->children; child; child = child->flink)
|
||||
for (child = group->tg_children; child; child = child->flink)
|
||||
{
|
||||
if (child->ch_pid == pid)
|
||||
{
|
||||
@@ -298,15 +304,51 @@ FAR struct child_status_s *task_findchild(FAR _TCB *tcb, pid_t pid)
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: task_removechild
|
||||
* Name: group_exitchild
|
||||
*
|
||||
* Description:
|
||||
* Remove one child structure from the TCB. The child is removed, but is
|
||||
* not yet freed. task_freechild must be called in order to free the child
|
||||
* status structure.
|
||||
* Search for any child that has exitted.
|
||||
*
|
||||
* Parameters:
|
||||
* tcb - The TCB of the parent task to containing the child status.
|
||||
*
|
||||
* Return Value:
|
||||
* On success, a non-NULL pointer to a child status structure for the
|
||||
* exited child. NULL is returned if not child has exited.
|
||||
*
|
||||
* Assumptions:
|
||||
* Called during SIGCHLD processing in a safe context. No special precautions
|
||||
* are required here.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
FAR struct child_status_s *group_exitchild(FAR struct task_group_s *group)
|
||||
{
|
||||
FAR struct child_status_s *child;
|
||||
|
||||
/* Find the status structure of any child task that has exitted. */
|
||||
|
||||
for (child = group->tg_children; child; child = child->flink)
|
||||
{
|
||||
if ((child->ch_flags & CHILD_FLAG_EXITED) != 0)
|
||||
{
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: group_removechild
|
||||
*
|
||||
* Description:
|
||||
* Remove one child structure from a task group. The child is removed, but
|
||||
* is not yet freed. group_freechild must be called in order to free the
|
||||
* child status structure.
|
||||
*
|
||||
* Parameters:
|
||||
* group - The task group containing the child status.
|
||||
* pid - The ID of the child to find.
|
||||
*
|
||||
* Return Value:
|
||||
@@ -319,14 +361,17 @@ FAR struct child_status_s *task_findchild(FAR _TCB *tcb, pid_t pid)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
FAR struct child_status_s *task_removechild(FAR _TCB *tcb, pid_t pid)
|
||||
FAR struct child_status_s *group_removechild(FAR struct task_group_s *group,
|
||||
pid_t pid)
|
||||
{
|
||||
FAR struct child_status_s *curr;
|
||||
FAR struct child_status_s *prev;
|
||||
|
||||
/* Find the status structure with the matching PID */
|
||||
DEBUGASSERT(group);
|
||||
|
||||
for (prev = NULL, curr = tcb->children;
|
||||
/* Find the status structure with the matching PID */
|
||||
|
||||
for (prev = NULL, curr = group->tg_children;
|
||||
curr;
|
||||
prev = curr, curr = curr->flink)
|
||||
{
|
||||
@@ -336,7 +381,7 @@ FAR struct child_status_s *task_removechild(FAR _TCB *tcb, pid_t pid)
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we find it? If so, remove it from the TCB. */
|
||||
/* Did we find it? If so, remove it from the group. */
|
||||
|
||||
if (curr)
|
||||
{
|
||||
@@ -348,24 +393,24 @@ FAR struct child_status_s *task_removechild(FAR _TCB *tcb, pid_t pid)
|
||||
}
|
||||
else
|
||||
{
|
||||
tcb->children = curr->flink;
|
||||
group->tg_children = curr->flink;
|
||||
}
|
||||
|
||||
curr->flink = NULL;
|
||||
task_dumpchildren(tcb, "task_removechild");
|
||||
group_dumpchildren(group, "group_removechild");
|
||||
}
|
||||
|
||||
return curr;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: task_removechildren
|
||||
* Name: group_removechildren
|
||||
*
|
||||
* Description:
|
||||
* Remove and free all child structure from the TCB.
|
||||
* Remove and free all child structure from the task group.
|
||||
*
|
||||
* Parameters:
|
||||
* tcb - The TCB of the parent task to containing the child status.
|
||||
* group - The task group containing the child status.
|
||||
*
|
||||
* Return Value:
|
||||
* None.
|
||||
@@ -376,21 +421,21 @@ FAR struct child_status_s *task_removechild(FAR _TCB *tcb, pid_t pid)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void task_removechildren(FAR _TCB *tcb)
|
||||
void group_removechildren(FAR struct task_group_s *group)
|
||||
{
|
||||
FAR struct child_status_s *curr;
|
||||
FAR struct child_status_s *next;
|
||||
|
||||
/* Remove all child structures for the TCB and return them to the freelist */
|
||||
|
||||
for (curr = tcb->children; curr; curr = next)
|
||||
for (curr = group->tg_children; curr; curr = next)
|
||||
{
|
||||
next = curr->flink;
|
||||
task_freechild(curr);
|
||||
group_freechild(curr);
|
||||
}
|
||||
|
||||
tcb->children = NULL;
|
||||
task_dumpchildren(tcb, "task_removechildren");
|
||||
group->tg_children = NULL;
|
||||
group_dumpchildren(group, "group_removechildren");
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SCHED_HAVE_PARENT && CONFIG_SCHED_CHILD_STATUS */
|
||||
@@ -0,0 +1,276 @@
|
||||
/*****************************************************************************
|
||||
* sched/group_create.c
|
||||
*
|
||||
* Copyright (C) 2013 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 <sched.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
||||
#include "group_internal.h"
|
||||
#include "env_internal.h"
|
||||
|
||||
#ifdef HAVE_TASK_GROUP
|
||||
|
||||
/*****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
*****************************************************************************/
|
||||
/* Is this worth making a configuration option? */
|
||||
|
||||
#define GROUP_INITIAL_MEMBERS 4
|
||||
|
||||
/*****************************************************************************
|
||||
* Private Types
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private Data
|
||||
*****************************************************************************/
|
||||
/* This is counter that is used to generate unique task group IDs */
|
||||
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
static gid_t g_gidcounter;
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Public Data
|
||||
*****************************************************************************/
|
||||
/* This is the head of a list of all group members */
|
||||
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
FAR struct task_group_s *g_grouphead;
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Private Functions
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: group_assigngid
|
||||
*
|
||||
* Description:
|
||||
* Create a unique group ID.
|
||||
*
|
||||
* Parameters:
|
||||
* tcb - The tcb in need of the task group.
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called during task creation in a safe context. No special precautions
|
||||
* are required here.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
void group_assigngid(FAR struct task_group_s *group)
|
||||
{
|
||||
irqstate_t flags;
|
||||
gid_t gid;
|
||||
|
||||
/* Pre-emption should already be enabled, but lets be paranoid careful */
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Loop until we create a unique ID */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* Increment the ID counter. This is global data so be extra paraoid. */
|
||||
|
||||
flags = irqsave();
|
||||
gid = ++g_gidcounter;
|
||||
|
||||
/* Check for overflow */
|
||||
|
||||
if (gid <= 0)
|
||||
{
|
||||
g_gidcounter = 1;
|
||||
irqrestore(flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Does a task group with this ID already exist? */
|
||||
|
||||
irqrestore(flags);
|
||||
if (group_find(gid) == NULL)
|
||||
{
|
||||
/* Now assign this ID to the group and return */
|
||||
|
||||
group->tg_gid = gid;
|
||||
sched_unlock();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_GROUP_MEMBERS */
|
||||
|
||||
/*****************************************************************************
|
||||
* Public Functions
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: group_allocate
|
||||
*
|
||||
* Description:
|
||||
* Create and a new task group structure for the specified TCB. This
|
||||
* function is called as part of the task creation sequence. The structure
|
||||
* allocated and zered, but otherwise uninitialized. The full creation
|
||||
* of the group of a two step process: (1) First, this function allocates
|
||||
* group structure early in the task creation sequence in order to provide a
|
||||
* group container, then (2) group_initialize() is called to set up the
|
||||
* group membership.
|
||||
*
|
||||
* Parameters:
|
||||
* tcb - The tcb in need of the task group.
|
||||
*
|
||||
* Return Value:
|
||||
* 0 (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
* Assumptions:
|
||||
* Called during task creation in a safe context. No special precautions
|
||||
* are required here.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
int group_allocate(FAR _TCB *tcb)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(tcb && !tcb->group);
|
||||
|
||||
/* Allocate the group structure and assign it to the TCB */
|
||||
|
||||
tcb->group = (FAR struct task_group_s *)kzalloc(sizeof(struct task_group_s));
|
||||
if (!tcb->group)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Assign the group a unique ID. If g_gidcounter were to wrap before we
|
||||
* finish with task creation, that would be a problem.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
group_assigngid(tcb->group);
|
||||
#endif
|
||||
|
||||
/* Duplicate the parent tasks envionment */
|
||||
|
||||
ret = env_dup(tcb->group);
|
||||
if (ret < 0)
|
||||
{
|
||||
kfree(tcb->group);
|
||||
tcb->group = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: group_initialize
|
||||
*
|
||||
* Description:
|
||||
* Add the task as the initial member of the group. The full creation of
|
||||
* the group of a two step process: (1) First, this group structure is
|
||||
* allocated by group_allocate() early in the task creation sequence, then
|
||||
* (2) this function is called to set up the initial group membership.
|
||||
*
|
||||
* Parameters:
|
||||
* tcb - The tcb in need of the task group.
|
||||
*
|
||||
* Return Value:
|
||||
* 0 (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
* Assumptions:
|
||||
* Called during task creation in a safe context. No special precautions
|
||||
* are required here.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
int group_initialize(FAR _TCB *tcb)
|
||||
{
|
||||
FAR struct task_group_s *group;
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
irqstate_t flags;
|
||||
#endif
|
||||
|
||||
DEBUGASSERT(tcb && tcb->group);
|
||||
group = tcb->group;
|
||||
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
/* Allocate space to hold GROUP_INITIAL_MEMBERS members of the group */
|
||||
|
||||
group->tg_members = (FAR pid_t *)kmalloc(GROUP_INITIAL_MEMBERS*sizeof(pid_t));
|
||||
if (!group->tg_members)
|
||||
{
|
||||
free(group);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Assign the PID of this new task as a member of the group*/
|
||||
|
||||
group->tg_members[0] = tcb->pid;
|
||||
|
||||
/* Initialize the non-zero elements of group structure and assign it to
|
||||
* the tcb.
|
||||
*/
|
||||
|
||||
group->tg_mxmembers = GROUP_INITIAL_MEMBERS; /* Number of members in allocation */
|
||||
|
||||
/* Add the initialized entry to the list of groups */
|
||||
|
||||
flags = irqsave();
|
||||
group->flink = g_grouphead;
|
||||
g_grouphead = group;
|
||||
irqrestore(flags);
|
||||
|
||||
#endif
|
||||
|
||||
group->tg_nmembers = 1; /* Number of members in the group */
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* HAVE_TASK_GROUP */
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* sched/env_share.c
|
||||
/*****************************************************************************
|
||||
* sched/group_find.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -31,87 +31,95 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
*****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
/*****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
*****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
|
||||
#include <sched.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "os_internal.h"
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
||||
#include "group_internal.h"
|
||||
#include "env_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
#ifdef HAVE_TASK_GROUP
|
||||
|
||||
/*****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private Types
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
*****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
/*****************************************************************************
|
||||
* Public Data
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private Functions
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
*****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: env_share
|
||||
/*****************************************************************************
|
||||
* Name: group_find
|
||||
*
|
||||
* Description:
|
||||
* Increment the reference count on the internal environment structure of
|
||||
* a task. This is the action that is performed when a new pthread is
|
||||
* created: The new pthread shares the environment with its parent.
|
||||
* Given a group ID, find the group task structure with that ID. IDs are
|
||||
* used instead of pointers to group structures. This is done because a
|
||||
* group can disappear at any time leaving a stale pointer; an ID is cleaner
|
||||
* because if the group disappears, this function will fail gracefully.
|
||||
*
|
||||
* Parameters:
|
||||
* ptcb The new TCB to receive the shared environment.
|
||||
* gid - The group ID to find.
|
||||
*
|
||||
* Return Value:
|
||||
* A pointer to a specified TCB's environment structure with an incremented
|
||||
* reference count.
|
||||
* On success, a pointer to the group task structure is returned. This
|
||||
* function can fail only if there is no group that corresponds to the
|
||||
* groupd ID.
|
||||
*
|
||||
* Assumptions:
|
||||
* Not called from an interrupt handler.
|
||||
* Called during when signally tasks in a safe context. No special
|
||||
* precautions should be required here. However, extra care is taken when
|
||||
* accessing the global g_grouphead list.
|
||||
*
|
||||
****************************************************************************/
|
||||
*****************************************************************************/
|
||||
|
||||
int env_share(FAR _TCB *ptcb)
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
FAR struct task_group_s *group_find(gid_t gid)
|
||||
{
|
||||
int ret = OK;
|
||||
if (!ptcb)
|
||||
FAR struct task_group_s *group;
|
||||
irqstate_t flags;
|
||||
|
||||
/* Find the status structure with the matching PID */
|
||||
|
||||
flags = irqsave();
|
||||
for (group = g_grouphead; group; group = group->flink)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
FAR _TCB *parent = (FAR _TCB*)g_readytorun.head;
|
||||
environ_t *envp = parent->envp;
|
||||
|
||||
/* Pre-emption must be disabled throughout the following because the
|
||||
* environment is shared.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Does the parent task have an environment? */
|
||||
|
||||
if (envp)
|
||||
if (group->tg_gid == gid)
|
||||
{
|
||||
/* Yes.. increment the reference count on the environment */
|
||||
|
||||
envp->ev_crefs++;
|
||||
irqrestore(flags);
|
||||
return group;
|
||||
}
|
||||
|
||||
/* Then share the environment */
|
||||
|
||||
ptcb->envp = envp;
|
||||
sched_unlock();
|
||||
}
|
||||
|
||||
return ret;
|
||||
irqrestore(flags);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_DISABLE_ENVIRON */
|
||||
|
||||
|
||||
|
||||
#endif /* HAVE_TASK_GROUP */
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* sched_setuppthreadfiles.c
|
||||
* sched/group_internal.h
|
||||
*
|
||||
* Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -33,76 +33,94 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __SCHED_GROUP_INERNAL_H
|
||||
#define __SCHED_GROUP_INERNAL_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <queue.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/lib.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
||||
#include "os_internal.h"
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* Any negative GID is invalid. */
|
||||
|
||||
#define INVALID_GROUP_ID (pid_t)-1
|
||||
#define IS_INVALID_GID(gid) ((int)(gid) < 0)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
/* This is the head of a list of all group members */
|
||||
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
extern FAR struct task_group_s *g_grouphead;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
/* Task group data structure management */
|
||||
|
||||
#ifdef HAVE_TASK_GROUP
|
||||
int group_allocate(FAR _TCB *tcb);
|
||||
int group_initialize(FAR _TCB *tcb);
|
||||
int group_bind(FAR _TCB *tcb);
|
||||
int group_join(FAR _TCB *tcb);
|
||||
void group_leave(FAR _TCB *tcb);
|
||||
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
FAR struct task_group_s *group_find(gid_t gid);
|
||||
int group_addmember(FAR struct task_group_s *group, pid_t pid);
|
||||
int group_removemember(FAR struct task_group_s *group, pid_t pid);
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
int group_signal(FAR struct task_group_s *group, FAR siginfo_t *info);
|
||||
#endif
|
||||
#endif /* HAVE_TASK_GROUP */
|
||||
|
||||
/* Parent/child data management */
|
||||
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
int task_reparent(pid_t ppid, pid_t chpid);
|
||||
|
||||
#ifdef CONFIG_SCHED_CHILD_STATUS
|
||||
FAR struct child_status_s *group_allocchild(void);
|
||||
void group_freechild(FAR struct child_status_s *status);
|
||||
void group_addchild(FAR struct task_group_s *group,
|
||||
FAR struct child_status_s *child);
|
||||
FAR struct child_status_s *group_exitchild(FAR struct task_group_s *group);
|
||||
FAR struct child_status_s *group_findchild(FAR struct task_group_s *group,
|
||||
pid_t pid);
|
||||
FAR struct child_status_s *group_removechild(FAR struct task_group_s *group,
|
||||
pid_t pid);
|
||||
void group_removechildren(FAR struct task_group_s *group);
|
||||
|
||||
#endif /* CONFIG_SCHED_CHILD_STATUS */
|
||||
#endif /* CONFIG_SCHED_HAVE_PARENT */
|
||||
|
||||
/* Group data resource configuration */
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sched_setuppthreadfiles
|
||||
*
|
||||
* Description:
|
||||
* Configure a newly allocated TCB so that it will inherit file
|
||||
* descriptors and streams from the parent pthread.
|
||||
*
|
||||
* Parameters:
|
||||
* tcb - tcb of the new task.
|
||||
*
|
||||
* Return Value:
|
||||
* OK (if an error were returned, it would need to be a non-negated
|
||||
* errno value).
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sched_setuppthreadfiles(FAR _TCB *tcb)
|
||||
{
|
||||
FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
/* The child thread inherits the parent file descriptors */
|
||||
|
||||
tcb->filelist = rtcb->filelist;
|
||||
files_addreflist(tcb->filelist);
|
||||
|
||||
#endif /* CONFIG_NFILE_DESCRIPTORS */
|
||||
|
||||
#if CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
/* The child thread inherits the parent socket descriptors */
|
||||
|
||||
tcb->sockets = rtcb->sockets;
|
||||
net_addreflist(tcb->sockets);
|
||||
|
||||
#endif /* CONFIG_NSOCKET_DESCRIPTORS */
|
||||
|
||||
int group_setupidlefiles(FAR _TCB *tcb);
|
||||
int group_setuptaskfiles(FAR _TCB *tcb);
|
||||
#if CONFIG_NFILE_STREAMS > 0
|
||||
/* The child thread inherits the parent streams */
|
||||
int group_setupstreams(FAR _TCB *tcb);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
tcb->streams = rtcb->streams;
|
||||
lib_addreflist(tcb->streams);
|
||||
|
||||
#endif /* CONFIG_NFILE_STREAMS */
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NFILE_DESCRIPTORS || CONFIG_NSOCKET_DESCRIPTORS */
|
||||
#endif /* __SCHED_GROUP_INERNAL_H */
|
||||
@@ -0,0 +1,227 @@
|
||||
/*****************************************************************************
|
||||
* sched/group_join.c
|
||||
*
|
||||
* Copyright (C) 2013 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 <sched.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
||||
#include "group_internal.h"
|
||||
#include "env_internal.h"
|
||||
|
||||
#ifdef HAVE_TASK_GROUP
|
||||
|
||||
/*****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
*****************************************************************************/
|
||||
/* Is this worth making a configuration option? */
|
||||
|
||||
#define GROUP_REALLOC_MEMBERS 4
|
||||
|
||||
/*****************************************************************************
|
||||
* Private Types
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private Data
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private Functions
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public Functions
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: group_bind
|
||||
*
|
||||
* Description:
|
||||
* A thread joins the group when it is created. This is a two step process,
|
||||
* first, the group must bound to the new threads TCB. group_bind() does
|
||||
* this (at the return from group_join, things are a little unstable: The
|
||||
* group has been bound, but tg_nmembers hs not yet been incremented).
|
||||
* Then, after the new thread is initialized and has a PID assigned to it,
|
||||
* group_join() is called, incrementing the tg_nmembers count on the group.
|
||||
*
|
||||
* Parameters:
|
||||
* tcb - The TCB of the new "child" task that need to join the group.
|
||||
*
|
||||
* Return Value:
|
||||
* 0 (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
* Assumptions:
|
||||
* - The parent task from which the group will be inherited is the task at
|
||||
* the thead of the ready to run list.
|
||||
* - Called during thread creation in a safe context. No special precautions
|
||||
* are required here.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
int group_bind(FAR _TCB *tcb)
|
||||
{
|
||||
FAR _TCB *ptcb = (FAR _TCB *)g_readytorun.head;
|
||||
|
||||
DEBUGASSERT(ptcb && tcb && ptcb->group && !tcb->group);
|
||||
|
||||
/* Copy the group reference from the parent to the child */
|
||||
|
||||
tcb->group = ptcb->group;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: group_join
|
||||
*
|
||||
* Description:
|
||||
* A thread joins the group when it is created. This is a two step process,
|
||||
* first, the group must bound to the new threads TCB. group_bind() does
|
||||
* this (at the return from group_join, things are a little unstable: The
|
||||
* group has been bound, but tg_nmembers hs not yet been incremented).
|
||||
* Then, after the new thread is initialized and has a PID assigned to it,
|
||||
* group_join() is called, incrementing the tg_nmembers count on the group.
|
||||
*
|
||||
* Parameters:
|
||||
* tcb - The TCB of the new "child" task that need to join the group.
|
||||
*
|
||||
* Return Value:
|
||||
* 0 (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
* Assumptions:
|
||||
* - The parent task from which the group will be inherited is the task at
|
||||
* the thead of the ready to run list.
|
||||
* - Called during thread creation in a safe context. No special precautions
|
||||
* are required here.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
int group_join(FAR _TCB *tcb)
|
||||
{
|
||||
FAR struct task_group_s *group;
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
int ret;
|
||||
#endif
|
||||
|
||||
DEBUGASSERT(tcb && tcb->group &&
|
||||
tcb->group->tg_nmembers < UINT8_MAX);
|
||||
|
||||
/* Get the group from the TCB */
|
||||
|
||||
group = tcb->group;
|
||||
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
/* Add the member to the group */
|
||||
|
||||
ret = group_addmember(group, tcb->pid);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
group->tg_nmembers++;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: group_addmember
|
||||
*
|
||||
* Description:
|
||||
* Add a new member to a group.
|
||||
*
|
||||
* Parameters:
|
||||
* group - The task group to add the new member
|
||||
* pid - The new member
|
||||
*
|
||||
* Return Value:
|
||||
* 0 (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
* Assumptions:
|
||||
* Called during thread creation and during reparenting in a safe context.
|
||||
* No special precautions are required here.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
int group_addmember(FAR struct task_group_s *group, pid_t pid)
|
||||
{
|
||||
DEBUGASSERT(group && group->tg_nmembers < UINT8_MAX);
|
||||
|
||||
/* Will we need to extend the size of the array of groups? */
|
||||
|
||||
if (group->tg_nmembers >= group->tg_mxmembers)
|
||||
{
|
||||
FAR pid_t *newmembers;
|
||||
unsigned int newmax;
|
||||
|
||||
/* Yes... reallocate the array of members */
|
||||
|
||||
newmax = group->tg_mxmembers + GROUP_REALLOC_MEMBERS;
|
||||
if (newmax > UINT8_MAX)
|
||||
{
|
||||
newmax = UINT8_MAX;
|
||||
}
|
||||
|
||||
newmembers = (FAR pid_t *)
|
||||
krealloc(group->tg_members, sizeof(pid_t) * newmax);
|
||||
|
||||
if (!newmembers)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Save the new number of members in the reallocated members array */
|
||||
|
||||
group->tg_members = newmembers;
|
||||
group->tg_mxmembers = newmax;
|
||||
}
|
||||
|
||||
/* Assign this new pid to the group. */
|
||||
|
||||
group->tg_members[group->tg_nmembers] = pid;
|
||||
return OK;
|
||||
}
|
||||
#endif /* HAVE_GROUP_MEMBERS */
|
||||
|
||||
#endif /* HAVE_TASK_GROUP */
|
||||
@@ -0,0 +1,366 @@
|
||||
/*****************************************************************************
|
||||
* sched/group_leave.c
|
||||
*
|
||||
* Copyright (C) 2013 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 <sched.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/lib.h>
|
||||
|
||||
#include "group_internal.h"
|
||||
#include "env_internal.h"
|
||||
|
||||
#ifdef HAVE_TASK_GROUP
|
||||
|
||||
/*****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private Types
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private Data
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private Functions
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: group_remove
|
||||
*
|
||||
* Description:
|
||||
* Remove a group from the list of groups.
|
||||
*
|
||||
* Parameters:
|
||||
* group - The group to be removed.
|
||||
*
|
||||
* Return Value:
|
||||
* None.
|
||||
*
|
||||
* Assumptions:
|
||||
* Called during task deletion in a safe context. No special precautions
|
||||
* are required here.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
void group_remove(FAR struct task_group_s *group)
|
||||
{
|
||||
FAR struct task_group_s *curr;
|
||||
FAR struct task_group_s *prev;
|
||||
irqstate_t flags;
|
||||
|
||||
/* Let's be especially careful while access the global task group list.
|
||||
* This is probably un-necessary.
|
||||
*/
|
||||
|
||||
flags = irqsave();
|
||||
|
||||
/* Find the task group structure */
|
||||
|
||||
for (prev = NULL, curr = g_grouphead;
|
||||
curr && curr != group;
|
||||
prev = curr, curr = curr->flink);
|
||||
|
||||
/* Did we find it? If so, remove it from the list. */
|
||||
|
||||
if (curr)
|
||||
{
|
||||
/* Do we remove it from mid-list? Or from the head of the list? */
|
||||
|
||||
if (prev)
|
||||
{
|
||||
prev->flink = curr->flink;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_grouphead = curr->flink;
|
||||
}
|
||||
|
||||
curr->flink = NULL;
|
||||
}
|
||||
|
||||
irqrestore(flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: group_release
|
||||
*
|
||||
* Description:
|
||||
* Release group resources after the last member has left the group.
|
||||
*
|
||||
* Parameters:
|
||||
* group - The group to be removed.
|
||||
*
|
||||
* Return Value:
|
||||
* None.
|
||||
*
|
||||
* Assumptions:
|
||||
* Called during task deletion in a safe context. No special precautions
|
||||
* are required here.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static inline void group_release(FAR struct task_group_s *group)
|
||||
{
|
||||
/* Free all un-reaped child exit status */
|
||||
|
||||
#if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS)
|
||||
group_removechildren(group);
|
||||
#endif
|
||||
|
||||
/* Free all file-related resources now. We really need to close files as
|
||||
* soon as possible while we still have a functioning task.
|
||||
*/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
/* Free resources held by the file descriptor list */
|
||||
|
||||
files_releaselist(&group->tg_filelist);
|
||||
|
||||
#if CONFIG_NFILE_STREAMS > 0
|
||||
/* Free resource held by the stream list */
|
||||
|
||||
lib_releaselist(&group->tg_streamlist);
|
||||
|
||||
#endif /* CONFIG_NFILE_STREAMS */
|
||||
#endif /* CONFIG_NFILE_DESCRIPTORS */
|
||||
|
||||
#if CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
/* Free resource held by the socket list */
|
||||
|
||||
net_releaselist(&group->tg_socketlist);
|
||||
#endif /* CONFIG_NSOCKET_DESCRIPTORS */
|
||||
|
||||
/* Release all shared environment variables */
|
||||
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
env_release(group);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
/* Remove the group from the list of groups */
|
||||
|
||||
group_remove(group);
|
||||
|
||||
/* Release the members array */
|
||||
|
||||
if (group->tg_members)
|
||||
{
|
||||
sched_free(group->tg_members);
|
||||
group->tg_members = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Release the group container itself */
|
||||
|
||||
sched_free(group);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Public Functions
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: group_leave
|
||||
*
|
||||
* Description:
|
||||
* Release a reference on a group. This function is called when a task or
|
||||
* thread exits. It decrements the reference count on the group. If the
|
||||
* reference count decrements to zero, then it frees the group and all of
|
||||
* resources contained in the group.
|
||||
*
|
||||
* Parameters:
|
||||
* tcb - The TCB of the task that is exiting.
|
||||
*
|
||||
* Return Value:
|
||||
* None.
|
||||
*
|
||||
* Assumptions:
|
||||
* Called during task deletion in a safe context. No special precautions
|
||||
* are required here.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
void group_leave(FAR _TCB *tcb)
|
||||
{
|
||||
FAR struct task_group_s *group;
|
||||
|
||||
DEBUGASSERT(tcb);
|
||||
|
||||
/* Make sure that we have a group */
|
||||
|
||||
group = tcb->group;
|
||||
if (group)
|
||||
{
|
||||
/* Remove the member from group */
|
||||
|
||||
int ret = group_removemember(group, tcb->pid);
|
||||
DEBUGASSERT(ret >= 0);
|
||||
|
||||
/* Is the group now empty? */
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
/* Release all of the resource held by the task group */
|
||||
|
||||
group_release(group);
|
||||
}
|
||||
|
||||
/* In any event, we can detach the group from the TCB so that we won't
|
||||
* do this again.
|
||||
*/
|
||||
|
||||
tcb->group = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#else /* HAVE_GROUP_MEMBERS */
|
||||
|
||||
void group_leave(FAR _TCB *tcb)
|
||||
{
|
||||
FAR struct task_group_s *group;
|
||||
|
||||
DEBUGASSERT(tcb);
|
||||
|
||||
/* Make sure that we have a group */
|
||||
|
||||
group = tcb->group;
|
||||
if (group)
|
||||
{
|
||||
/* Yes, we have a group.. Is this the last member of the group? */
|
||||
|
||||
if (group->tg_nmembers > 1)
|
||||
{
|
||||
/* No.. just decrement the number of members in the group */
|
||||
|
||||
group->tg_nmembers--;
|
||||
}
|
||||
|
||||
/* Yes.. that was the last member remaining in the group */
|
||||
|
||||
else
|
||||
{
|
||||
/* Release all of the resource held by the task group */
|
||||
|
||||
group_release(group);
|
||||
}
|
||||
|
||||
/* In any event, we can detach the group from the TCB so we won't do
|
||||
* this again.
|
||||
*/
|
||||
|
||||
tcb->group = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_GROUP_MEMBERS */
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: group_removemember
|
||||
*
|
||||
* Description:
|
||||
* Remove a member from a group.
|
||||
*
|
||||
* Parameters:
|
||||
* group - The group from which to remove the member.
|
||||
* pid - The member to be removed.
|
||||
*
|
||||
* Return Value:
|
||||
* On success, returns the number of members remaining in the group (>=0).
|
||||
* Can fail only if the member is not found in the group. On failure,
|
||||
* returns -ENOENT
|
||||
*
|
||||
* Assumptions:
|
||||
* Called during task deletion and also from the reparenting logic, both
|
||||
* in a safe context. No special precautions are required here.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
int group_removemember(FAR struct task_group_s *group, pid_t pid)
|
||||
{
|
||||
int i;
|
||||
|
||||
DEBUGASSERT(group);
|
||||
|
||||
/* Find the member in the array of members and remove it */
|
||||
|
||||
for (i = 0; i < group->tg_nmembers; i++)
|
||||
{
|
||||
/* Does this member have the matching pid */
|
||||
|
||||
if (group->tg_members[i] == pid)
|
||||
{
|
||||
/* Yes.. break out of the loop. We don't do the actual
|
||||
* removal here, instead we re-test i and do the adjustments
|
||||
* outside of the loop. We do this because we want the
|
||||
* DEBUGASSERT to work properly.
|
||||
*/
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now, test if we found the task in the array of members. */
|
||||
|
||||
if (i < group->tg_nmembers)
|
||||
{
|
||||
/* Remove the member from the array of members */
|
||||
|
||||
group->tg_members[i] = group->tg_members[group->tg_nmembers - 1];
|
||||
group->tg_nmembers--;
|
||||
return group->tg_nmembers;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif /* HAVE_GROUP_MEMBERS */
|
||||
|
||||
#endif /* HAVE_TASK_GROUP */
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* sched/sched_setupidlefiles.c
|
||||
* sched/group_setupidlefiles.c
|
||||
*
|
||||
* Copyright (C) 2007-2010, 2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2010, 2012-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -50,6 +50,7 @@
|
||||
#include <nuttx/net/net.h>
|
||||
|
||||
#include "os_internal.h"
|
||||
#include "group_internal.h"
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
|
||||
@@ -62,7 +63,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sched_setupidlefiles
|
||||
* Name: group_setupidlefiles
|
||||
*
|
||||
* Description:
|
||||
* Configure the idle thread's TCB.
|
||||
@@ -77,30 +78,29 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sched_setupidlefiles(FAR _TCB *tcb)
|
||||
int group_setupidlefiles(FAR _TCB *tcb)
|
||||
{
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NFILE_DESCRIPTORS > 0
|
||||
FAR struct task_group_s *group = tcb->group;
|
||||
#endif
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_DEV_CONSOLE)
|
||||
int fd;
|
||||
#endif
|
||||
|
||||
/* Allocate file descriptors for the TCB */
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
tcb->filelist = files_alloclist();
|
||||
if (!tcb->filelist)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NFILE_DESCRIPTORS > 0
|
||||
DEBUGASSERT(group);
|
||||
#endif
|
||||
|
||||
/* Allocate socket descriptors for the TCB */
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
/* Initialize file descriptors for the TCB */
|
||||
|
||||
files_initlist(&group->tg_filelist);
|
||||
#endif
|
||||
|
||||
#if CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
tcb->sockets = net_alloclist();
|
||||
if (!tcb->sockets)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
/* Allocate socket descriptors for the TCB */
|
||||
|
||||
net_initlist(&group->tg_socketlist);
|
||||
#endif
|
||||
|
||||
/* Open stdin, dup to get stdout and stderr. This should always
|
||||
@@ -139,7 +139,7 @@ int sched_setupidlefiles(FAR _TCB *tcb)
|
||||
/* Allocate file/socket streams for the TCB */
|
||||
|
||||
#if CONFIG_NFILE_STREAMS > 0
|
||||
return sched_setupstreams(tcb);
|
||||
return group_setupstreams(tcb);
|
||||
#else
|
||||
return OK;
|
||||
#endif
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* sched_setupstreams.c
|
||||
* group_setupstreams.c
|
||||
*
|
||||
* Copyright (C) 2007-2008, 2010-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2008, 2010-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -46,6 +46,8 @@
|
||||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/lib.h>
|
||||
|
||||
#include "group_internal.h"
|
||||
|
||||
/* Make sure that there are file or socket descriptors in the system and
|
||||
* that some number of streams have been configured.
|
||||
*/
|
||||
@@ -62,7 +64,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sched_setupstreams
|
||||
* Name: group_setupstreams
|
||||
*
|
||||
* Description:
|
||||
* Setup streams data structures that may be used for standard C buffered
|
||||
@@ -70,26 +72,25 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sched_setupstreams(FAR _TCB *tcb)
|
||||
int group_setupstreams(FAR _TCB *tcb)
|
||||
{
|
||||
/* Allocate file streams for the TCB */
|
||||
DEBUGASSERT(tcb && tcb->group);
|
||||
|
||||
tcb->streams = lib_alloclist();
|
||||
if (tcb->streams)
|
||||
{
|
||||
/* fdopen to get the stdin, stdout and stderr streams.
|
||||
* The following logic depends on the fact that the library
|
||||
* layer will allocate FILEs in order.
|
||||
*
|
||||
* fd = 0 is stdin (read-only)
|
||||
* fd = 1 is stdout (write-only, append)
|
||||
* fd = 2 is stderr (write-only, append)
|
||||
*/
|
||||
/* Initialize file streams for the task group */
|
||||
|
||||
(void)fs_fdopen(0, O_RDONLY, tcb);
|
||||
(void)fs_fdopen(1, O_WROK|O_CREAT, tcb);
|
||||
(void)fs_fdopen(2, O_WROK|O_CREAT, tcb);
|
||||
}
|
||||
lib_streaminit(&tcb->group->tg_streamlist);
|
||||
|
||||
/* fdopen to get the stdin, stdout and stderr streams. The following logic
|
||||
* depends on the fact that the library layer will allocate FILEs in order.
|
||||
*
|
||||
* fd = 0 is stdin (read-only)
|
||||
* fd = 1 is stdout (write-only, append)
|
||||
* fd = 2 is stderr (write-only, append)
|
||||
*/
|
||||
|
||||
(void)fs_fdopen(0, O_RDONLY, tcb);
|
||||
(void)fs_fdopen(1, O_WROK|O_CREAT, tcb);
|
||||
(void)fs_fdopen(2, O_WROK|O_CREAT, tcb);
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* sched/sched_setuptaskfiles.c
|
||||
* sched/group_setuptaskfiles.c
|
||||
*
|
||||
* Copyright (C) 2007-2008, 2010, 2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2008, 2010, 2012-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <nuttx/net/net.h>
|
||||
|
||||
#include "os_internal.h"
|
||||
#include "group_internal.h"
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
|
||||
@@ -93,34 +94,33 @@ static inline void sched_dupfiles(FAR _TCB *tcb)
|
||||
FAR struct file *child;
|
||||
int i;
|
||||
|
||||
DEBUGASSERT(tcb && tcb->group && rtcb->group);
|
||||
|
||||
/* Duplicate the file descriptors. This will be either all of the
|
||||
* file descriptors or just the first three (stdin, stdout, and stderr)
|
||||
* if CONFIG_FDCLONE_STDIO is defined. NFSDS_TOCLONE is set
|
||||
* accordingly above.
|
||||
*/
|
||||
|
||||
if (rtcb->filelist)
|
||||
/* Get pointers to the parent and child task file lists */
|
||||
|
||||
parent = rtcb->group->tg_filelist.fl_files;
|
||||
child = tcb->group->tg_filelist.fl_files;
|
||||
|
||||
/* Check each file in the parent file list */
|
||||
|
||||
for (i = 0; i < NFDS_TOCLONE; i++)
|
||||
{
|
||||
/* Get pointers to the parent and child task file lists */
|
||||
/* Check if this file is opened by the parent. We can tell if
|
||||
* if the file is open because it contain a reference to a non-NULL
|
||||
* i-node structure.
|
||||
*/
|
||||
|
||||
parent = rtcb->filelist->fl_files;
|
||||
child = tcb->filelist->fl_files;
|
||||
|
||||
/* Check each file in the parent file list */
|
||||
|
||||
for (i = 0; i < NFDS_TOCLONE; i++)
|
||||
if (parent[i].f_inode)
|
||||
{
|
||||
/* Check if this file is opened by the parent. We can tell if
|
||||
* if the file is open because it contain a reference to a non-NULL
|
||||
* i-node structure.
|
||||
*/
|
||||
/* Yes... duplicate it for the child */
|
||||
|
||||
if (parent[i].f_inode)
|
||||
{
|
||||
/* Yes... duplicate it for the child */
|
||||
|
||||
(void)files_dup(&parent[i], &child[i]);
|
||||
}
|
||||
(void)files_dup(&parent[i], &child[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,32 +152,31 @@ static inline void sched_dupsockets(FAR _TCB *tcb)
|
||||
FAR struct socket *child;
|
||||
int i;
|
||||
|
||||
/* Duplicate the socket descriptors of all sockets opened by the parent
|
||||
* task.
|
||||
*/
|
||||
/* Duplicate the socket descriptors of all sockets opened by the parent
|
||||
* task.
|
||||
*/
|
||||
|
||||
if (rtcb->sockets)
|
||||
DEBUGASSERT(tcb && tcb->group && rtcb->group);
|
||||
|
||||
/* Get pointers to the parent and child task socket lists */
|
||||
|
||||
parent = rtcb->group->tg_socketlist.sl_sockets;
|
||||
child = tcb->group->tg_socketlist.sl_sockets;
|
||||
|
||||
/* Check each socket in the parent socket list */
|
||||
|
||||
for (i = 0; i < CONFIG_NSOCKET_DESCRIPTORS; i++)
|
||||
{
|
||||
/* Get pointers to the parent and child task socket lists */
|
||||
/* Check if this parent socket is allocated. We can tell if the
|
||||
* socket is allocated because it will have a positive, non-zero
|
||||
* reference count.
|
||||
*/
|
||||
|
||||
parent = rtcb->sockets->sl_sockets;
|
||||
child = tcb->sockets->sl_sockets;
|
||||
|
||||
/* Check each socket in the parent socket list */
|
||||
|
||||
for (i = 0; i < CONFIG_NSOCKET_DESCRIPTORS; i++)
|
||||
if (parent[i].s_crefs > 0)
|
||||
{
|
||||
/* Check if this parent socket is allocated. We can tell if the
|
||||
* socket is allocated because it will have a positive, non-zero
|
||||
* reference count.
|
||||
*/
|
||||
/* Yes... duplicate it for the child */
|
||||
|
||||
if (parent[i].s_crefs > 0)
|
||||
{
|
||||
/* Yes... duplicate it for the child */
|
||||
|
||||
(void)net_clone(&parent[i], &child[i]);
|
||||
}
|
||||
(void)net_clone(&parent[i], &child[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,7 +189,7 @@ static inline void sched_dupsockets(FAR _TCB *tcb)
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sched_setuptaskfiles
|
||||
* Name: group_setuptaskfiles
|
||||
*
|
||||
* Description:
|
||||
* Configure a newly allocated TCB so that it will inherit
|
||||
@@ -207,26 +206,24 @@ static inline void sched_dupsockets(FAR _TCB *tcb)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sched_setuptaskfiles(FAR _TCB *tcb)
|
||||
int group_setuptaskfiles(FAR _TCB *tcb)
|
||||
{
|
||||
/* Allocate file descriptors for the TCB */
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
FAR struct task_group_s *group = tcb->group;
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
tcb->filelist = files_alloclist();
|
||||
if (!tcb->filelist)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
DEBUGASSERT(group);
|
||||
#endif
|
||||
|
||||
/* Allocate socket descriptors for the TCB */
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
/* Initialize file descriptors for the TCB */
|
||||
|
||||
files_initlist(&group->tg_filelist);
|
||||
#endif
|
||||
|
||||
#if CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
tcb->sockets = net_alloclist();
|
||||
if (!tcb->sockets)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
/* Allocate socket descriptors for the TCB */
|
||||
|
||||
net_initlist(&group->tg_socketlist);
|
||||
#endif
|
||||
|
||||
/* Duplicate the parent task's file descriptors */
|
||||
@@ -240,7 +237,7 @@ int sched_setuptaskfiles(FAR _TCB *tcb)
|
||||
/* Allocate file/socket streams for the new TCB */
|
||||
|
||||
#if CONFIG_NFILE_STREAMS > 0
|
||||
return sched_setupstreams(tcb);
|
||||
return group_setupstreams(tcb);
|
||||
#else
|
||||
return OK;
|
||||
#endif
|
||||
@@ -0,0 +1,163 @@
|
||||
/*****************************************************************************
|
||||
* sched/group_signal.c
|
||||
*
|
||||
* Copyright (C) 2013 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 <sched.h>
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "os_internal.h"
|
||||
#include "group_internal.h"
|
||||
#include "sig_internal.h"
|
||||
|
||||
#if defined(HAVE_TASK_GROUP) && !defined(CONFIG_DISABLE_SIGNALS)
|
||||
|
||||
/*****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private Types
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private Data
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private Functions
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public Functions
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: group_signal
|
||||
*
|
||||
* Description:
|
||||
* Send a signal to every member of the group.
|
||||
*
|
||||
* Parameters:
|
||||
* group - The task group that needs to be signalled.
|
||||
*
|
||||
* Return Value:
|
||||
* 0 (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
* Assumptions:
|
||||
* Called during task terminatino in a safe context. No special precautions
|
||||
* are required here.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
int group_signal(FAR struct task_group_s *group, FAR siginfo_t *info)
|
||||
{
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
FAR _TCB *gtcb;
|
||||
int i;
|
||||
|
||||
DEBUGASSERT(group && info);
|
||||
|
||||
/* Make sure that pre-emption is disabled to that we signal all of teh
|
||||
* members of the group before any of them actually run.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Send the signal to each member of the group */
|
||||
|
||||
for (i = 0; i < group->tg_nmembers; i++)
|
||||
{
|
||||
gtcb = sched_gettcb(group->tg_members[i]);
|
||||
DEBUGASSERT(gtcb);
|
||||
if (gtcb)
|
||||
{
|
||||
/* Use the sig_received interface so that it does not muck with
|
||||
* the siginfo_t.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
int ret = sig_received(gtcb, info);
|
||||
DEBUGASSERT(ret == 0);
|
||||
#else
|
||||
(void)sig_received(gtcb, info);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-enable pre-emption an return success */
|
||||
|
||||
sched_unlock();
|
||||
return OK;
|
||||
#else
|
||||
return -ENOSYS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: group_signalmember
|
||||
*
|
||||
* Description:
|
||||
* Send a signal to every member of the group to which task belongs.
|
||||
*
|
||||
* Parameters:
|
||||
* tcb - The tcb of one task in the task group that needs to be signalled.
|
||||
*
|
||||
* Return Value:
|
||||
* 0 (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
* Assumptions:
|
||||
* Called during task terminatino in a safe context. No special precautions
|
||||
* are required here.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
int group_signalmember(FAR _TCB *tcb, FAR siginfo_t *info)
|
||||
{
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
DEBUGASSERT(tcb);
|
||||
return group_signal(tcb->group, info);
|
||||
#else
|
||||
return sig_received(tcb, info);
|
||||
#endif
|
||||
}
|
||||
#endif /* HAVE_TASK_GROUP && !CONFIG_DISABLE_SIGNALS */
|
||||
@@ -124,7 +124,7 @@ int mq_verifysend(mqd_t mqdes, const void *msg, size_t msglen, int prio)
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (msglen < 0 || msglen > (size_t)mqdes->msgq->maxmsgsize)
|
||||
if (msglen > (size_t)mqdes->msgq->maxmsgsize)
|
||||
{
|
||||
set_errno(EMSGSIZE);
|
||||
return ERROR;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user