install zephyr
west init
: install zephyr in current folder with default yml- we can init with a manifest file
- the manifest file will have its own repo
- other repos can be included as module
- forest topology
- we can init with a manifest file
- use modules to define out of tree board, dts, drivers, etc
- repo should contain
zephyr/module.yml
- Reference
- kconfig extensions
- repo should contain
Kconfig
- Reference
- build/zephyr/.config is generated based on the following sources
- board config
<BOARD>_defconfig
- CMAKE cache
CONFIG_
- application conf file:
prj.conf
and etc
- board config
- Kconfig item without label is invisible in menuconfig
board porting
- Reference
Kconfig.board
- define options in menuconfig
- board specific kconfig defaults
Kconfig.defconfig
: invisible Kconfig symbols<BOARD>_defconfig
: visible Kconfig symbols
device tree
- Specification
- Reference
- each node is named like
[label:] node-name[@unit-address]
node-name
should describe teh general class of device- tree struct starts from root node
/
- tree struct starts from root node
unit-address
: differentiate node based on bus address, but for naming purpose only- actual bus address is determined by node’s
reg
propertyreg
is constructed by concat address + size (i.e. offset)
#address-cells
,#size-cells
: specified by parent bus controller#address-cells
: number of<u32>
cells inreg
for address#size-cells
: number of<u32>
cells inreg
for size
- actual bus address is determined by node’s
label
: unique shorthand for identifying node- a node can have zero, one, or multiple node labels
- translate into
phandle
which compiling
- node property
compatible
: specify driver to be used- node name is contained in property
label
:device_get_binding()
name
: ?
/aliases
: gloabl section for node name to label mapping-
/chosen
: describe non-hardware parameters. ex.bootargs
- device tree puts no contraint over its content
dts/bindings
: enforce tree structure & parsing requirement.dt_schema
: used in linux kernel with slight different definition
device access
- get node id
- cannot assign to variable
DT_PATH()
: from tree pathDT_NODELABEL()
: from node_labelDT_ALIAS()
: from/aliases
DT_INST()
: get one compatible device via its instance number- order of instance is not guaranteed
- get node label
DT_LABEL
- get device binding
- notice that device loading depend on priority
device driver
struct device *
- config: build time configuration
- data: driver data
- api: sub system api
macro
- device tree content will be convert to macro with the help of bindings
- if a matching driver is not found
- the compilation still pass
- the device is not used
- the dt entry can get accessed
- if a matching driver is not found
- driver macro defined as
#define DT_DRV_COMPAT ...
- if dt macro is not defined, ie device does not exist
- compilation fail becasue driver cannot be registered.
- if dt macro is not defined, ie device does not exist
interrupt
- gpio:
gpio_pin_configure()
- init gpio struct for read
gpio_init_callback()
init cb struct- with callback func and pin mask
gpio_add_callback()
add gpio to callbackgpio_pin_interrupt_configure()
- enable interrupt for gpio struct
- callback func:
- called with gpio struct + cb struct + pin mask
- should trigger worker thread
- global thread
k_work
- trigger by
k_work_submit
k_work.handler
stores the actual work
- trigger by
- local thread
- trigger by semphemore
k_sem_give
- trigger by semphemore
concurrency
https://docs.zephyrproject.org/latest/reference/kernel/index.html#scheduling-interrupts-and-synchronization
todo
user mode optimization