Kernel Configuration Options

Kconfig files describe build-time configuration options (called symbols in Kconfig-speak), how they’re grouped into menus and sub-menus, and dependencies between them that determine what configurations are valid.

Kconfig files appear throughout the directory tree. For example, subsys/power/Kconfig defines power-related options.

This documentation is generated automatically from the Kconfig files by the script. Click on symbols for more information.

Configuration Options

Symbol name



This priority level is for end-user drivers such as sensors and display which have no inward dependencies.


It’s possible that an architecture port cannot or does not want to use the provided k_busy_wait(), but instead must do something custom. It must enable this option in that case.


It’s possible that an architecture port cannot use _Swap() to swap to the _main() thread, but instead must do something custom. It must enable this option in that case.


Use the compiler builtin functions for atomic operations. This is the preferred method. However, support for all arches in GCC is incomplete.


Use atomic operations routines that are implemented entirely in C by locking interrupts. Selected by architectures which either do not have support for atomic operations in their instruction set, or haven’t been implemented yet during bring-up, and also the compiler does not have support for the atomic __sync_* builtins.


Use when there isn’t support for compiler built-ins, but you have written optimized assembly code under arch/ which implements these.


This option outputs a banner to the console device during boot up.


This option delays bootup for the specified amount of milliseconds. This is used to allow serial ports to get ready before starting to print information on them during boot, as some systems might boot to fast for a receiving endpoint to detect the new USB serial bus, enumerate it and get ready to receive before it actually gets data. A similar effect can be achieved by waiting for DCD on the serial port–however, not all serial ports have DCD.


Untrusted parameters from user mode may be used in system calls to index arrays during speculative execution, also known as the Spectre V1 vulnerability. When enabled, various macros defined in misc/speculation.h will insert fence instructions or other appropriate mitigations after bounds checking any array index parameters passed in from untrusted sources (user mode threads). When disabled, these macros do nothing.



This option enables the device power management interface. The interface consists of hook functions implemented by device drivers that get called by the power manager application when the system is going to suspend state or resuming from suspend state. This allows device drivers to do any necessary power management operations like turning off device clocks and peripherals. The device drivers may also save and restore states in these hook functions.


Enable per-thread errno in the kernel. Application and library code must include errno.h provided by the C library (libc) to use the errno symbol. The C library must access the per-thread errno via the _get_errno() symbol.


When enabled, will enforce that a writable page isn’t executable and vice versa. This might not be acceptable in all scenarios, so this option is given for those unafraid of shooting themselves in the foot.

If unsure, say Y.


This option enables the tracking of various times inside the kernel the exact set of metrics being tracked is board-dependent. All timing measurements are enabled for X86 and ARM based architectures. In other architectures only a subset is enabled.


This option specifies the size of the smallest block in the pool. Option must be a power of 2 and lower than or equal to the size of the entire pool.


This option specifies the size of the heap memory pool used when dynamically allocating memory using k_malloc(). Supported values are: 256, 1024, 4096, and 16384. A size of zero means that no heap memory pool is defined.


Depending on the work that the idle task must do, most likely due to power management but possibly to other features like system event logging (e.g. logging when the system goes to sleep), the idle thread may need more stack space than the default value.


This option instructs the kernel to initialize stack areas with a known value (0xaa) before they are first used, so that the high water mark can be easily determined. This applies to the stack areas for threads, as well as to the interrupt stack.


This option specifies the size of the stack used by interrupt service routines (ISRs), and during kernel initialization.


Enable kernel debugging.

Note that debugging the kernel internals can be very verbose.


Default minimal init priority for each init level.


Device driver, that depends on common components, such as interrupt controller, but does not depend on other devices, uses this init priority.


Kernel objects use this priority for initialization. This priority needs to be higher than minimal default initialization priority.


When the initialization is complete, the thread executing it then executes the main() routine, so as to reuse the stack used by the initialization, which would be wasted RAM otherwise.

After initialization is complete, the thread runs main().


Priority at which the initialization thread runs, including the start of the main() function. main() can then change its priority if desired.


Configure the maximum number of partitions per memory domain.


Number of multiprocessing-capable cores available to the multicpu API and SMP features.


If disabled, only the main thread is available, so a main() function must be provided. Interrupts are available. Kernel objects will most probably not behave as expected, especially with regards to pending, since the main thread cannot pend, it being the only thread in the system.

Many drivers and subsystems will not work with this option set to ‘n’; disable only when you REALLY know what you are doing.


Number of cooperative priorities configured in the system. Gives access to priorities:


or seen another way, priorities:


This can be set to zero to disable cooperative scheduling. Cooperative threads always preempt preemptible threads.

Each priority requires an extra 8 bytes of RAM. Each set of 32 extra total priorities require an extra 4 bytes and add one possible iteration to loops that search for the next thread to run.

The total number of priorities is


The extra one is for the idle thread, which must run at the lowest priority, and be the only thread at that priority.


This option specifies the total number of asynchronous mailbox messages that can exist simultaneously, across all mailboxes in the system.

Setting this option to 0 disables support for asynchronous mailbox messages.


This defines a set of priorities at the (numerically) lowest end of the range which have “meta-irq” behavior. Runnable threads at these priorities will always be scheduled before threads at lower priorities, EVEN IF those threads are otherwise cooperative and/or have taken a scheduler lock. Making such a thread runnable in any way thus has the effect of “interrupting” the current task and running the meta-irq thread synchronously, like an exception or system call. The intent is to use these priorities to implement “interrupt bottom half” or “tasklet” behavior, allowing driver subsystems to return from interrupt context but be guaranteed that user code will not be executed (on the current CPU) until the remaining work is finished. As this breaks the “promise” of non-preemptibility granted by the current API for cooperative threads, this tool probably shouldn’t be used from application code.


This option specifies the total number of asynchronous pipe messages that can exist simultaneously, across all pipes in the system.

Setting this option to 0 disables support for asynchronous pipe messages.


Number of preemptible priorities available in the system. Gives access to priorities 0 to CONFIG_NUM_PREEMPT_PRIORITIES - 1.

This can be set to 0 to disable preemptible scheduling.

Each priority requires an extra 8 bytes of RAM. Each set of 32 extra total priorities require an extra 4 bytes and add one possible iteration to loops that search for the next thread to run.

The total number of priorities is


The extra one is for the idle thread, which must run at the lowest priority, and be the only thread at that priority.


Offload requests workqueue priority


Workqueue stack size for thread offload requests


Asynchronous notification framework. Enable the k_poll() and k_poll_signal_raise() APIs. The former can wait on multiple events concurrently, which can be either directly triggered or triggered by the availability of some kernel objects (semaphores and fifos).



Priority inheritance ceiling


When true, the application will have access to the k_thread_cpu_mask_*() APIs which control per-CPU affinity masks in SMP mode, allowing applications to pin threads to specific CPUs or disallow threads from running on given CPUs. Note that as currently implemented, this involves an inherent O(N) scaling in the number of idle-but-runnable threads, and thus works only with the DUMB scheduler (as SCALABLE and MULTIQ would see no benefit).

Note that this setting does not technically depend on SMP and is implemented without it for testing purposes, but for obvious reasons makes sense as an application API only where there is more than one CPU. With one CPU, it’s just a higher overhead version of k_thread_start/stop().


This enables a simple “earliest deadline first” scheduling mode where threads can set “deadline” deltas measured in k_cycle_get_32() units. Priority decisions within (!!) a single priority will choose the next expiring deadline and not simply the least recently added thread.


When selected, the scheduler ready queue will be implemented as a simple unordered list, with very fast constant time performance for single threads and very low code size. Choose this on systems with constrained code size that will never see more than a small number (3, maybe) of runnable threads in the queue at any given time. On most platforms (that are not otherwise using the red/black tree) this results in a savings of ~2k of code size.


True if the architecture supports a call to arch_sched_ipi() to broadcast an interrupt that will call z_sched_ipi() on other CPUs in the system. Required for k_thread_abort() to operate with reasonable latency (otherwise we might have to wait for the other thread to take an interrupt, which can be arbitrarily far in the future).


When selected, the scheduler ready queue will be implemented as the classic/textbook array of lists, one per priority (max 32 priorities). This corresponds to the scheduler algorithm used in Zephyr versions prior to 1.12. It incurs only a tiny code size overhead vs. the “dumb” scheduler and runs in O(1) time in almost all circumstances with very low constant factor. But it requires a fairly large RAM budget to store those list heads, and the limited features make it incompatible with features like deadline scheduling that need to sort threads more finely, and SMP affinity which need to traverse the list of threads. Typical applications with small numbers of runnable threads probably want the DUMB scheduler.


When selected, the scheduler ready queue will be implemented as a red/black tree. This has rather slower constant-time insertion and removal overhead, and on most platforms (that are not otherwise using the rbtree somewhere) requires an extra ~2kb of code. But the resulting behavior will scale cleanly and quickly into the many thousands of threads. Use this on platforms where you may have many threads (very roughly: more than 20 or so) marked as runnable at a given time. Most applications don’t want this.


When true, kernel will be built with SMP support, allowing more than one CPU to schedule Zephyr tasks at a time.


This option enables compiler stack canaries.

If stack canaries are supported by the compiler, it will emit extra code that inserts a canary value into the stack frame when a function is entered and validates this value upon exit. Stack corruption (such as that caused by buffer overflow) results in a fatal error condition for the running entity. Enabling this option can result in a significant increase in footprint and an associated decrease in performance.

If stack canaries are not supported by the compiler an error will occur at build time.


This option performs a limited form of Address Space Layout Randomization by offsetting some random value to a thread’s initial stack pointer upon creation. This hinders some types of security attacks by making the location of any given stack frame non-deterministic.

This feature can waste up to the specified size in bytes the stack region, which is carved out of the total size of the stack region. A reasonable minimum value would be around 100 bytes if this can be spared.

This is currently only implemented for systems whose stack pointers grow towards lower memory addresses.


On some architectures, the _Swap() primitive cannot be made atomic with respect to the irq_lock being released. That is, interrupts may be received between the entry to _Swap and the completion of the context switch. There are a handful of workaround cases in the kernel that need to be enabled when this is true. Currently, this only happens on ARM when the PendSV exception priority sits below that of Zephyr-handled interrupts.


By default, system work queue priority is the lowest cooperative priority. This means that any work handler, once started, won’t be preempted by any other thread until finished.


System workqueue stack size


This option specifies that the kernel lacks timer support. Some device configurations can eliminate significant code if this is disabled. Obviously timeout-related APIs will not work.


This option specifies hardware clock.


This option specifies the nominal frequency of the system clock in Hz.

Depending on the choice made, an amount of possibly expensive math must occur when converting ticks to milliseconds and vice-versa. Some values are optimized, and yield significantly less math.

The optimal values from a computational point-of-view are 1000, 500, 250 and 125, since in these cases there is either no computation required, or it is all done via bit-shifting. These also give a granularity from 1ms to 8ms.

Other good values are 100, 50, 25, 20 and 10. In this case, some math is required but is minimized. These are also values that necessitate a reduced number of clock interrupts per second, at the cost of granularity (10ms to 100ms).

All other values require some extensive 64-bit math, and in some configurations even require calls to compiler built-in functions, and can require a non-trivial extra amount of stack space (e.g. around 80 bytes on x86).

Note that when available and enabled, in “tickless” mode this config variable specifies the minimum available timing granularity, not necessarily the number or frequency of interrupts delivered to the kernel.

A value of 0 completely disables timer support in the kernel.


This option enables the kernel to interface with a power manager application. This permits the system to enter a Deep sleep state supported by the SOC where the system clock is turned off while RAM is retained. This state would be entered when the kernel becomes idle for extended periods and would have a high wake latency. Resume would be from the reset vector same as cold boot. The interface allows restoration of states that were saved at the time of suspend.


This option enables the board to implement extra power management policies whenever the kernel becomes idle. The kernel informs the power management subsystem of the number of ticks until the next kernel timer is due to expire.


This option enables the kernel to interface with a power manager application. This permits the system to enter a custom CPU low power state when the kernel becomes idle. The low power state could be any of the CPU low power states supported by the processor. Generally the one saving most power.


This option allows each thread to store 32 bits of custom data, which can be accessed using the k_thread_custom_data_xxx() APIs.


Thread names get stored in the k_thread struct. Indicate the max name length, including the terminating NULL byte. Reduce this value to conserve memory.


This option instructs the kernel to maintain a list of all threads (excluding those that have not yet started or have already terminated).


This option allows to set a name for a thread.


This option allows each thread to store the thread stack info into the k_thread data structure.




This option suppresses periodic system clock interrupts whenever the kernel becomes idle. This permits the system to remain in a power saving state for extended periods without having to wake up to service each tick as it occurs.


This option enables clock interrupt suppression when the kernel idles for only a short period of time. It specifies the minimum number of ticks that must occur before the next kernel timer expires in order for suppression to happen.


This option enables a fully event driven kernel. Periodic system clock interrupt generation would be stopped at all times.


This option specifies the thread priority level at which time slicing takes effect; threads having a higher priority than this ceiling are not subject to time slicing.


This option specifies the maximum amount of time a thread can execute before other threads of equal priority are given an opportunity to run. A time slice size of zero means “no limit” (i.e. an infinitely large time slice).


This option enables time slicing between preemptible threads of equal priority.


The _arch_switch() API is a lower level context switching primitive than the original arch_swap mechanism. It is required for an SMP-aware scheduler, or if the architecture does not provide arch_swap. In uniprocess situations where the architecture provides both, _arch_switch incurs more somewhat overhead and may be slower.


Indicates whether _arch_switch() API is supported by the currently enabled platform. This option should be selected by platforms that implement it.


When selected, the wait_q will be implemented with a doubly-linked list. Choose this if you expect to have only a few threads blocked on any single IPC primitive.


When selected, the wait_q will be implemented with a balanced tree. Choose this if you expect to have many threads waiting on individual primitives. There is a ~2kb code size increase over WAITQ_DUMB (which may be shared with SCHED_SCALABLE) if the rbtree is not used elsewhere in the application, and pend/unpend operations on “small” queues will be somewhat slower (though this is not generally a performance path).


This option allows the kernel to operate with its text and read-only sections residing in ROM (or similar read-only memory). Not all boards support this option so it must be used with care; you must also supply a linker command file when building your image. Enabling this option increases both the code and data footprint of the image.