f8077022bd
* The appropriate size of stack varies among archs. E.g. for 64-bit sim, 2048 is way too small, especially when the task happens to use host OS functionalities. I plan to allow an arch provide its own default. * I plan to use this to replace hardcoded "STACKSIZE = 2048" in APPDIR.
1796 lines
60 KiB
Plaintext
1796 lines
60 KiB
Plaintext
#
|
|
# For a description of the syntax of this configuration file,
|
|
# see the file kconfig-language.txt in the NuttX tools repository.
|
|
#
|
|
|
|
menuconfig DISABLE_OS_API
|
|
bool "Disable NuttX interfaces"
|
|
default y
|
|
---help---
|
|
The following can be used to disable categories of
|
|
APIs supported by the OS. If the compiler supports
|
|
weak functions, then it should not be necessary to
|
|
disable functions unless you want to restrict usage
|
|
of those APIs.
|
|
|
|
There are certain dependency relationships in these
|
|
features.
|
|
|
|
1) mq_notify logic depends on signals to awaken tasks
|
|
waiting for queues to become full or empty.
|
|
2) pthread_condtimedwait() depends on signals to wake
|
|
up waiting tasks.
|
|
|
|
if DISABLE_OS_API
|
|
|
|
config DISABLE_POSIX_TIMERS
|
|
bool "Disable POSIX timers"
|
|
default y if DEFAULT_SMALL
|
|
default n if !DEFAULT_SMALL
|
|
---help---
|
|
Disable support for the the entire POSIX timer family
|
|
including timer_create(), timer_gettime(), timer_settime(),
|
|
etc.
|
|
|
|
NOTE: This option will also disable getitimer() and
|
|
setitimer() which are not, strictly speaking, POSIX timers.
|
|
|
|
config DISABLE_PTHREAD
|
|
bool "Disable pthread support"
|
|
default n
|
|
|
|
config DISABLE_MQUEUE
|
|
bool "Disable POSIX message queue support"
|
|
default n
|
|
|
|
config DISABLE_ENVIRON
|
|
bool "Disable environment variable support"
|
|
default y if DEFAULT_SMALL
|
|
default n if !DEFAULT_SMALL
|
|
|
|
endif # DISABLE_OS_API
|
|
|
|
menu "Clocks and Timers"
|
|
|
|
config ARCH_HAVE_TICKLESS
|
|
bool
|
|
|
|
config SCHED_TICKLESS
|
|
bool "Support tick-less OS"
|
|
default n
|
|
depends on ARCH_HAVE_TICKLESS
|
|
---help---
|
|
By default, system time is driven by a periodic timer interrupt. An
|
|
alternative configurations is a tick-less configuration in which
|
|
there is no periodic timer interrupt. Instead and interval timer is
|
|
used to schedule the next OS time event. This option selects that
|
|
tick-less OS option. If the tick-less OS is selected, then there are
|
|
additional platform specific interfaces that must be provided as
|
|
defined include/nuttx/arch.h
|
|
|
|
if SCHED_TICKLESS
|
|
|
|
config SCHED_TICKLESS_ALARM
|
|
bool "Tickless alarm"
|
|
default n
|
|
---help---
|
|
The tickless option can be supported either via a simple interval
|
|
timer (plus elapsed time) or via an alarm. The interval timer allows
|
|
programming events to occur after an interval. With the alarm,
|
|
you can set a time in the future and get an event when that alarm
|
|
goes off. This option selects the use of an alarm.
|
|
|
|
The advantage of an alarm is that it avoids some small timing
|
|
errors; the advantage of the use of the interval timer is that
|
|
the hardware requirement may be less.
|
|
|
|
config SCHED_TICKLESS_LIMIT_MAX_SLEEP
|
|
bool "Max sleep period (in microseconds)"
|
|
default n
|
|
---help---
|
|
Enables use of the g_oneshot_maxticks variable. This variable is
|
|
initialized by platform-specific logic at runtime to the maximum
|
|
delay that the timer can wait (in configured clock ticks). The
|
|
RTOS tickless logic will then limit all requested delays to this
|
|
value.
|
|
|
|
endif
|
|
|
|
config USEC_PER_TICK
|
|
int "System timer tick period (microseconds)"
|
|
default 10000 if !SCHED_TICKLESS
|
|
default 100 if SCHED_TICKLESS
|
|
---help---
|
|
In the "normal" configuration where system time is provided by a
|
|
periodic timer interrupt, the default system timer is expected to
|
|
run at 100Hz or USEC_PER_TICK=10000. This setting must be defined
|
|
to inform of NuttX the interval that the processor hardware is
|
|
providing system timer interrupts to the OS.
|
|
|
|
If SCHED_TICKLESS is selected, then there are no system timer
|
|
interrupts. In this case, USEC_PER_TICK does not control any timer
|
|
rates. Rather, it only determines the resolution of time reported
|
|
by clock_systimer() and the resolution of times that can be set for
|
|
certain delays including watchdog timers and delayed work. In this
|
|
case there is a trade-off: It is better to have the USEC_PER_TICK as
|
|
low as possible for higher timing resolution. However, the time
|
|
is currently held in 'unsigned int' on some systems, this may be
|
|
16-bits but on most contemporary systems it will be 32-bits. In
|
|
either case, smaller values of USEC_PER_TICK will reduce the range
|
|
of values that delays that can be represented. So the trade-off is
|
|
between range and resolution (you could also modify the code to use
|
|
a 64-bit value if you really want both).
|
|
|
|
The default, 100 microseconds, will provide for a range of delays
|
|
up to 120 hours.
|
|
|
|
This value should never be less than the underlying resolution of
|
|
the timer. Error may ensue.
|
|
|
|
if !SCHED_TICKLESS
|
|
|
|
config SYSTEMTICK_EXTCLK
|
|
bool "Use external clock"
|
|
default n
|
|
depends on ARCH_HAVE_EXTCLK
|
|
---help---
|
|
Use external clock for system tick. When enabled, the platform-specific
|
|
logic must start its own timer interrupt to make periodic calls to the
|
|
nxsched_process_timer() or the functions called within. The purpose is
|
|
to move the scheduling off the processor clock to allow entering low
|
|
power states that would disable that clock.
|
|
|
|
config SYSTEMTICK_HOOK
|
|
bool "System timer hook"
|
|
default n
|
|
---help---
|
|
Enable a call to a user-provided, board-level function on each timer
|
|
tick. This permits custom actions that may be performed on each
|
|
timer tick. The form of the user-provided function is:
|
|
|
|
void board_timerhook(void);
|
|
|
|
(prototyped in include/nuttx/board.h).
|
|
|
|
endif # !SCHED_TICKLESS
|
|
|
|
config SYSTEM_TIME64
|
|
bool "64-bit system clock"
|
|
default n
|
|
---help---
|
|
The system timer is incremented at the rate determined by
|
|
USEC_PER_TICK, typically at 100Hz. The count at any given time is
|
|
then the "uptime" in units of system timer ticks. By default, the
|
|
system time is 32-bits wide. Those defaults provide a range of about
|
|
497 days which is probably a sufficient range for "uptime".
|
|
|
|
However, if the system timer rate is significantly higher than 100Hz
|
|
and/or if a very long "uptime" is required, then this option can be
|
|
selected to support a 64-bit wide timer.
|
|
|
|
config CLOCK_MONOTONIC
|
|
bool "Support CLOCK_MONOTONIC"
|
|
default n
|
|
---help---
|
|
CLOCK_MONOTONIC is an optional standard POSIX clock. Unlike
|
|
CLOCK_REALTIME which can move forward and backward when the
|
|
time-of-day changes, CLOCK_MONOTONIC is the elapsed time since some
|
|
arbitrary point in the post (the system start-up time for NuttX)
|
|
and, hence, is always monotonically increasing. CLOCK_MONOTONIC
|
|
is, hence, the more appropriate clock for determining time
|
|
differences.
|
|
|
|
The value of the CLOCK_MONOTONIC clock cannot be set via clock_settime().
|
|
|
|
config ARCH_HAVE_TIMEKEEPING
|
|
bool
|
|
default n
|
|
|
|
config CLOCK_TIMEKEEPING
|
|
bool "Support timekeeping algorithms"
|
|
default n
|
|
depends on EXPERIMENTAL && ARCH_HAVE_TIMEKEEPING
|
|
---help---
|
|
CLOCK_TIMEKEEPING enables experimental time management algorithms.
|
|
|
|
config JULIAN_TIME
|
|
bool "Enables Julian time conversions"
|
|
default n
|
|
---help---
|
|
Enables Julian time conversions
|
|
|
|
config START_YEAR
|
|
int "Start year"
|
|
default 2018
|
|
range 1970 2106
|
|
---help---
|
|
NuttX uses an unsigned 32-bit integer for time_t which provides a
|
|
range from 1970 to 2106.
|
|
|
|
config START_MONTH
|
|
int "Start month"
|
|
default 1
|
|
range 1 12
|
|
|
|
config START_DAY
|
|
int "Start day"
|
|
default 1
|
|
range 1 31
|
|
|
|
config MAX_WDOGPARMS
|
|
int "Maximum number of watchdog parameters"
|
|
default 4
|
|
---help---
|
|
Maximum number of parameters that can be passed to a watchdog handler
|
|
|
|
config PREALLOC_WDOGS
|
|
int "Number of pre-allocated watchdog timers"
|
|
default 32
|
|
---help---
|
|
The number of pre-allocated watchdog structures. The system manages
|
|
a pool of preallocated watchdog structures to minimize dynamic
|
|
allocations. Dynamic allocations will still be made if this pool is
|
|
exhausted. You will, however, get better performance and memory
|
|
usage if this value is tuned to minimize such allocations.
|
|
|
|
config WDOG_INTRESERVE
|
|
int "Watchdog structures reserved for interrupt handlers"
|
|
default 4
|
|
---help---
|
|
Watchdog structures may be allocated from normal task and also from
|
|
interrupt handlers. Interrupt handlers, however, can only use pre-
|
|
allocated watchdog timer. So, in order to keep normal task
|
|
allocations from exhausting all watchdog structures, a small number
|
|
of pre-allocated watchdog timers must be reserved for exclusive use
|
|
by interrupt handler. This setting determines that number of
|
|
reserved watchdogs.
|
|
|
|
config PREALLOC_TIMERS
|
|
int "Number of pre-allocated POSIX timers"
|
|
default 8
|
|
---help---
|
|
The number of pre-allocated POSIX timer structures. The system manages a
|
|
pool of preallocated timer structures to minimize dynamic allocations. Set to
|
|
zero for all dynamic allocations.
|
|
|
|
endmenu # Clocks and Timers
|
|
|
|
menu "Tasks and Scheduling"
|
|
|
|
config SPINLOCK
|
|
bool "Support Spinlocks"
|
|
default n
|
|
depends on ARCH_HAVE_TESTSET
|
|
---help---
|
|
Enables support for spinlocks. Spinlocks are used primarily for
|
|
synchronization in SMP configurations but are available for general
|
|
synchronization between CPUs. Use in a single CPU configuration would
|
|
most likely be fatal. Note, however, that this does not depend on
|
|
CONFIG_ARCH_HAVE_MULTICPU. This permits the use of spinlocks in
|
|
other novel architectures.
|
|
|
|
config SPINLOCK_IRQ
|
|
bool "Support Spinlocks with IRQ control"
|
|
default n
|
|
depends on ARCH_GLOBAL_IRQDISABLE
|
|
---help---
|
|
Enables support for spinlocks with IRQ control. This feature can be
|
|
used to protect data in SMP mode.
|
|
|
|
config IRQCHAIN
|
|
bool "Enable multi handler sharing a IRQ"
|
|
default n
|
|
---help---
|
|
Enable support for IRQCHAIN.
|
|
|
|
if IRQCHAIN
|
|
|
|
config PREALLOC_IRQCHAIN
|
|
int "Number of pre-allocated irq chains"
|
|
default 8
|
|
---help---
|
|
The number of pre-allocated irq chain structures. The system manages
|
|
a pool of preallocated irq chain structures to minimize dynamic
|
|
allocations. You will, however, get better performance and memory
|
|
usage if this value is tuned to minimize such allocations.
|
|
|
|
endif # IRQCHAIN
|
|
|
|
config IRQCOUNT
|
|
bool
|
|
default n
|
|
|
|
config SMP
|
|
bool "Symmetric Multi-Processing (SMP)"
|
|
default n
|
|
depends on ARCH_HAVE_MULTICPU
|
|
select SPINLOCK
|
|
select SCHED_RESUMESCHEDULER
|
|
select IRQCOUNT
|
|
---help---
|
|
Enables support for Symmetric Multi-Processing (SMP) on a multi-CPU
|
|
platform.
|
|
|
|
if SMP
|
|
|
|
config SMP_NCPUS
|
|
int "Number of CPUs"
|
|
default 4
|
|
range 1 32 if DEBUG_FEATURES
|
|
range 2 32 if !DEBUG_FEATURES
|
|
---help---
|
|
This value identifies the number of CPUs supported by the processor
|
|
that will be used for SMP.
|
|
|
|
If CONFIG_DEBUG_FEATURES is enabled, then the value one is permitted
|
|
for CONFIG_SMP_NCPUS. This is not normally a valid setting for an
|
|
SMP configuration. However, running the SMP logic in a single CPU
|
|
configuration is useful during certain testing.
|
|
|
|
config SMP_IDLETHREAD_STACKSIZE
|
|
int "CPU IDLE stack size"
|
|
default DEFAULT_TASK_STACKSIZE
|
|
---help---
|
|
Each CPU will have its own IDLE task. System initialization occurs
|
|
on CPU0 and uses CONFIG_IDLETHREAD_STACKSIZE which will probably be
|
|
larger than is generally needed. This setting provides the stack
|
|
size for the IDLE task on CPUS 1 through (CONFIG_SMP_NCPUS-1).
|
|
|
|
endif # SMP
|
|
|
|
choice
|
|
prompt "Initialization Task"
|
|
default INIT_ENTRYPOINT if !BUILD_KERNEL
|
|
default INIT_FILEPATH if BUILD_KERNEL && !BINFMT_DISABLE
|
|
default INIT_NONE if BUILD_KERNEL && BINFMT_DISABLE
|
|
|
|
config INIT_NONE
|
|
bool "None"
|
|
|
|
config INIT_ENTRYPOINT
|
|
bool "Via application entry point"
|
|
depends on !BUILD_KERNEL
|
|
|
|
config INIT_FILEPATH
|
|
bool "Via executable file"
|
|
depends on !BINFMT_DISABLE
|
|
|
|
endchoice # Initialization task
|
|
|
|
if INIT_ENTRYPOINT
|
|
config USER_ENTRYPOINT
|
|
string "Application entry point"
|
|
default "main"
|
|
---help---
|
|
The name of the entry point for user applications. For the example
|
|
applications this is of the form 'app_main' where 'app' is the application
|
|
name. If not defined, USER_ENTRYPOINT defaults to "main".
|
|
|
|
config USERMAIN_PRIORITY
|
|
int "init thread priority"
|
|
default 100
|
|
---help---
|
|
The priority of the user initialization thread.
|
|
|
|
endif # INIT_ENTRYPOINT
|
|
|
|
if INIT_FILEPATH
|
|
|
|
config USER_INITPATH
|
|
string "Application initialization path"
|
|
default "/bin/init"
|
|
---help---
|
|
The name of the entry point for user applications. For the example
|
|
applications this is of the form 'app_main' where 'app' is the application
|
|
name. If not defined, USER_ENTRYPOINT defaults to "main".
|
|
|
|
config INIT_SYMTAB
|
|
string "Symbol table"
|
|
default "NULL" if !EXECFUNCS_HAVE_SYMTAB
|
|
default EXECFUNCS_SYMTAB_ARRAY if EXECFUNCS_HAVE_SYMTAB
|
|
depends on !BUILD_PROTECTED && !BUILD_KERNEL
|
|
---help---
|
|
The name of other global array that holds the exported symbol table.
|
|
The special string "NULL" may be provided if there is no symbol
|
|
table. Quotation marks will be stripped when config.h is generated.
|
|
|
|
NOTE: This setting cannot be used in protected or kernel builds.
|
|
Any kernel mode symbols tables would not be usable for resolving
|
|
symbols in user mode executables.
|
|
|
|
config INIT_NEXPORTS
|
|
string "Symbol table size"
|
|
default "0" if !EXECFUNCS_HAVE_SYMTAB
|
|
default EXECFUNCS_NSYMBOLS_VAR if EXECFUNCS_HAVE_SYMTAB
|
|
depends on !BUILD_PROTECTED && !BUILD_KERNEL
|
|
---help---
|
|
The size of the symbol table. NOTE that is is logically a numeric
|
|
value but is represent by a string. That allows you to put
|
|
sizeof(something) or a macro or a global variable name for the
|
|
symbol table size. Quotation marks will be stripped when config.h
|
|
is generated.
|
|
|
|
NOTE: This setting cannot be used in protected or kernel builds.
|
|
Any kernel mode symbols tables would not be usable for resolving
|
|
symbols in user mode executables.
|
|
|
|
menuconfig INIT_MOUNT
|
|
bool "Auto-mount init file system"
|
|
default n
|
|
depends on !DISABLE_MOUNTPOINT
|
|
---help---
|
|
In order to use the the initial startup program when CONFIG_INIT_FILEPATH
|
|
is provided, it is necessary to mount the initial file system that
|
|
provides init program. Normally this mount is done in the board-specific
|
|
initialization logic. However, if the mount is very simple, it can be
|
|
performed by the OS bring-up logic itself by selecting this option.
|
|
|
|
if INIT_MOUNT
|
|
|
|
config INIT_MOUNT_SOURCE
|
|
string "The block device to mount"
|
|
default "/dev/ram0"
|
|
|
|
config INIT_MOUNT_TARGET
|
|
string "Path to the mounted file system"
|
|
default "/bin"
|
|
|
|
config INIT_MOUNT_FSTYPE
|
|
string "The file system type to mount"
|
|
default "romfs"
|
|
|
|
config INIT_MOUNT_FLAGS
|
|
hex "Flags passed to mount"
|
|
default 0
|
|
|
|
config INIT_MOUNT_DATA
|
|
string "Additional data passed to mount"
|
|
default ""
|
|
|
|
endif # INIT_MOUNT
|
|
endif # INIT_FILEPATH
|
|
|
|
config RR_INTERVAL
|
|
int "Round robin timeslice (MSEC)"
|
|
default 0
|
|
---help---
|
|
The round robin timeslice will be set this number of milliseconds;
|
|
Round robin scheduling (SCHED_RR) is enabled by setting this
|
|
interval to a positive, non-zero value.
|
|
|
|
config SCHED_SPORADIC
|
|
bool "Support sporadic scheduling"
|
|
default n
|
|
select SCHED_SUSPENDSCHEDULER
|
|
select SCHED_RESUMESCHEDULER
|
|
---help---
|
|
Build in additional logic to support sporadic scheduling
|
|
(SCHED_SPORADIC).
|
|
|
|
if SCHED_SPORADIC
|
|
|
|
config SCHED_SPORADIC_MAXREPL
|
|
int "Maximum number of replenishments"
|
|
default 3
|
|
range 1 255
|
|
---help---
|
|
Controls the size of allocated replenishment structures and, hence,
|
|
also limits the maximum number of replenishments.
|
|
|
|
config SPORADIC_INSTRUMENTATION
|
|
bool "Sporadic scheduler monitor hooks"
|
|
default n
|
|
---help---
|
|
Enables instrumentation in the sporadic scheduler to monitor
|
|
scheduler behavior. If enabled, then the board-specific logic must
|
|
provide the following functions:
|
|
|
|
void arch_sporadic_start(FAR struct tcb_s *tcb);
|
|
void arch_sporadic_lowpriority(FAR struct tcb_s *tcb);
|
|
void arch_sporadic_suspend(FAR struct tcb_s *tcb);
|
|
void arch_sporadic_resume(FAR struct tcb_s *tcb);
|
|
|
|
endif # SCHED_SPORADIC
|
|
|
|
config TASK_NAME_SIZE
|
|
int "Maximum task name size"
|
|
default 31
|
|
---help---
|
|
Specifies the maximum size of a task name to save in the TCB.
|
|
Useful if scheduler instrumentation is selected. Set to zero to
|
|
disable. Excludes the NUL terminator; the actual allocated size
|
|
will be TASK_NAME_SIZE + 1. The default of 31 then results in
|
|
a align-able 32-byte allocation.
|
|
|
|
config MAX_TASKS
|
|
int "Max number of tasks"
|
|
default 32
|
|
---help---
|
|
The maximum number of simultaneously active tasks. This value must be
|
|
a power of two.
|
|
|
|
config SCHED_HAVE_PARENT
|
|
bool "Support parent/child task relationships"
|
|
default n
|
|
---help---
|
|
Remember the ID of the parent task when a new child task is
|
|
created. This support enables some additional features (such as
|
|
SIGCHLD) and modifies the behavior of other interfaces. For
|
|
example, it makes waitpid() more standards complete by restricting
|
|
the waited-for tasks to the children of the caller. Default:
|
|
disabled.
|
|
|
|
config SCHED_CHILD_STATUS
|
|
bool "Retain child exit status"
|
|
default n
|
|
depends on SCHED_HAVE_PARENT
|
|
---help---
|
|
If this option is selected, then the exit status of the child task
|
|
will be retained after the child task exits. This option should be
|
|
selected if you require knowledge of a child process's exit status.
|
|
Without this setting, wait(), waitpid() or waitid() may fail. For
|
|
example, if you do:
|
|
|
|
1) Start child task
|
|
2) Wait for exit status (using wait(), waitpid(), or waitid()).
|
|
|
|
This can fail because the child task may run to completion before
|
|
the wait begins. There is a non-standard work-around in this case:
|
|
The above sequence will work if you disable pre-emption using
|
|
sched_lock() prior to starting the child task, then re-enable pre-
|
|
emption with sched_unlock() after the wait completes. This works
|
|
because the child task is not permitted to run until the wait is in
|
|
place.
|
|
|
|
The standard solution would be to enable SCHED_CHILD_STATUS. In
|
|
this case the exit status of the child task is retained after the
|
|
child exits and the wait will successful obtain the child task's
|
|
exit status whether it is called before the child task exits or not.
|
|
|
|
Warning: If you enable this feature, then your application must
|
|
either (1) take responsibility for reaping the child status with wait(),
|
|
waitpid(), or waitid(), or (2) suppress retention of child status.
|
|
If you do not reap the child status, then you have a memory leak and
|
|
your system will eventually fail.
|
|
|
|
Retention of child status can be suppressed on the parent using logic like:
|
|
|
|
struct sigaction sa;
|
|
|
|
sa.sa_handler = SIG_IGN;
|
|
sa.sa_flags = SA_NOCLDWAIT;
|
|
int ret = sigaction(SIGCHLD, &sa, NULL);
|
|
|
|
if SCHED_CHILD_STATUS
|
|
|
|
config PREALLOC_CHILDSTATUS
|
|
int "Number of pre-allocated child status"
|
|
default 0
|
|
---help---
|
|
To prevent runaway child status allocations and to improve
|
|
allocation performance, child task exit status structures are pre-
|
|
allocated when the system boots. This setting determines the number
|
|
of child status structures that will be pre-allocated. If this
|
|
setting is not defined or if it is defined to be zero then a value
|
|
of 2*MAX_TASKS is used.
|
|
|
|
Note that there cannot be more than MAX_TASKS tasks in total.
|
|
However, the number of child status structures may need to be
|
|
significantly larger because this number includes the maximum number
|
|
of tasks that are running PLUS the number of tasks that have exit'ed
|
|
without having their exit status reaped (via wait(), waitid(), or
|
|
waitpid()).
|
|
|
|
Obviously, if tasks spawn children indefinitely and never have the
|
|
exit status reaped, then you may have a memory leak! If you enable
|
|
the SCHED_CHILD_STATUS feature, then your application must take
|
|
responsibility for either (1) reaping the child status with wait(),
|
|
waitpid(), or waitid() or it must (2) suppress retention of child
|
|
status. Otherwise, your system will eventually fail.
|
|
|
|
Retention of child status can be suppressed on the parent using logic like:
|
|
|
|
struct sigaction sa;
|
|
|
|
sa.sa_handler = SIG_IGN;
|
|
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_FEATURES
|
|
---help---
|
|
Very detailed... I am sure that you do not want this.
|
|
|
|
endif # SCHED_CHILD_STATUS
|
|
|
|
config SCHED_WAITPID
|
|
bool "Enable waitpid() API"
|
|
default n
|
|
---help---
|
|
Enables the waitpid() interface in a default, non-standard mode
|
|
(non-standard in the sense that the waited for PID need not be child
|
|
of the caller). If SCHED_HAVE_PARENT is also defined, then this
|
|
setting will modify the behavior or waitpid() (making more spec
|
|
compliant) and will enable the waitid() and wait() interfaces as
|
|
well.
|
|
|
|
config SCHED_EXIT_KILL_CHILDREN
|
|
bool "Enable kill all children when exit"
|
|
default n
|
|
depends on SCHED_HAVE_PARENT && SCHED_CHILD_STATUS
|
|
---help---
|
|
When a task exits, all of its child threads will be killed.
|
|
|
|
Caution: This selection should not be used unless you are certain
|
|
of what you are doing. Uninformed of this option can often lead to
|
|
memory leaks since, for example, memory allocations held by threads
|
|
are not automatically freed!
|
|
|
|
config SCHED_USER_IDENTITY
|
|
bool "Support per-task User Identity"
|
|
default n
|
|
---help---
|
|
This selection enables functionality of getuid(), setuid(), getgid(),
|
|
setgid(). If this option is not selected, then stub, root-only
|
|
versions of these interfaces are available. When selected, these
|
|
interfaces will associate a UID and/or GID with each task group.
|
|
Those can then be managed using the interfaces. Child tasks will
|
|
inherit the UID and GID of its parent.
|
|
|
|
endmenu # Tasks and Scheduling
|
|
|
|
menu "Pthread Options"
|
|
|
|
config NPTHREAD_KEYS
|
|
int "Maximum number of pthread keys"
|
|
default 4 if !DISABLE_PTHREAD
|
|
default 0 if DISABLE_PTHREAD
|
|
range 0 32
|
|
---help---
|
|
The number of items of thread-specific data that can be retained.
|
|
The value zero disables support for pthread-specific data.
|
|
|
|
if !DISABLE_PTHREAD
|
|
|
|
config PTHREAD_MUTEX_TYPES
|
|
bool "Enable mutex types"
|
|
default n
|
|
---help---
|
|
Set to enable support for recursive and errorcheck mutexes. Enables
|
|
pthread_mutexattr_settype().
|
|
|
|
choice
|
|
prompt "pthread mutex robustness"
|
|
default PTHREAD_MUTEX_ROBUST if !DEFAULT_SMALL
|
|
default PTHREAD_MUTEX_UNSAFE if DEFAULT_SMALL
|
|
|
|
config PTHREAD_MUTEX_ROBUST
|
|
bool "Robust mutexes"
|
|
---help---
|
|
Support only the robust form of the NORMAL mutex.
|
|
|
|
config PTHREAD_MUTEX_UNSAFE
|
|
bool "Traditional unsafe mutexes"
|
|
---help---
|
|
Support only the traditional non-robust form of the NORMAL mutex.
|
|
You should select this option only for backward compatibility with
|
|
software you may be porting or, perhaps, if you are trying to minimize
|
|
footprint.
|
|
|
|
config PTHREAD_MUTEX_BOTH
|
|
bool "Both robust and unsafe mutexes"
|
|
---help---
|
|
Support both forms of NORMAL mutexes.
|
|
|
|
endchoice # pthread mutex robustness
|
|
|
|
choice
|
|
prompt "Default NORMAL mutex robustness"
|
|
default PTHREAD_MUTEX_DEFAULT_ROBUST
|
|
depends on PTHREAD_MUTEX_BOTH
|
|
|
|
config PTHREAD_MUTEX_DEFAULT_ROBUST
|
|
bool "Robust default"
|
|
---help---
|
|
The default is robust NORMAL mutexes (non-standard)
|
|
|
|
config PTHREAD_MUTEX_DEFAULT_UNSAFE
|
|
bool "Unsafe default"
|
|
---help---
|
|
The default is traditional unsafe NORMAL mutexes (standard)
|
|
|
|
endchoice # Default NORMAL mutex robustness
|
|
|
|
config PTHREAD_CLEANUP
|
|
bool "pthread cleanup stack"
|
|
default n
|
|
---help---
|
|
Select to enable support for pthread exit cleanup stacks. This
|
|
enables the interfaces pthread_cleanup_push() and
|
|
pthread_cleanup_pop().
|
|
|
|
config PTHREAD_CLEANUP_STACKSIZE
|
|
int "pthread cleanup stack size"
|
|
default 1
|
|
range 1 32
|
|
depends on PTHREAD_CLEANUP
|
|
---help---
|
|
The maximum number of cleanup actions that may be pushed by
|
|
pthread_clean_push(). This setting will increase the size of EVERY
|
|
pthread task control block by about n * CONFIG_PTHREAD_CLEANUP_STACKSIZE
|
|
where n is the size of a pointer, 2* sizeof(uintptr_t), this would be
|
|
8 for a CPU with 32-bit addressing and 4 for a CPU with 16-bit
|
|
addressing.
|
|
|
|
config CANCELLATION_POINTS
|
|
bool "Cancellation points"
|
|
default n
|
|
---help---
|
|
Enable POSIX cancellation points for pthread_cancel(). If selected,
|
|
cancellation points will also used with the () task_delete() API even if
|
|
pthreads are not enabled.
|
|
|
|
endif # !DISABLE_PTHREAD
|
|
|
|
endmenu # Pthread Options
|
|
|
|
menu "Performance Monitoring"
|
|
|
|
config SCHED_SUSPENDSCHEDULER
|
|
bool
|
|
default n
|
|
|
|
config SCHED_RESUMESCHEDULER
|
|
bool
|
|
default n
|
|
|
|
config SCHED_IRQMONITOR
|
|
bool "Enable IRQ monitoring"
|
|
default n
|
|
depends on FS_PROCFS
|
|
---help---
|
|
Enabling counting of interrupts from all interrupt sources. These
|
|
counts will be available in the mounted procfs file systems at the
|
|
top-level file, "irqs".
|
|
|
|
config SCHED_CRITMONITOR
|
|
bool "Enable Critical Section monitoring"
|
|
default n
|
|
depends on FS_PROCFS
|
|
select SCHED_SUSPENDSCHEDULER
|
|
select SCHED_RESUMESCHEDULER
|
|
select IRQCOUNT
|
|
---help---
|
|
Enables logic that monitors the duration of time that a thread keeps
|
|
interrupts or pre-emption disabled. These global locks can have
|
|
negative consequences to real timer performance: Disabling interrupts
|
|
adds jitter in the time when a interrupt request is asserted until
|
|
the hardware can responds with the interrupt. Disabling pre-emption
|
|
adds jitter in the timer from when the event is posted in the
|
|
interrupt handler until the task that responds to the event can run.
|
|
|
|
If this option is selected, then the following interfaces must be
|
|
provided by platform-specific logic:
|
|
|
|
uint32_t up_critmon_gettime(void);
|
|
void up_critmon_convert(uint32_t elapsed, FAR struct timespec *ts);
|
|
|
|
The first interface simply provides the current time value in unknown
|
|
units. NOTE: This function may be called early before the timer has
|
|
been initialized. In that event, the function should just return a
|
|
start time of zero.
|
|
|
|
Nothing is assumed about the units of this time value. The following
|
|
are assumed, however: (1) The time is an unsigned integer value, (2)
|
|
the time is monotonically increasing, and (3) the elapsed time (also
|
|
in unknown units) can be obtained by subtracting a start time from
|
|
the current time.
|
|
|
|
The second interface simple converts an elapsed time into well known
|
|
units for presentation by the ProcFS file system.
|
|
|
|
config SCHED_CPULOAD
|
|
bool "Enable CPU load monitoring"
|
|
default n
|
|
select SCHED_CPULOAD_EXTCLK if SCHED_TICKLESS
|
|
---help---
|
|
If this option is selected, the timer interrupt handler will monitor
|
|
if the system is IDLE or busy at the time of that the timer interrupt
|
|
occurs. This is a very coarse measurement, but over a period of time,
|
|
it can very accurately determined the percentage of the time that the
|
|
CPU is IDLE.
|
|
|
|
The statistics collected in this could be used, for example in the
|
|
PROCFS file system to provide CPU load measurements when read.
|
|
|
|
Note that in tickless mode of operation (SCHED_TICKLESS) there is
|
|
no system timer interrupt and CPU load measurements will not be
|
|
possible unless you provide an alternative clock to driver the
|
|
sampling and select SCHED_CPULOAD_EXTCLK.
|
|
|
|
if SCHED_CPULOAD
|
|
|
|
config SCHED_CPULOAD_EXTCLK
|
|
bool "Use external clock"
|
|
default n
|
|
---help---
|
|
The CPU load measurements are determined by sampling the active
|
|
tasks periodically at the occurrence to a timer expiration. By
|
|
default, the system clock is used to do that sampling.
|
|
|
|
There is a serious issue for the accuracy of measurements if the
|
|
system clock is used, however. NuttX threads are often started at
|
|
the time of the system timer expiration. Others may be stopped at
|
|
the time of the system timer expiration (if round-robin time-slicing
|
|
is enabled). Such thread behavior occurs synchronously with the
|
|
system timer and, hence, is not randomly sampled. As a consequence,
|
|
the CPU load attributed to these threads that run synchronously with
|
|
they system timer may be grossly in error.
|
|
|
|
The solution is to use some other clock that runs at a different
|
|
rate and has timer expirations that are asynchronous with the
|
|
system timer. Then truly accurate load measurements can be
|
|
achieved. This option enables use of such an "external" clock. The
|
|
implementation of the clock must be provided by platform-specific
|
|
logic; that platform-specific logic must call the system function
|
|
nxsched_process_cpuload() at each timer expiration with interrupts
|
|
disabled.
|
|
|
|
if SCHED_CPULOAD_EXTCLK
|
|
|
|
config SCHED_CPULOAD_TICKSPERSEC
|
|
int "External clock rate"
|
|
default 100
|
|
---help---
|
|
If an external clock is used to drive the sampling for the CPU load
|
|
calculations, then this value must be provided. This value provides
|
|
the rate of the external clock interrupts in units of ticks per
|
|
second. The default value of 100 corresponds to a 100Hz clock. NOTE:
|
|
that 100Hz is the default frequency of the system time and, hence,
|
|
the worst possible choice in most cases.
|
|
|
|
choice
|
|
prompt "Select CPU load timer"
|
|
default CPULOAD_ONESHOT
|
|
|
|
config CPULOAD_ONESHOT
|
|
bool "Use Oneshot timer"
|
|
---help---
|
|
Use an MCU-specific oneshot timer as the external clock. The
|
|
oneshot timer must be configured by board specific logic which must
|
|
then call:
|
|
|
|
void sched_oneshot_extclk(FAR struct oneshot_lowerhalf_s *lower);
|
|
|
|
To start the CPU load measurement. See include/nuttx/clock.h
|
|
|
|
NOTE that in this configuration, CONFIG_SCHED_CPULOAD_TICKSPERSEC is
|
|
the sample rate that will be accomplished by programming the oneshot
|
|
time repeatedly. If CPULOAD_ONESHOT_ENTROPY is also selected, then
|
|
the underly frequency driving the oneshot timer must be
|
|
significantly faster than CONFIG_SCHED_CPULOAD_TICKSPERSE to permit
|
|
precise modulation the sample periods.
|
|
|
|
config CPULOAD_PERIOD
|
|
bool "Use Period timer"
|
|
---help---
|
|
Use an MCU-specific period timer as the external clock. The
|
|
period timer must be configured by board specific logic which must
|
|
then call:
|
|
|
|
void sched_period_extclk(FAR struct timer_lowerhalf_s *lower);
|
|
|
|
To start the CPU load measurement. See include/nuttx/clock.h
|
|
|
|
NOTE that in this configuration, CONFIG_SCHED_CPULOAD_TICKSPERSEC is
|
|
the sample rate that will be accomplished by programming the period
|
|
time.
|
|
|
|
endchoice
|
|
|
|
config CPULOAD_ENTROPY
|
|
int "Bits of entropy"
|
|
default 6
|
|
range 0 30
|
|
depends on CPULOAD_ONESHOT
|
|
---help---
|
|
This is the number of bits of entropy that will be applied. The
|
|
oneshot will be set to this interval:
|
|
|
|
CPULOAD_ONESHOT_NOMINAL - (CPULOAD_ONESHOT_ENTROPY / 2) +
|
|
error + nrand(CPULOAD_ONESHOT_ENTROPY)
|
|
|
|
Where
|
|
|
|
CPULOAD_ONESHOT_NOMINAL is the nominal sample interval implied
|
|
by CONFIG_SCHED_CPULOAD_TICKSPERSEC in units of microseconds.
|
|
CPULOAD_ONESHOT_ENTROPY is (1 << CONFIG_CPULOAD_ENTROPY),
|
|
and 'error' is an error value that is retained from interval to
|
|
interval so that although individual intervals are randomized,
|
|
the average will still be CONFIG_SCHED_CPULOAD_TICKSPERSEC.
|
|
|
|
This special value of zero disables entropy.
|
|
|
|
endif # SCHED_CPULOAD_EXTCLK
|
|
|
|
config SCHED_CPULOAD_TIMECONSTANT
|
|
int "CPU load time constant"
|
|
default 2
|
|
---help---
|
|
The accumulated CPU count is divided by two when the accumulated
|
|
tick count exceeds this time constant. This time constant is in
|
|
units of seconds.
|
|
|
|
endif # SCHED_CPULOAD
|
|
|
|
config SCHED_INSTRUMENTATION
|
|
bool "System performance monitor hooks"
|
|
default n
|
|
select SCHED_SUSPENDSCHEDULER
|
|
select SCHED_RESUMESCHEDULER
|
|
---help---
|
|
Enables instrumentation in scheduler to monitor system performance.
|
|
If enabled, then the board-specific logic must provide the following
|
|
functions (see include/sched.h):
|
|
|
|
void sched_note_start(FAR struct tcb_s *tcb);
|
|
void sched_note_stop(FAR struct tcb_s *tcb);
|
|
void sched_note_suspend(FAR struct tcb_s *tcb);
|
|
void sched_note_resume(FAR struct tcb_s *tcb);
|
|
|
|
If CONFIG_SMP is enabled, then these additional interfaces are
|
|
expected:
|
|
|
|
void sched_note_cpu_pause(FAR struct tcb_s *tcb, int cpu);
|
|
void sched_note_cpu_paused(FAR struct tcb_s *tcb);
|
|
void sched_note_cpu_resume(FAR struct tcb_s *tcb, int cpu);
|
|
void sched_note_cpu_resumed(FAR struct tcb_s *tcb);
|
|
|
|
NOTE: These are internal OS interfaces and are called at at very
|
|
critical locations in the OS. There is very little that can be
|
|
done in these interfaces. For example, normal devices may not be
|
|
used; syslog output cannot be performed.
|
|
|
|
An option is to use SCHED_INSTRUMENTATION_BUFFER below.
|
|
|
|
if SCHED_INSTRUMENTATION
|
|
|
|
config SCHED_INSTRUMENTATION_CPUSET
|
|
hex "CPU bit set"
|
|
default 0xffff
|
|
depends on SMP
|
|
---help---
|
|
Monitor only CPUs in the bitset. Bit 0=CPU0, Bit1=CPU1, etc.
|
|
|
|
config SCHED_INSTRUMENTATION_PREEMPTION
|
|
bool "Preemption monitor hooks"
|
|
default n
|
|
---help---
|
|
Enables additional hooks for changes to pre-emption state. Board-
|
|
specific logic must provide this additional logic.
|
|
|
|
void sched_note_premption(FAR struct tcb_s *tcb, bool state);
|
|
|
|
config SCHED_INSTRUMENTATION_CSECTION
|
|
bool "Critical section monitor hooks"
|
|
default n
|
|
select IRQCOUNT
|
|
---help---
|
|
Enables additional hooks for entry and exit from critical sections.
|
|
Interrupts are disabled while within a critical section. Board-
|
|
specific logic must provide this additional logic.
|
|
|
|
void sched_note_csection(FAR struct tcb_s *tcb, bool state);
|
|
|
|
config SCHED_INSTRUMENTATION_SPINLOCKS
|
|
bool "Spinlock monitor hooks"
|
|
default n
|
|
---help---
|
|
Enables additional hooks for spinlock state. Board-specific logic
|
|
must provide this additional logic.
|
|
|
|
void sched_note_spinlock(FAR struct tcb_s *tcb, bool state);
|
|
void sched_note_spinlocked(FAR struct tcb_s *tcb, bool state);
|
|
void sched_note_spinunlock(FAR struct tcb_s *tcb, bool state);
|
|
void sched_note_spinabort(FAR struct tcb_s *tcb, bool state);
|
|
|
|
config SCHED_INSTRUMENTATION_BUFFER
|
|
bool "Buffer instrumentation data in memory"
|
|
default n
|
|
---help---
|
|
If this option is selected, then in-memory buffering logic is
|
|
enabled to capture scheduler instrumentation data. This has
|
|
the advantage that (1) the platform logic does not have to provide
|
|
the sched_note_* interfaces described for the previous settings.
|
|
Instead, the buffering logic catches all of these. It encodes
|
|
timestamps the scheduler note and adds the note to an in-memory,
|
|
circular buffer. And (2) buffering the scheduler instrumentation
|
|
data (versus performing some output operation) minimizes the impact
|
|
of the instrumentation on the behavior of the system.
|
|
|
|
If the in-memory buffer becomes full, then older notes are
|
|
overwritten by newer notes. The following interface is provided:
|
|
|
|
ssize_t sched_note_get(FAR uint8_t *buffer, size_t buflen);
|
|
|
|
Platform specific information must call this function and dispose
|
|
of it quickly so that overwriting of the tail of the circular buffer
|
|
does not occur. See include/nuttx/sched_note.h for additional
|
|
information.
|
|
|
|
if SCHED_INSTRUMENTATION_BUFFER
|
|
|
|
config SCHED_NOTE_BUFSIZE
|
|
int "Instrumentation buffer size"
|
|
default 2048
|
|
---help---
|
|
The size of the in-memory, circular instrumentation buffer (in
|
|
bytes).
|
|
|
|
config SCHED_NOTE_GET
|
|
bool "Callable interface to get instrumentatin data"
|
|
default n
|
|
depends on !SCHED_INSTRUMENTATION_CSECTION && (!SCHED_INSTRUMENTATION_SPINLOCK || !SMP)
|
|
---help---
|
|
Add support for interfaces to get the size of the next note and also
|
|
to extract the next note from the instrumentation buffer:
|
|
|
|
ssize_t sched_note_get(FAR uint8_t *buffer, size_t buflen);
|
|
ssize_t sched_note_size(void);
|
|
|
|
NOTE: This option is not available if critical sections are being
|
|
monitor (nor if spinlocks are being monitored in SMP configuration)
|
|
because there would be a logical error in the design in those cases.
|
|
That error is that these interfaces call enter_ and leave_critical_section
|
|
(and which us spinlocks in SMP mode). That means that each call to
|
|
sched_note_get() causes several additional entries to be added from
|
|
the note buffer in order to remove one entry.
|
|
|
|
endif # SCHED_INSTRUMENTATION_BUFFER
|
|
endif # SCHED_INSTRUMENTATION
|
|
endmenu # Performance Monitoring
|
|
|
|
menu "Files and I/O"
|
|
|
|
config DEV_CONSOLE
|
|
bool "Enable /dev/console"
|
|
default y
|
|
---help---
|
|
Set if architecture-specific logic provides /dev/console at boot-up
|
|
time. Enables stdout, stderr, stdin in the start-up application.
|
|
|
|
You need this setting if your console device is ready at boot time.
|
|
For example, if you are using a serial console, then /dev/console
|
|
(aka, /dev/ttyS0) will be available when the application first starts.
|
|
|
|
You must not select DEV_CONSOLE if you console device comes up later
|
|
and is not ready until after the application starts. At this time,
|
|
the only console device that behaves this way is a USB serial console.
|
|
When the application first starts, the USB is (probably) not yet
|
|
connected and /dev/console will not be created until later when the
|
|
host connects to the USB console.
|
|
|
|
config FDCLONE_DISABLE
|
|
bool "Disable cloning of file descriptors"
|
|
default n
|
|
---help---
|
|
Disable cloning of all file descriptors by task_create() when a new
|
|
ask is started. If set, all files/drivers will appear to be closed
|
|
in the new task.
|
|
|
|
config FDCLONE_STDIO
|
|
bool "Disable clone file descriptors without stdio"
|
|
default n
|
|
---help---
|
|
Disable cloning of all but the first three file descriptors (stdin,
|
|
stdout, stderr) by task_create() when a new task is started. If set,
|
|
all files/drivers will appear to be closed in the new task except
|
|
for stdin, stdout, and stderr.
|
|
|
|
config SDCLONE_DISABLE
|
|
bool "Disable cloning of socket descriptors"
|
|
default n
|
|
---help---
|
|
Disable cloning of all socket
|
|
descriptors by task_create() when a new task is started. If
|
|
set, all sockets will appear to be closed in the new task.
|
|
|
|
config NFILE_DESCRIPTORS
|
|
int "Maximum number of file descriptors per task"
|
|
default 16
|
|
range 3 99999
|
|
---help---
|
|
The maximum number of file descriptors per task (one for each open)
|
|
|
|
config NFILE_STREAMS
|
|
int "Maximum number of FILE streams"
|
|
default 16
|
|
---help---
|
|
The maximum number of streams that can be fopen'ed
|
|
|
|
config NAME_MAX
|
|
int "Maximum size of a file name"
|
|
default 32
|
|
---help---
|
|
The maximum size of a file name.
|
|
|
|
config PATH_MAX
|
|
int "Maximum size of path name"
|
|
default 256
|
|
---help---
|
|
The maximum size of path name.
|
|
|
|
endmenu # Files and I/O
|
|
|
|
menuconfig PRIORITY_INHERITANCE
|
|
bool "Enable priority inheritance "
|
|
default n
|
|
---help---
|
|
Set to enable support for priority inheritance on mutexes and semaphores.
|
|
When this option is enabled, the initial configuration of all seamphores
|
|
and mutexes will be with priority inheritance enabled. That configuration
|
|
may not be appropriate in all cases (such as when the semaphore or mutex
|
|
is used for signaling). In such cases, priority inheritance can be
|
|
disabled for individual semaphores by calling:
|
|
|
|
int ret = sem_setprotocol(&sem, SEM_PRIO_NONE);
|
|
|
|
From applications, the functionally equivalent OS internal interface,
|
|
nxsem_setprotocol(), should be used within the OS
|
|
|
|
And for individual pthread mutexes by setting the protocol attribute
|
|
before initializing the mutex:
|
|
|
|
int ret = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_NONE);
|
|
|
|
if PRIORITY_INHERITANCE
|
|
|
|
config SEM_PREALLOCHOLDERS
|
|
int "Number of pre-allocated holders"
|
|
default 16
|
|
---help---
|
|
This setting is only used if priority inheritance is enabled.
|
|
It defines the maximum number of different threads (minus one) that
|
|
can take counts on a semaphore with priority inheritance support.
|
|
This may be set to zero if priority inheritance is disabled OR if you
|
|
are only using semaphores as mutexes (only one holder) OR if no more
|
|
than two threads participate using a counting semaphore.
|
|
|
|
config SEM_NNESTPRIO
|
|
int "Maximum number of higher priority threads"
|
|
default 16
|
|
---help---
|
|
If priority inheritance is enabled, then this setting is the
|
|
maximum number of higher priority threads (minus 1) than can be
|
|
waiting for another thread to release a count on a semaphore.
|
|
This value may be set to zero if no more than one thread is
|
|
expected to wait for a semaphore.
|
|
|
|
endif # PRIORITY_INHERITANCE
|
|
|
|
menu "RTOS hooks"
|
|
|
|
config BOARD_EARLY_INITIALIZE
|
|
bool "Custom board early initialization"
|
|
default n
|
|
---help---
|
|
There are three points in time where you can insert custom,
|
|
board-specific initialization logic:
|
|
|
|
1) <arch>_board_initialize(): This function is used only for
|
|
initialization of very low-level things like configuration of
|
|
GPIO pins, power setting. The OS has not been initialized
|
|
at this point, so you cannot allocate memory or initialize
|
|
device drivers at this phase.
|
|
|
|
2) The next level of initialization is performed by a call to
|
|
up_initialize() (in arch/<arch>/src/common/up_initialize.c).
|
|
The OS has been initialized at this point and it is okay to
|
|
initialize drivers in this phase.
|
|
|
|
At this same point in time, the OS will also call a board-
|
|
specific initialization function named board_early_initialize()
|
|
if CONFIG_BOARD_EARLY_INITIALIZE is selected. The context in
|
|
which board_early_initialize() executes is suitable for early
|
|
initialization of most, simple device drivers and is a logical,
|
|
board-specific extension of up_initialize().
|
|
|
|
board_early_initialize() runs on the startup, initialization thread.
|
|
Some initialization operations cannot be performed on the start-up,
|
|
initialization thread. That is because the initialization thread
|
|
cannot wait for event. Waiting may be required, for example, to
|
|
mount a file system or or initialize a device such as an SD card.
|
|
For this reason, such driver initialize must be deferred to
|
|
board_late_initialize().
|
|
|
|
3) And, finally, just before the user application code starts.
|
|
|
|
If CONFIG_BOARD_LATE_INITIALIZE is selected, then an additional
|
|
initialization call will be performed in the boot-up sequence to a
|
|
function called board_late_initialize(). board_late_initialize()
|
|
will be called after up_initialize() is called and just before the
|
|
main application is started. This additional initialization
|
|
phase may be used, for example, to initialize more complex,
|
|
board-specific device drivers.
|
|
|
|
Waiting for events, use of I2C, SPI, etc are permissible in the
|
|
context of board_late_initialize(). That is because
|
|
board_late_initialize() will run on a temporary, internal kernel
|
|
thread.
|
|
|
|
config BOARD_LATE_INITIALIZE
|
|
bool "Custom board late initialization"
|
|
default n
|
|
---help---
|
|
There are three points in time where you can insert custom,
|
|
board-specific initialization logic:
|
|
|
|
1) <arch>_board_initialize(): This function is used only for
|
|
initialization of very low-level things like configuration of
|
|
GPIO pins, power setting. The OS has not been initialized
|
|
at this point, so you cannot allocate memory or initialize
|
|
device drivers at this phase.
|
|
|
|
2) The next level of initialization is performed by a call to
|
|
up_initialize() (in arch/<arch>/src/common/up_initialize.c).
|
|
The OS has been initialized at this point and it is okay to
|
|
initialize drivers in this phase.
|
|
|
|
At this same point in time, the OS will also call a board-
|
|
specific initialization function named board_early_initialize()
|
|
if CONFIG_BOARD_EARLY_INITIALIZE is selected. The context in
|
|
which board_early_initialize() executes is suitable for early
|
|
initialization of most, simple device drivers and is a logical,
|
|
board-specific extension of up_initialize().
|
|
|
|
board_early_initialize() runs on the startup, initialization thread.
|
|
Some initialization operations cannot be performed on the start-up,
|
|
initialization thread. That is because the initialization thread
|
|
cannot wait for event. Waiting may be required, for example, to
|
|
mount a file system or or initialize a device such as an SD card.
|
|
For this reason, such driver initialize must be deferred to
|
|
board_late_initialize().
|
|
|
|
3) And, finally, just before the user application code starts.
|
|
|
|
If CONFIG_BOARD_LATE_INITIALIZE is selected, then an additional
|
|
initialization call will be performed in the boot-up sequence to a
|
|
function called board_late_initialize(). board_late_initialize()
|
|
will be called after up_initialize() is called and just before the
|
|
main application is started. This additional initialization
|
|
phase may be used, for example, to initialize more complex,
|
|
board-specific device drivers.
|
|
|
|
Waiting for events, use of I2C, SPI, etc are permissible in the
|
|
context of board_late_initialize(). That is because
|
|
board_late_initialize() will run on a temporary, internal kernel
|
|
thread.
|
|
|
|
if BOARD_LATE_INITIALIZE
|
|
|
|
config BOARD_INITTHREAD_STACKSIZE
|
|
int "Board initialization thread stack size"
|
|
default DEFAULT_TASK_STACKSIZE
|
|
---help---
|
|
The size of the stack to allocate when starting the board
|
|
initialization thread.
|
|
|
|
config BOARD_INITTHREAD_PRIORITY
|
|
int "Board initialization thread priority"
|
|
default 240
|
|
---help---
|
|
The priority of the board initialization thread. This priority is
|
|
not a critical setting. No other application threads will be
|
|
started until the board initialization is completed. Hence, there
|
|
is very little competition for the CPU.
|
|
|
|
endif # BOARD_LATE_INITIALIZE
|
|
|
|
config SCHED_STARTHOOK
|
|
bool "Enable startup hook"
|
|
default n
|
|
---help---
|
|
Enable a non-standard, internal OS API call nxtask_starthook().
|
|
nxtask_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
|
|
---help---
|
|
Enables the atexit() API
|
|
|
|
config SCHED_ATEXIT_MAX
|
|
int "Max number of atexit() functions"
|
|
default 1
|
|
depends on SCHED_ATEXIT && !SCHED_ONEXIT
|
|
---help---
|
|
By default if SCHED_ATEXIT is selected, only a single atexit() function
|
|
is supported. That number can be increased by defined this setting to
|
|
the number that you require.
|
|
|
|
If both SCHED_ONEXIT and SCHED_ATEXIT are selected, then atexit() is built
|
|
on top of the on_exit() implementation. In that case, SCHED_ONEXIT_MAX
|
|
determines the size of the combined number of atexit(0) and on_exit calls
|
|
and SCHED_ATEXIT_MAX is not used.
|
|
|
|
config SCHED_ONEXIT
|
|
bool "Enable on_exit() API"
|
|
default n
|
|
---help---
|
|
Enables the on_exit() API
|
|
|
|
config SCHED_ONEXIT_MAX
|
|
int "Max number of on_exit() functions"
|
|
default 1
|
|
depends on SCHED_ONEXIT
|
|
---help---
|
|
By default if SCHED_ONEXIT is selected, only a single on_exit() function
|
|
is supported. That number can be increased by defined this setting to the
|
|
number that you require.
|
|
|
|
If both SCHED_ONEXIT and SCHED_ATEXIT are selected, then atexit() is built
|
|
on top of the on_exit() implementation. In that case, SCHED_ONEXIT_MAX
|
|
determines the size of the combined number of atexit(0) and on_exit calls.
|
|
|
|
endmenu # RTOS hooks
|
|
|
|
menu "Signal Configuration"
|
|
|
|
config SIG_EVTHREAD
|
|
bool "Support SIGEV_THHREAD"
|
|
default n
|
|
depends on BUILD_FLAT && SCHED_WORKQUEUE
|
|
---help---
|
|
Built in support for the SIGEV_THREAD signal deliver method.
|
|
|
|
NOTE: The current implementation uses a work queue to notify the
|
|
client. This, however, would only work in the FLAT build. A
|
|
different mechanism would need to be development to support this
|
|
feature on the PROTECTED or KERNEL build.
|
|
|
|
config SIG_EVTHREAD_HPWORK
|
|
bool "SIGEV_EVTHREAD use HPWORK"
|
|
default n
|
|
depends on SIG_EVTHREAD && CONFIG_SCHED_HPWORK
|
|
---help---
|
|
if selected, SIGEV_THHREAD will use the high priority work queue.
|
|
If not, it will use the low priority work queue (if available).
|
|
|
|
REVISIT: This solution is non-optimal. Some notifications should
|
|
be high priority and others should be lower priority. Ideally, you
|
|
should be able to determine which work queue is used on a
|
|
notification-by-notification basis.
|
|
|
|
menuconfig SIG_DEFAULT
|
|
bool "Default signal actions"
|
|
default n
|
|
---help---
|
|
Enable to support default signal actions.
|
|
|
|
if SIG_DEFAULT
|
|
|
|
comment "Per-signal Default Actions"
|
|
|
|
config SIG_SIGUSR1_ACTION
|
|
bool "SIGUSR1"
|
|
default n
|
|
---help---
|
|
Enable the default action for SIGUSR1 (terminate the task)
|
|
Make sure that your applications are expecting this POSIX behavior.
|
|
Backward compatible behavior would require that the application use
|
|
sigaction() to ignore SIGUSR1.
|
|
|
|
config SIG_SIGUSR2_ACTION
|
|
bool "SIGUSR2"
|
|
default n
|
|
---help---
|
|
Enable the default action for SIGUSR2 (terminate the task)
|
|
Make sure that your applications are expecting this POSIX behavior.
|
|
Backward compatible behavior would require that the application use
|
|
sigaction() to ignore SIGUSR2.
|
|
|
|
config SIG_SIGALRM_ACTION
|
|
bool "SIGALRM"
|
|
default n
|
|
---help---
|
|
Enable the default action for SIGALRM (terminate the task)
|
|
Make sure that your applications are expecting this POSIX behavior.
|
|
Backward compatible behavior would require that the application use
|
|
sigaction() to ignore SIGALRM.
|
|
|
|
config SIG_SIGPOLL_ACTION
|
|
bool "SIGPOLL"
|
|
default n
|
|
depends on FS_AIO
|
|
---help---
|
|
Enable the default action for SIGPOLL (terminate the task)
|
|
Make sure that your applications are expecting this POSIX behavior.
|
|
Backward compatible behavior would require that the application use
|
|
sigaction() to ignore SIGPOLL.
|
|
|
|
config SIG_SIGSTOP_ACTION
|
|
bool "SIGSTOP SIGSTP, and SIGCONT"
|
|
default y
|
|
---help---
|
|
Enable the default action for SIGSTOP and SIGSTP (suspend the
|
|
task) and SIGCONT (resume the task).
|
|
|
|
config SIG_SIGKILL_ACTION
|
|
bool "SIGINT and SIGKILL"
|
|
default y
|
|
---help---
|
|
Enable the default action for SIGINT and SIGKILL (terminate the
|
|
task).
|
|
|
|
config SIG_SIGPIPE_ACTION
|
|
bool "SIGPIPE"
|
|
default y
|
|
---help---
|
|
Enable the default action for SIGPIPE (terminate the task).
|
|
|
|
endif # SIG_DEFAULT
|
|
|
|
menu "Signal Numbers"
|
|
|
|
comment "Standard Signal Numbers"
|
|
|
|
config SIG_SIGUSR1
|
|
int "SIGUSR1"
|
|
default 1
|
|
---help---
|
|
Value of standard user signal 1 (SIGUSR1). Default: 1
|
|
|
|
config SIG_SIGUSR2
|
|
int "SIGUSR2"
|
|
default 2
|
|
---help---
|
|
Value of standard user signal 2 (SIGUSR2). Default: 2
|
|
|
|
config SIG_SIGALRM
|
|
int "SIGALRM"
|
|
default 3
|
|
---help---
|
|
Default the signal number used with POSIX timers (SIGALRM).
|
|
Default: 3
|
|
|
|
config SIG_SIGCHLD
|
|
int "SIGCHLD"
|
|
default 4
|
|
depends on SCHED_HAVE_PARENT
|
|
---help---
|
|
The SIGCHLD signal is sent to the parent of a child process when it
|
|
exits, is interrupted (stopped), or resumes after being interrupted.
|
|
Default: 4
|
|
|
|
config SIG_POLL
|
|
int "SIGPOLL"
|
|
default 5
|
|
depends on FS_AIO
|
|
---help---
|
|
The SIGPOLL signal is sent to a process when an asynchronous I/O
|
|
event occurs (meaning it has been polled). Default: 5
|
|
|
|
if SIG_DEFAULT
|
|
|
|
config SIG_STOP
|
|
int "SIGSTOP"
|
|
default 6
|
|
depends on SIG_SIGSTOP_ACTION
|
|
---help---
|
|
Suspend/pause a task. SIGSTOP may not be caught or ignored.
|
|
|
|
config SIG_STP
|
|
int "SIGSTP"
|
|
default 7
|
|
depends on SIG_SIGSTOP_ACTION
|
|
---help---
|
|
Suspend/pause a task. Unlike SIGSTOP, this signal can be caught or
|
|
ignored.
|
|
|
|
config SIG_CONT
|
|
int "SIGCONT"
|
|
default 8
|
|
depends on SIG_SIGSTOP_ACTION
|
|
---help---
|
|
Resume a suspended/paused task. SIGSTOP only has an action when
|
|
send to a stopped task. SIGCONT is ignored by other task. SIGCONT
|
|
may not be caught or ignored by a stopped task.
|
|
|
|
config SIG_KILL
|
|
int "SIGKILL"
|
|
default 9
|
|
depends on SIG_SIGKILL_ACTION
|
|
---help---
|
|
The SIGKILL signal is sent to cause a task termination event.
|
|
SIGKILL may not be caught or ignored.
|
|
|
|
config SIG_INT
|
|
int "SIGINT"
|
|
default 10
|
|
depends on SIG_SIGKILL_ACTION
|
|
---help---
|
|
The SIGINT signal is sent to cause a task termination event.
|
|
SIGINT may be ignored or caught by the receiving task.
|
|
|
|
endif # SIG_DEFAULT
|
|
|
|
config SIG_PIPE
|
|
int "SIGPIPE"
|
|
default 11
|
|
---help---
|
|
The SIGPIPE signal is sent to a task termination event.
|
|
This signal is generated when write on a pipe with no one to read it.
|
|
SIGPIPE may be ignored.
|
|
|
|
comment "Non-standard Signal Numbers"
|
|
|
|
config SIG_SIGCONDTIMEDOUT
|
|
int "SIGCONDTIMEDOUT"
|
|
default 16
|
|
depends on !DISABLE_PTHREAD
|
|
---help---
|
|
This non-standard signal number is used the implementation of
|
|
pthread_cond_timedwait(). Default 16.
|
|
|
|
config SIG_SIGWORK
|
|
int "SIGWORK"
|
|
default 17
|
|
depends on SCHED_WORKQUEUE || LIB_USRWORK
|
|
---help---
|
|
SIGWORK is a non-standard signal used to wake up the internal NuttX
|
|
worker thread. This setting specifies the signal number that will be
|
|
used for SIGWORK. Default: 17
|
|
|
|
endmenu # Signal Numbers
|
|
endmenu # Signal Configuration
|
|
|
|
menu "POSIX Message Queue Options"
|
|
depends on !DISABLE_MQUEUE
|
|
|
|
config PREALLOC_MQ_MSGS
|
|
int "Number of pre-allocated messages"
|
|
default 32
|
|
---help---
|
|
The number of pre-allocated message structures. The system manages
|
|
a pool of preallocated message structures to minimize dynamic allocations
|
|
|
|
config MQ_MAXMSGSIZE
|
|
int "Maximum message size"
|
|
default 32
|
|
---help---
|
|
Message structures are allocated with a fixed payload size given by this
|
|
setting (does not include other message structure overhead.
|
|
|
|
endmenu # POSIX Message Queue Options
|
|
|
|
config MODULE
|
|
bool "Enable loadable OS modules"
|
|
default n
|
|
select LIBC_MODLIB
|
|
select ARCH_USE_MODULE_TEXT if ARCH_HAVE_MODULE_TEXT
|
|
---help---
|
|
Enable support for loadable OS modules. Default: n
|
|
|
|
menu "Work queue support"
|
|
|
|
config SCHED_WORKQUEUE
|
|
# bool "Enable worker thread"
|
|
bool
|
|
default n
|
|
---help---
|
|
Create dedicated "worker" threads to handle delayed or asynchronous
|
|
processing.
|
|
|
|
config WQUEUE_NOTIFIER
|
|
bool "Generic work notifier"
|
|
default n
|
|
depends on SCHED_WORKQUEUE
|
|
---help---
|
|
Enable building of work queue notifier logic that will execute a
|
|
worker function an event occurs. This is is a general purpose
|
|
notifier, but was developed specifically to support poll() logic
|
|
where the poll must wait for an resources to become available.
|
|
|
|
config SCHED_HPWORK
|
|
bool "High priority (kernel) worker thread"
|
|
default n
|
|
select SCHED_WORKQUEUE
|
|
---help---
|
|
Create a dedicated high-priority "worker" thread to handle delayed
|
|
processing from interrupt handlers. This feature is required for
|
|
some drivers but, if there are no complaints, can be safely
|
|
disabled. The high priority worker thread also performs garbage
|
|
collection -- completing any delayed memory deallocations from
|
|
interrupt handlers. If the high-priority worker thread is disabled,
|
|
then that clean up will be performed either by (1) the low-priority
|
|
worker thread, if enabled, and if not (2) the IDLE thread instead
|
|
(which runs at the lowest of priority and may not be appropriate if
|
|
memory reclamation is of high priority)
|
|
|
|
For other, less-critical asynchronous or delayed process, the
|
|
low-priority worker thread is recommended.
|
|
|
|
if SCHED_HPWORK
|
|
|
|
config SCHED_HPNTHREADS
|
|
int "Number of high-priority worker threads"
|
|
default 1
|
|
---help---
|
|
This options selects multiple, high-priority threads. This is
|
|
essentially a "thread pool" that provides multi-threaded servicing
|
|
of the high-priority work queue. This breaks the serialization
|
|
of the "queue" (hence, it is no longer a queue at all).
|
|
|
|
CAUTION: Some drivers may use the work queue to serialize
|
|
operations. They may also use the high-priority work queue if it is
|
|
available. If there are multiple high-priority worker threads, then
|
|
this can result in the loss of that serialization. There may be
|
|
concurrent driver operations running on different HP threads and
|
|
this could lead to a failure. You may need to visit the use of the
|
|
HP work queue on your configuration is you select
|
|
CONFIG_SCHED_HPNTHREADS > 1
|
|
|
|
config SCHED_HPWORKPRIORITY
|
|
int "High priority worker thread priority"
|
|
default 224
|
|
---help---
|
|
The execution priority of the higher priority worker thread.
|
|
|
|
The higher priority worker thread is intended to serve as the
|
|
"bottom" half for device drivers. As a consequence it must run at
|
|
a very high, fixed priority. Typically, it should be the highest
|
|
priority thread in your system. Default: 224
|
|
|
|
For lower priority, application oriented worker thread support,
|
|
please consider enabling the lower priority work queue. The lower
|
|
priority work queue runs at a lower priority, of course, but has
|
|
the added advantage that it supports "priority inheritance" (if
|
|
PRIORITY_INHERITANCE is also selected): The priority of the lower
|
|
priority worker thread can then be adjusted to match the highest
|
|
priority client.
|
|
|
|
config SCHED_HPWORKSTACKSIZE
|
|
int "High priority worker thread stack size"
|
|
default DEFAULT_TASK_STACKSIZE
|
|
---help---
|
|
The stack size allocated for the worker thread. Default: 2K.
|
|
|
|
endif # SCHED_HPWORK
|
|
|
|
config SCHED_LPWORK
|
|
bool "Low priority (kernel) worker thread"
|
|
default n
|
|
select SCHED_WORKQUEUE
|
|
---help---
|
|
If SCHED_LPWORK is defined then a lower-priority work queue will
|
|
be created. This lower priority work queue is better suited for
|
|
more extended, application oriented processing (such as file system
|
|
clean-up operations or asynchronous I/O)
|
|
|
|
if SCHED_LPWORK
|
|
|
|
config SCHED_LPNTHREADS
|
|
int "Number of low-priority worker threads"
|
|
default 1 if !FS_AIO
|
|
default 4 if FS_AIO
|
|
---help---
|
|
This options selects multiple, low-priority threads. This is
|
|
essentially a "thread pool" that provides multi-threaded servicing
|
|
of the low-priority work queue. This breaks the serialization
|
|
of the "queue" (hence, it is no longer a queue at all).
|
|
|
|
This options is required to support, for example, I/O operations
|
|
that stall waiting for input. If there is only a single thread,
|
|
then the entire low-priority queue processing stalls in such cases.
|
|
Such behavior is necessary to support asynchronous I/O, AIO (for
|
|
example).
|
|
|
|
CAUTION: Some drivers may use the work queue to serialize
|
|
operations. They may also use the low-priority work queue if it is
|
|
available. If there are multiple low-priority worker threads, then
|
|
this can result in the loss of that serialization. There may be
|
|
concurrent driver operations running on different LP threads and
|
|
this could lead to a failure. You may need to visit the use of the
|
|
LP work queue on your configuration is you select
|
|
CONFIG_SCHED_LPNTHREADS > 1
|
|
|
|
config SCHED_LPWORKPRIORITY
|
|
int "Low priority worker thread priority"
|
|
default 100
|
|
---help---
|
|
The minimum execution priority of the lower priority worker thread.
|
|
|
|
The lower priority worker thread is intended support application-
|
|
oriented functions. The lower priority work queue runs at a lower
|
|
priority, of course, but has the added advantage that it supports
|
|
"priority inheritance" (if PRIORITY_INHERITANCE is also selected):
|
|
The priority of the lower priority worker thread can then be
|
|
adjusted to match the highest priority client. Default: 100
|
|
|
|
NOTE: This priority inheritance feature is not automatic. The
|
|
lower priority worker thread will always a fixed priority unless
|
|
you implement logic that calls lpwork_boostpriority() to raise the
|
|
priority of the lower priority worker thread (typically called
|
|
before scheduling the work) and then call the matching
|
|
lpwork_restorepriority() when the work is completed (typically
|
|
called within the work handler at the completion of the work).
|
|
Currently, only the NuttX asynchronous I/O logic uses this dynamic
|
|
prioritization feature.
|
|
|
|
The higher priority worker thread, on the other hand, is intended
|
|
to serve as the "bottom" half for device drivers. As a consequence
|
|
it must run at a very high, fixed priority. Typically, it should
|
|
be the highest priority thread in your system.
|
|
|
|
config SCHED_LPWORKPRIOMAX
|
|
int "Low priority worker thread maximum priority"
|
|
default 176
|
|
depends on PRIORITY_INHERITANCE
|
|
---help---
|
|
The maximum execution priority of the lower priority worker thread.
|
|
|
|
The lower priority worker thread is intended support application-
|
|
oriented functions. The lower priority work queue runs at a lower
|
|
priority, of course, but has the added advantage that it supports
|
|
"priority inheritance" (if PRIORITY_INHERITANCE is also selected):
|
|
The priority of the lower priority worker thread can then be
|
|
adjusted to match the highest priority client.
|
|
|
|
The higher priority worker thread, on the other hand, is intended
|
|
to serve as the "bottom" half for device drivers. As a consequence
|
|
it must run at a very high, fixed priority. Typically, it should
|
|
be the highest priority thread in your system.
|
|
|
|
This value provides an upper limit on the priority of the lower
|
|
priority worker thread. This would be necessary, for example, if
|
|
the higher priority worker thread were to defer work to the lower
|
|
priority thread. Clearly, in such a case, you would want to limit
|
|
the maximum priority of the lower priority work thread. Default:
|
|
176
|
|
|
|
config SCHED_LPWORKSTACKSIZE
|
|
int "Low priority worker thread stack size"
|
|
default DEFAULT_TASK_STACKSIZE
|
|
---help---
|
|
The stack size allocated for the lower priority worker thread. Default: 2K.
|
|
|
|
endif # SCHED_LPWORK
|
|
endmenu # Work Queue Support
|
|
|
|
menu "Stack and heap information"
|
|
|
|
config IDLETHREAD_STACKSIZE
|
|
int "Idle thread stack size"
|
|
default 1024
|
|
---help---
|
|
The size of the initial stack used by the IDLE thread. The IDLE thread
|
|
is the thread that (1) performs the initial boot of the system up to the
|
|
point where start-up application is spawned, and (2) there after is the
|
|
IDLE thread that executes only when there is no other thread ready to run.
|
|
|
|
config USERMAIN_STACKSIZE
|
|
int "Main thread stack size"
|
|
default DEFAULT_TASK_STACKSIZE
|
|
---help---
|
|
The size of the stack to allocate for the user initialization thread
|
|
that is started as soon as the OS completes its initialization.
|
|
|
|
config PTHREAD_STACK_MIN
|
|
int "Minimum pthread stack size"
|
|
default 256
|
|
---help---
|
|
Minimum pthread stack size
|
|
|
|
config PTHREAD_STACK_DEFAULT
|
|
int "Default pthread stack size"
|
|
default DEFAULT_TASK_STACKSIZE
|
|
---help---
|
|
Default pthread stack size
|
|
|
|
endmenu # Stack and heap information
|