Hey,
Trying to compile a custom driver for an I2C device and running into issues getting the actual DT node to link with the driver at build time.
Specifically, (because it looks like it'll never go in) I'm trying to use this driver https://github.com/zephyrproject-rtos/zephyr/pull/48389
My filesystem is set up as follows (other files omitted):
application_repo/ ├─ drivers/ │ ├─ sensor/ │ │ ├─ mcp9600/ │ │ │ ├─ CMakeLists.txt │ │ │ ├─ mcp9600.c │ │ │ ├─ mcp9600.h │ │ ├─ CMakeLists.txt │ ├─ CMakeLists.txt ├─ dts/ │ ├─ bindings/ │ │ ├─ sensor/ │ │ │ ├─ microchip,mcp9600.yaml ├─ boards/ │ ├─ arm/ │ │ ├─ board_name/ │ │ │ ├─ board_name.dts (and others) ├─ src/ │ ├─ main.c ├─ CMakeLists.txt ├─ prj.conf
I have included all driver code in CMakeFiles correctly and removed all ifdef guards, and double checked the driver CMakeList is getting added with a fatal error test message.
I have added the device to the devicetree with this inside the i2c node (the other sensors work fine)
&i2c1 { label = "I2C1"; clock-frequency = <100000>; compatible = "nordic,nrf-twim"; status = "okay"; pinctrl-0 = <&i2c1_default>; pinctrl-1 = <&i2c1_sleep>; pinctrl-names = "default", "sleep"; lis2dh: lis2dh@19 { compatible = "st,lis2dh"; label = "LIS2DH_I2C"; reg = <0x19>; irq-gpios = <&gpio0 29 0>; }; bme280: bme280@77 { compatible = "bosch,bme280"; reg = <0x77>; label = "BME280_I2C"; }; mcp9600: mcp9600@67 { compatible = "microchip,mcp9600"; label = "MCP9600_I2C"; reg = <0x67>; status = "okay"; }; };
I've tried also putting it in an overlay file just for this board as well.
It appears the node is getting compiled from DT as the following are all present in the build directory.
CONFIG_DT_HAS_MICROCHIP_MCP9600_ENABLED=y set_target_properties(devicetree_target PROPERTIES "DT_NODE|/soc/peripheral@40000000/i2c@9000/mcp9600@67" TRUE) set_target_properties(devicetree_target PROPERTIES "DT_NODELABEL|mcp9600" "/soc/peripheral@40000000/i2c@9000/mcp9600@67") set_target_properties(devicetree_target PROPERTIES "DT_PROP|/soc/peripheral@40000000/i2c@9000/mcp9600@67|reg" "103;") set_target_properties(devicetree_target PROPERTIES "DT_PROP|/soc/peripheral@40000000/i2c@9000/mcp9600@67|status" "okay") set_target_properties(devicetree_target PROPERTIES "DT_PROP|/soc/peripheral@40000000/i2c@9000/mcp9600@67|compatible" "microchip,mcp9600;") set_target_properties(devicetree_target PROPERTIES "DT_PROP|/soc/peripheral@40000000/i2c@9000/mcp9600@67|label" "MCP9600_I2C") set_target_properties(devicetree_target PROPERTIES "DT_PROP|/soc/peripheral@40000000/i2c@9000/mcp9600@67|wakeup-source" "False") set_target_properties(devicetree_target PROPERTIES "DT_REG|/soc/peripheral@40000000/i2c@9000/mcp9600@67|NUM" "1") set_target_properties(devicetree_target PROPERTIES "DT_REG|/soc/peripheral@40000000/i2c@9000/mcp9600@67|ADDR" "0x67;") set_target_properties(devicetree_target PROPERTIES "DT_REG|/soc/peripheral@40000000/i2c@9000/mcp9600@67|SIZE" "NONE;") extern const struct device DEVICE_DT_NAME_GET(DT_N_S_soc_S_peripheral_40000000_S_i2c_9000_S_mcp9600_67); /* dts_ord_96 */
But in the output map, the driver is never actually present causing my app to not compile. The zephyr_pre0.map file stops at __device_dts_ord_95 and doesn't include the mcp9600. You can see it include the other sensors here.
.z_device_POST_KERNEL90_ 0x000000000002c29c 0x18 zephyr/drivers/sensor/bme280/libdrivers__sensor__bme280.a(bme280.c.obj) 0x000000000002c29c __device_dts_ord_94 .z_device_POST_KERNEL90_ 0x000000000002c2b4 0x18 zephyr/drivers/sensor/lis2dh/libdrivers__sensor__lis2dh.a(lis2dh.c.obj) 0x000000000002c2b4 __device_dts_ord_95 0x000000000002c2cc __device_APPLICATION_start = . *(SORT_BY_NAME(SORT_BY_ALIGNMENT(.z_device_APPLICATION[0-9]_*))) *(SORT_BY_NAME(SORT_BY_ALIGNMENT(.z_device_APPLICATION[1-9][0-9]_*))) 0x000000000002c2cc __device_SMP_start = . *(SORT_BY_NAME(SORT_BY_ALIGNMENT(.z_device_SMP[0-9]_*))) *(SORT_BY_NAME(SORT_BY_ALIGNMENT(.z_device_SMP[1-9][0-9]_*))) 0x000000000002c2cc __device_end = .
I've slightly changed the driver code from the PR, but the DT_INST_FOREACH_STATUS_OKAY macro is still not finding any instances to compile, I get a "too few arguments in invocation of macro Z_FOR_LOOP_1" error on that line.
I have included the correct #define DT_DRV_COMPAT
microchip_mcp9600
in the c file as well.
#define MCP9600_DEFINE(inst) \ static struct mcp9600_data mcp9600_data_##inst; \ static const struct mcp9600_config mcp9600_config_##inst = { \ .i2c = I2C_DT_SPEC_INST_GET(inst), \ }; \ \ DEVICE_DT_INST_DEFINE(inst, mcp9600_init, NULL, &mcp9600_data_##inst, &mcp9600_config_##inst, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ &mcp9600_api_functions); DT_INST_FOREACH_STATUS_OKAY(MCP9600_DEFINE)
Do I need to put these files elsewhere? Every other sample I've looked at seems to follow this same structure. I'm on SDK 2.1.1 for reference. If needed I can share the full project in a confidential environment.
Thanks in advance