Zephyr device driver model
Keywords: zephyr device drivers
Zephyr device driver model
Zephyr device drivers getting started
Challenged by Zephyr's way of writing device drivers, capturing some notes here on a study of a Zephyr example project which talks to LIS2DH accelerometer on a Sparkfun Thing Plus board. Casting net wider for Zephyr device driver "How To" articles, find Jared Wolff's blog post:
Excerpt from Zephyr project drivers documentation:
-
Driver Data Structures
The device initialization macros populate some data structures at build time which are split into read-only and runtime-mutable parts. At a high level we have:
struct device { const char *name; const void *config; const void *api; void * const data; };
Excerpt from file ~/ncs/zephyr/include/drivers/sensor.h
:
382 /** 383 * @brief Set an attribute for a sensor 384 * 385 * @param dev Pointer to the sensor device 386 * @param chan The channel the attribute belongs to, if any. Some 387 * attributes may only be set for all channels of a device, depending on 388 * device capabilities. 389 * @param attr The attribute to set 390 * @param val The value to set the attribute to 391 * 392 * @return 0 if successful, negative errno code if failure. 393 */ 394 __syscall int sensor_attr_set(const struct device *dev, 395 enum sensor_channel chan, 396 enum sensor_attribute attr, 397 const struct sensor_value *val); 398 399 static inline int z_impl_sensor_attr_set(const struct device *dev, 400 enum sensor_channel chan, 401 enum sensor_attribute attr, 402 const struct sensor_value *val) 403 { 404 const struct sensor_driver_api *api = 405 (const struct sensor_driver_api *)dev->api; 406 407 if (api->attr_set == NULL) { 408 return -ENOSYS; 409 } 410 411 return api->attr_set(dev, chan, attr, val); 412 } 413
From these two code excerpts the big question is, how is dev->api assigned in early configuring code for an I2C based sensor?
./include/drivers/sensor.h:61: SENSOR_CHAN_ACCEL_XYZ, . . . hmm, this is part of a large enumeration:
53 enum sensor_channel { 54 /** Acceleration on the X axis, in m/s^2. */ 55 SENSOR_CHAN_ACCEL_X, 56 /** Acceleration on the Y axis, in m/s^2. */ 57 SENSOR_CHAN_ACCEL_Y, 58 /** Acceleration on the Z axis, in m/s^2. */ 59 SENSOR_CHAN_ACCEL_Z, 60 /** Acceleration on the X, Y and Z axes. */ 61 SENSOR_CHAN_ACCEL_XYZ, 62 /** Angular velocity around the X axis, in radians/s. */ 63 SENSOR_CHAN_GYRO_X, 64 /** Angular velocity around the Y axis, in radians/s. */ 65 SENSOR_CHAN_GYRO_Y, 66 /** Angular velocity around the Z axis, in radians/s. */ 67 SENSOR_CHAN_GYRO_Z, 68 /** Angular velocity around the X, Y and Z axes. */ 69 SENSOR_CHAN_GYRO_XYZ, . . .
edit point
ted@localhost:~/projects/embedded/ncs/zephyr/samples/z--sandbox/blink-plus-uart/build/zephyr/boards/arm/sparkfun_thing_plus_nrf9160$ nm -s libboards__arm__sparkfun_thing_plus_nrf9160.a board.c.obj: 0000002c t $d 00000000 r $d 00000000 t $t 00000001 t board_sparkfun_thing_plus_nrf9160_init 00000000 r __init_sys_init_board_sparkfun_thing_plus_nrf9160_init0 U z_impl_device_get_binding ted@localhost:~/projects/embedded/ncs/zephyr/samples/z--sandbox/blink-plus-uart/build/zephyr/boards/arm/sparkfun_thing_plus_nrf9160$
File noted:
ted@localhost:~/projects/embedded/ncs/zephyr/samples/z--sandbox/blink-plus-uart/build/zephyr/dev_handles.c
ted@localhost:~/projects/embedded/ncs/zephyr/samples/z--sandbox/blink-plus-uart/build/zephyr$ ls *.c dev_handles.c isr_tables.c ted@localhost:~/projects/embedded/ncs/zephyr/samples/z--sandbox/blink-plus-uart/build/zephyr$ ls *.h ls: cannot access '*.h': No such file or directory
Example project build directory noted, this dir auto-gen'd:
ted@localhost:~/projects/embedded/ncs/zephyr/samples/z--sandbox/blink-plus-uart/build/zephyr$ ls include/generated/ app_data_alignment.ld autoconf.h driver-validation.h otype-to-size.h snippets-ram-sections.ld snippets-sections.ld version.h app_smem_aligned.ld device_extern.h kobj-types-enum.h otype-to-str.h snippets-rodata.ld syscall_dispatch.c app_smem.ld devicetree_fixups.h ncs_version.h pm_config.h snippets-rom-start.ld syscall_list.h app_smem_unaligned.ld devicetree_unfixed.h offsets.h snippets-noinit.ld snippets-rwdata.ld syscalls