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.confand 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-nameshould 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
regpropertyregis constructed by concat address + size (i.e. offset)
#address-cells,#size-cells: specified by parent bus controller#address-cells: number of<u32>cells inregfor address#size-cells: number of<u32>cells inregfor 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
phandlewhich 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/aliasesDT_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.handlerstores 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