-
Notifications
You must be signed in to change notification settings - Fork 6.6k
Naming Conventions
Unlike desktop operating systems, where applications are written in user-space and drivers are used to cross the boundary between kernel and user space, all applications in the Zephyr Kernel are written in kernel space. Applications are linked with the kernel, creating a shared and common namespace.
To ensure proper execution of both kernel and applications, it makes sense to divide the namespace into kernel and application subspaces. This is achieved by restricting the kernel's global symbols and macros to a well-defined set of name prefixes. These prefixes apply both to public symbols, which applications can reference, and to private symbols, which only the kernel itself is permitted to reference. Symbols that do not begin with a kernel namespace prefix are available to applications with a few exceptions. See "Exceptions to the Namespace" section below for details.
Prefix | Description | Example |
---|---|---|
_ | Denotes a private symbol. |
_k_signal_event
|
atomic_ | Denotes an atomic operation. |
atomic_inc
|
device_ | Denotes an API relating to devices and their initialization. |
device_get_binding
|
irq_ | Denotes an IRQ management operation. |
irq_disable
|
isr_ | Denotes an operation called by an Interrupt Service Routine; |
isr_event_send
|
k_ | Kernel-specific function. |
k_malloc
|
k_do_ | kernel-specific functions indicating essential operation within the kernel space. Do not use these functions unless absolutely necessary. |
k_do_event_signal
|
sys_ | Catch-all for APIs that do not fit into the other namespaces. |
sys_write32
|
If your additional symbol does not fall into the above classification, consider renaming it.
Some kernel APIs use well-known names that lack prefixes. A few examples are:
ntohl
open
close
read
write
ioctl
- In rare cases a few global symbols do not use the normal kernel prefixes;
kernel_version_get()
is one such example.
Generally, any subsystem can define its own naming conventions for symbols. However, these should be implemented with their own namespace prefix (for example, bt\_
for BlueTooth, or net\_
for IP). This limits possible clashes with applications. Following this prefix convention with subsystems keeps a consistent interface for all users.
The current build system uses a series of make files to define the common pieces for a given subsystem in addition to a top level Makefile that is system wide and cross architecture. For example, common defines for x86 architecture are located under $ZEPHYR_BASE/arch/x86
, with platform-specific defines underneath it, like $ROOT/arch/x86/Makefile
. Too many default paths can cause problems when more than one file has the same name. The only include paths
into ${ZEPHYR_BASE}/include
should be Makefile
itself, and the header files should be included with:
#include <subdirectory/header.h>For example, if you have two files,
include/pci.h
and include/drivers/pci.h
, and have set both -Iinclude/drivers
and -Iinclude
for your compile, then any code using
#include <pci.h>becomes ambiguous, while
#include <drivers/pci.h>is not. Not having
-Iinclude/drivers
forces users to use the second form which is more explicit.
Zephyr uses the standard codes in errno.h
for all APIs.
As a general rule, 0
indicates success; a negative errno.h code indicates an error condition. The table below shows the error code conventions based on device driver use cases, but they can also be applied to other kernel components.
Code | Meaning |
---|---|
0 | Success. |
-EIO | General failure. |
-ENOTSUP | Operation is not supported or operation is invalid. |
-EINVAL | Device configuration is not valid or function argument is not valid. |
-EBUSY | Device controller is busy. |
-EACCES | Device controller is not accessible. |
-ENODEV | Device type is not supported. |
-EPERM | Device is not configured or operation is not permitted. |
-ENOSYS | Function is not implemented. |
Zephyr Project Home | Documentation Home | Mailing lists