<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Educational Question - How does the device driver acquire that device&amp;#39;s API?</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/107592/educational-question---how-does-the-device-driver-acquire-that-device-s-api</link><description>I&amp;#39;m learning to use the Zephyr toolchain and in the interest of connecting the Zephyr-side coding to the i2c protocols I am familiar with, I have some questions. 
 I&amp;#39;m trying to decipher how the enums and macros that are defined in Zephyr/device.h go</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Tue, 18 Jun 2024 18:27:21 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/107592/educational-question---how-does-the-device-driver-acquire-that-device-s-api" /><item><title>RE: Educational Question - How does the device driver acquire that device's API?</title><link>https://devzone.nordicsemi.com/thread/489376?ContentTypeID=1</link><pubDate>Tue, 18 Jun 2024 18:27:21 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:578a3ed0-6529-4a99-97e5-9c6652a8f052</guid><dc:creator>FinnBiggs</dc:creator><description>&lt;p&gt;Thank you very much, very clear answer!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Educational Question - How does the device driver acquire that device's API?</title><link>https://devzone.nordicsemi.com/thread/465164?ContentTypeID=1</link><pubDate>Sat, 20 Jan 2024 01:06:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6b51e3fc-25e3-470e-a70f-182e24ecbe5c</guid><dc:creator>Anthony Ambuehl</dc:creator><description>&lt;p&gt;Every device in devicetree declares which driver it is compatible with.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The Cmake/Kconfig/Devicetree environment will automatically include the corresponding driver source file for example zephyr/drivers/sensor/lis2mdl/lis2mdl.c.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;At the bottom of the device driver source file there are macros which declare a device object for&amp;nbsp;each instance of a device declared in device tree.&amp;nbsp; These macros automatically place the device struct in a named region that the kernel is aware.&amp;nbsp; The kernel will automatically call the init function from the device drive struct according&amp;nbsp;to&amp;nbsp;the init phase and init priority declared in the device object.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This device object includes a pointer to the device&amp;#39;s implementation of the API.&amp;nbsp; It also may include pointers run time data and configuration constants data ojbects.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Taking LIS2MDL as an example:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#define LIS2MDL_DEVICE_INIT(inst)                                                                  \
	PM_DEVICE_DT_INST_DEFINE(inst, lis2mdl_pm_action);                                         \
                                                                                                   \
	SENSOR_DEVICE_DT_INST_DEFINE(inst, lis2mdl_init, PM_DEVICE_DT_INST_GET(inst),              \
				     &amp;amp;lis2mdl_data_##inst, &amp;amp;lis2mdl_config_##inst, POST_KERNEL,    \
				     CONFIG_SENSOR_INIT_PRIORITY, &amp;amp;lis2mdl_driver_api);

#define LIS2MDL_DEFINE(inst)                                                                       \
	static struct lis2mdl_data lis2mdl_data_##inst = {                                         \
		.single_mode = DT_INST_PROP(inst, single_mode),                                    \
	};                                                                                         \
	static const struct lis2mdl_config lis2mdl_config_##inst =                                 \
		COND_CODE_1(DT_INST_ON_BUS(inst, spi), (LIS2MDL_CONFIG_SPI(inst)),                 \
			    (LIS2MDL_CONFIG_I2C(inst)));                                           \
	LIS2MDL_DEVICE_INIT(inst)

DT_INST_FOREACH_STATUS_OKAY(LIS2MDL_DEFINE)&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The macro&amp;#39;s for all this are deeply layered but they are all triggering off of defines coming from:&lt;/p&gt;
&lt;p&gt;build_dir/zephyr/include/generated/devicetree_generated.h&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;This actually touches on a flaw in zephyr.. there is no type checking on calls to device drivers.&amp;nbsp; Its entirely possible to call sensor_attr_set on a device that does not follow the sensor API.&amp;nbsp; Its up to the programmer to use the correct API functions with a driver of the same type.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I hope this helps!&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Also&amp;nbsp; I spent the last 7 months learning Zephyr and I&amp;#39;m now looking for a new gig so if you know anyone looking for a embedded software expert please share my linkedIn profile:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.linkedin.com/in/anthonyambuehl/"&gt;www.linkedin.com/.../&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>