{"id":21007,"date":"2015-12-09T17:36:54","date_gmt":"2015-12-09T16:36:54","guid":{"rendered":"https:\/\/www.inovex.de\/\/?p=1200"},"modified":"2022-12-01T12:15:21","modified_gmt":"2022-12-01T11:15:21","slug":"android-sensor-integration-part-1-sensor-stack-and-kernel-module","status":"publish","type":"post","link":"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/","title":{"rendered":"Android Sensor Integration Part 1: Sensor Stack and Kernel Module"},"content":{"rendered":"<p>This first part of a four part\u00a0series will take you on a walk through the integration of a proximity sensor into Android. We use the ultrasonic range sensor SRF02 which is connected to the I2C bus of a Pandaboard ES. Google released <a href=\"https:\/\/source.android.com\/devices\/sensors\/index.html\" target=\"_blank\" rel=\"noopener\">some high-level documentation<\/a> of the operating mode of the sensor stack, while everything which is done by the hardware manufacturers is largely undocumented. This includes the Hardware Abstraction Layer (HAL) and the kernel driver that we want to look at. In this first part we start investigating what occurs in kernel space.<!--more--><\/p>\n<div style=\"background-color: #0079ff; color: white; padding: 1em;\">Disclaimer: The integration described here was implemented for the Pandaboard ES Rev B3 with a Linaro Android 4.4.4 and the ultrasonic range sensor SRF02 connected on an I2C bus. The full source code is <a style=\"color: white; text-decoration: underline;\" href=\"https:\/\/github.com\/Allegra42\/android-srf02\" target=\"_blank\" rel=\"noopener\">available on Github<\/a>. However this is written as a guideline for any standard sensor integration into Android. It should be considered work in progress with several ugly details that I know have to be fixed. And they will be in the future \u2013 probably. Only the files I really had to change have been uploaded.<\/div>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_79_2 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\"><p class=\"ez-toc-title\" style=\"cursor:inherit\"><\/p>\n<\/div><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#The-Android-Sensor-Stack\" >The Android Sensor Stack<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#Diving-into-Kernel-Space\" >Diving into Kernel Space<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#Initializing-the-Kernel-Module\" >Initializing the Kernel Module<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#Stay-tuned\" >Stay tuned<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#The-Whole-Story\" >The Whole Story<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"The-Android-Sensor-Stack\"><\/span>The Android Sensor Stack<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>What has to be done for the integration of an additional sensor touches just a small part of the complex processes in the Android Sensor Stack. We just have to use an existing framework, but to really understand what is happening between an application and the hardware we should take a look at the big picture.<\/p>\n<figure id=\"attachment_1205\" aria-describedby=\"caption-attachment-1205\" style=\"width: 800px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.inovex.de\/wp-content\/uploads\/2015\/12\/android-sensor-integration.png\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1205 size-large\" src=\"https:\/\/www.inovex.de\/wp-content\/uploads\/2015\/12\/android-sensor-integration-1024x576.png\" alt=\"A schematic explanation of the Android sensor stack\" width=\"800\" height=\"450\" \/><\/a><figcaption id=\"caption-attachment-1205\" class=\"wp-caption-text\">Source: https:\/\/source.android.com\/devices\/sensors\/sensor-stack.html<\/figcaption><\/figure>\n<p>As an app developer you may know the SensorManager. It is your one stop shop to get access to all available sensors and register listeners to pick up their data. Access to this data is provided by the SensorManager, which is written in Java and is part of the application framework. The SensorManager forwards the Java calls via the Java Native Interface (JNI) to a native C++ SensorManager library. This library can access the SensorService, which is one of the system level services. These are long-running operations in the background, just like controlling our sensor through the methods provided by the HAL. In the HAL two areas are relevant: sensors.h\/cpp where all available sensors are listed with methods to poll their data and the sensor class itself which implements these methods by accessing the interface a kernel module provides. So let&#8217;s start our journey at the kernel module level.<\/p>\n<figure id=\"attachment_1210\" aria-describedby=\"caption-attachment-1210\" style=\"width: 800px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.inovex.de\/wp-content\/uploads\/2015\/12\/android-sensor-sub-system.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-large wp-image-1210\" src=\"https:\/\/www.inovex.de\/wp-content\/uploads\/2015\/12\/android-sensor-sub-system-1024x576.png\" alt=\"A schematic explanation of the Android Sensor Sub System\" width=\"800\" height=\"450\" \/><\/a><figcaption id=\"caption-attachment-1210\" class=\"wp-caption-text\">Source: http:\/\/processors.wiki.ti.com\/index.php\/Android_Sensor_PortingGuide<\/figcaption><\/figure>\n<h2><span class=\"ez-toc-section\" id=\"Diving-into-Kernel-Space\"><\/span>Diving into Kernel Space<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>First we&#8217;ll need a driver to communicate with the sensor over I2C. This includes an option to enable or disable the sensor, start a cyclic measurement and read values. Therefore the virtual file system sysfs (everything under \/sys\/) will be used. It provides information about hardware devices and their drivers to userspace and configures the devices from there. At first we&#8217;ll create a sysfs entry for the sensor. When we write &#8218;1&#8216; to this file, a cyclic routine will start triggering the sensor and save the last value. So it is easy to read out this file to get the latest value. When writing &#8218;0&#8216;, the routine should simply stop. This cyclic routine is controlled by a delayed work queue. When we enable the sensor, such a queue is created and calls the function for the measurement with a defined delay. The ranging function writes itself back into the queue until we disable this mode. Just like that we are nearly done with the implementation, but the HAL is designed to look for input events, so we must provide them. We&#8217;ll use the input subsystem to generate events each time a measurement is completed.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Initializing-the-Kernel-Module\"><\/span>Initializing the Kernel Module<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Kernel modules can be dynamically loaded into the kernel or removed from it. That is why we need to define a function which is called at loading time of the module into the kernel, initializing everything needed for the driver, and one cleaning up when the module is removed. With <span class=\"lang:c decode:true crayon-inline\">module_init()<\/span>\u00a0 and <span class=\"lang:c decode:true crayon-inline\">module_exit()<\/span>\u00a0 we define which functions do these jobs.<\/p>\n<p>The driver we initialize in this init-method is a client driver for the I2C-core-driver, so we do not need to implement the protocol. We however have to\u00a0allocate space for the character device using the automatically assigned device number (<span class=\"lang:c decode:true crayon-inline \">alloc_chrdev_region (&amp;dev_num, 0, 1, DEVICE_NAME);<\/span><span class=\"s1\">)<\/span>, which is\u00a0turned into major\/minor numbers by <span class=\"lang:c decode:true crayon-inline \">major_number=MAJOR(dev_num)<\/span>\u00a0and <span class=\"lang:c decode:true crayon-inline\">minor_number=MINOR(dev_num)<\/span>\u00a0respectively. In the long run, both will be replaced by dev_t device numbers.<\/p>\n<p>The major and minor number of a device characterize a file in \/dev for accessing the right driver. Such a file is a virtual layer between userspace and device drivers in the kernel. This happens automatically when we add our character device to the system and just like that\u00a0a cdev-structure, which is representing a character device within the kernel, is allocated. With <span class=\"lang:c decode:true crayon-inline\">cdev_add()<\/span>\u00a0the device this structure represents is added to the system.<\/p>\n<pre class=\"lang:c decode:true\">srf02dev = cdev_alloc();\r\n\r\nsrf02dev-&gt;ops = &amp;srf02_fops;\r\n\r\nsrf02dev-&gt;owner = THIS_MODULE;\r\n\r\ncdev_add (srf02dev, dev_num, 1);<\/pre>\n<p>Now it is required to register this client driver to the I2C-core-driver with <span class=\"lang:c decode:true crayon-inline \">i2c_add_driver (&amp;srf02_i2c_driver);<\/span>\u00a0 for easy\u00a0access to\u00a0the device using existing methods of this protocol.<\/p>\n<p>At this point\u00a0we&#8217;ll take a short detour to\u00a0the board description file where the driver is added to the address the device pipes up at the I2C bus. The I2C-core-driver learns about all devices registered there at system start time.<\/p>\n<pre class=\"lang:c decode:true\">static struct i2c_board_info __initdata panda_i2c_srf02[] = {\r\n\r\n    {\r\n\r\n        I2C_BOARD_INFO(\"srf02\", 0x70),\r\n\r\n    },\r\n\r\n};\r\n\r\nstatic int __init omap4_panda_i2c_init(void)\r\n\r\n{\r\n\r\n    \/\/ ...\r\n\r\n    omap_register_i2c_bus(4, 400, panda_i2c_srf02, ARRAY_SIZE(panda_i2c_srf02));\r\n\r\n    return 0;\r\n\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>After that let&#8217;s\u00a0return to the driver and take a look at its\u00a0I2C-driver-structure. The routines for the I2C-core-driver are defined here, e.g. the <span class=\"lang:c decode:true crayon-inline\">probe()<\/span>-function. To successfully connect the driver to the device the name both at this structure and in the id_table structure have to be equal to the name in the i2c_board_info structure. Also the address in <span class=\"lang:c decode:true crayon-inline \">id_table and i2c_board_info<\/span>\u00a0 structures must be identical, otherwise the <span class=\"lang:c decode:true crayon-inline \">probe()<\/span>-function where the driver gets access to the hardware and important parts of sysfs are initialized is not called.<\/p>\n<pre class=\"lang:c decode:true \">static struct i2c_driver srf02_i2c_driver = {\r\n\r\n    .probe = srf02_i2c_probe,\r\n\r\n    .remove = __devexit_p (srf02_i2c_remove),\r\n\r\n    .id_table = srf02_id,\r\n\r\n    .driver = {\r\n\r\n        .name = \"srf02\",\r\n\r\n        .owner = THIS_MODULE,\r\n\r\n    },\r\n\r\n};\r\n\r\nstatic const struct i2c_device_id srf02_id [] = {\r\n\r\n    {\"srf02\", 0x70},\r\n\r\n    {},\r\n\r\n};<\/pre>\n<p>&nbsp;<\/p>\n<p>Later on almost the complete driver logic is controlled via the sysfs, so we need\u00a0to create entries for the driver there. We do so\u00a0by writing\u00a0an entry for the class with <span class=\"lang:c decode:true crayon-inline \">class_create (THIS_MODULE, DEVICE_NAME);<\/span>\u00a0and with <span class=\"lang:c decode:true crayon-inline \">device_create (srf02_class, NULL, dev_num, NULL, DEVICE_NAME);<\/span>\u00a0 for device entry. However,\u00a0these\u00a0entries are not visible before initializing a sysfs group in the <span class=\"lang:c decode:true crayon-inline\">probe()<\/span>-function with <span class=\"lang:c decode:true crayon-inline\">sysfs_create_group (&amp;client -&gt; dev.kobj, &amp;srf02_attr_group);<\/span>.<\/p>\n<p>Before creating a file in this sysfs group representing the interface for the HAL to interact with the sensor, it is required to initialize the input subsystem for generating input events. We have\u00a0to remember the name we give to this input device because in the HAL the events we are looking for use the same name. In <span class=\"lang:c decode:true crayon-inline\">input_set_abs_params()<\/span>\u00a0we set some parameters for the input device <span class=\"lang:c decode:true crayon-inline\">srf02_input_dev<\/span>\u00a0such as\u00a0the event code, the minimum\u00a0and maximum\u00a0distance the sensor can capture, the fuzziness and the <span style=\"color: #000000;\">flat<\/span>.<\/p>\n<pre class=\"lang:c decode:true\">srf02_input_dev = input_allocate_device();\r\n\r\nsrf02_input_dev-&gt;evbit[0] = BIT_MASK(EV_ABS);\r\n\r\nsrf02_input_dev-&gt;name = \"SRF02 input event module\";\r\n\r\ninput_set_abs_params(srf02_input_dev, ABS_DISTANCE, 15, 700, 1, 0);\r\n\r\ninput_register_device(srf02_input_dev);<\/pre>\n<p>Each driver needs functions to perform various operations on the device on which\u00a0the <span class=\"lang:c decode:true crayon-inline\">file_operations<\/span>\u00a0structure holds pointers. Not every driver needs to implement all accessing though. In this case we have one for a character device, so only functions for writing on or reading from it as well as those to open and release the device are required.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Stay-tuned\"><\/span>Stay tuned<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>This concludes Part 1 of our series on Android Sensor Integration. Return later this week for instructions on how to actually use the sensor for range measurement and process its output. In the meantime have a look at our homepage for more information on <a href=\"https:\/\/www.inovex.de\/en\/our-services\/mobile\/internet-of-things-smart-devices\/\" target=\"_blank\" rel=\"noopener\">Android and IoT\u00a0development<\/a>.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"The-Whole-Story\"><\/span>The Whole Story<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<ul>\n<li><a href=\"https:\/\/www.inovex.de\/\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/\" target=\"_blank\" rel=\"noopener\">Part 1:\u00a0Sensor Stack and Kernel Module<\/a><\/li>\n<li><a href=\"https:\/\/www.inovex.de\/\/android-sensor-integration-part-2-sensor-readings\/\">Part 2: Sensor Readings<\/a><\/li>\n<li><a href=\"https:\/\/www.inovex.de\/\/android-sensor-integration-part-3-hal\/\">Part 3: HAL<\/a><\/li>\n<li><a href=\"https:\/\/www.inovex.de\/\/android-sensor-integration-part-4-the-android-sensor-framework\/\">Part 4: The Android Sensor Framework<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This first part of a four part\u00a0series will take you on a walk through the integration of a proximity sensor into Android. We use the ultrasonic range sensor SRF02 which is connected to the I2C bus of a Pandaboard ES. Google released some high-level documentation of the operating mode of the sensor stack, while everything [&hellip;]<\/p>\n","protected":false},"author":35,"featured_media":13054,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"ep_exclude_from_search":false,"footnotes":""},"tags":[74],"service":[712],"coauthors":[{"id":35,"display_name":"Anna-Lena Marx","user_nicename":"amarx"}],"class_list":["post-21007","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","tag-iot","service-internet-of-things-iot"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Sensor Stack and Kernel Module<\/title>\n<meta name=\"description\" content=\"This first part will take you on a walk through the integration of a proximity sensor into Android. We start investigating what occurs in kernel space.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Sensor Stack and Kernel Module\" \/>\n<meta property=\"og:description\" content=\"This first part will take you on a walk through the integration of a proximity sensor into Android. We start investigating what occurs in kernel space.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/\" \/>\n<meta property=\"og:site_name\" content=\"inovex GmbH\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/inovexde\" \/>\n<meta property=\"article:published_time\" content=\"2015-12-09T16:36:54+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-12-01T11:15:21+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/06\/android-embedded-porting.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2300\" \/>\n\t<meta property=\"og:image:height\" content=\"876\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Anna-Lena Marx\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/06\/android-embedded-porting-1024x390.jpg\" \/>\n<meta name=\"twitter:creator\" content=\"@inovexgmbh\" \/>\n<meta name=\"twitter:site\" content=\"@inovexgmbh\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Anna-Lena Marx\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"7\u00a0Minuten\" \/>\n\t<meta name=\"twitter:label3\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data3\" content=\"Anna-Lena Marx\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/\"},\"author\":{\"name\":\"Anna-Lena Marx\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/person\/b7d6fd8c3ec8972f3b14f0205e25d022\"},\"headline\":\"Android Sensor Integration Part 1: Sensor Stack and Kernel Module\",\"datePublished\":\"2015-12-09T16:36:54+00:00\",\"dateModified\":\"2022-12-01T11:15:21+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/\"},\"wordCount\":1346,\"commentCount\":3,\"publisher\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/06\/android-embedded-porting.jpg\",\"keywords\":[\"IoT\"],\"articleSection\":[\"Applications\",\"English Content\",\"General\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/\",\"url\":\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/\",\"name\":\"Sensor Stack and Kernel Module\",\"isPartOf\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/06\/android-embedded-porting.jpg\",\"datePublished\":\"2015-12-09T16:36:54+00:00\",\"dateModified\":\"2022-12-01T11:15:21+00:00\",\"description\":\"This first part will take you on a walk through the integration of a proximity sensor into Android. We start investigating what occurs in kernel space.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#primaryimage\",\"url\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/06\/android-embedded-porting.jpg\",\"contentUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/06\/android-embedded-porting.jpg\",\"width\":2300,\"height\":876,\"caption\":\"Porting an Android Embedded Setup\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.inovex.de\/de\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Android Sensor Integration Part 1: Sensor Stack and Kernel Module\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.inovex.de\/de\/#website\",\"url\":\"https:\/\/www.inovex.de\/de\/\",\"name\":\"inovex GmbH\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.inovex.de\/de\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.inovex.de\/de\/#organization\",\"name\":\"inovex GmbH\",\"url\":\"https:\/\/www.inovex.de\/de\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png\",\"contentUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png\",\"width\":1921,\"height\":1081,\"caption\":\"inovex GmbH\"},\"image\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/inovexde\",\"https:\/\/x.com\/inovexgmbh\",\"https:\/\/www.instagram.com\/inovexlife\/\",\"https:\/\/www.linkedin.com\/company\/inovex\",\"https:\/\/www.youtube.com\/channel\/UC7r66GT14hROB_RQsQBAQUQ\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/person\/b7d6fd8c3ec8972f3b14f0205e25d022\",\"name\":\"Anna-Lena Marx\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/person\/image\/a8cfb531252ec2ef604ef3033c45111b\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/44ab0d3916e62a17054b8e4cea92702db304b9dcb6dd28fb9915484c1830409b?s=96&d=retro&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/44ab0d3916e62a17054b8e4cea92702db304b9dcb6dd28fb9915484c1830409b?s=96&d=retro&r=g\",\"caption\":\"Anna-Lena Marx\"},\"url\":\"https:\/\/www.inovex.de\/de\/blog\/author\/amarx\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Sensor Stack and Kernel Module","description":"This first part will take you on a walk through the integration of a proximity sensor into Android. We start investigating what occurs in kernel space.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/","og_locale":"de_DE","og_type":"article","og_title":"Sensor Stack and Kernel Module","og_description":"This first part will take you on a walk through the integration of a proximity sensor into Android. We start investigating what occurs in kernel space.","og_url":"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/","og_site_name":"inovex GmbH","article_publisher":"https:\/\/www.facebook.com\/inovexde","article_published_time":"2015-12-09T16:36:54+00:00","article_modified_time":"2022-12-01T11:15:21+00:00","og_image":[{"width":2300,"height":876,"url":"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/06\/android-embedded-porting.jpg","type":"image\/jpeg"}],"author":"Anna-Lena Marx","twitter_card":"summary_large_image","twitter_image":"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/06\/android-embedded-porting-1024x390.jpg","twitter_creator":"@inovexgmbh","twitter_site":"@inovexgmbh","twitter_misc":{"Verfasst von":"Anna-Lena Marx","Gesch\u00e4tzte Lesezeit":"7\u00a0Minuten","Written by":"Anna-Lena Marx"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#article","isPartOf":{"@id":"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/"},"author":{"name":"Anna-Lena Marx","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/person\/b7d6fd8c3ec8972f3b14f0205e25d022"},"headline":"Android Sensor Integration Part 1: Sensor Stack and Kernel Module","datePublished":"2015-12-09T16:36:54+00:00","dateModified":"2022-12-01T11:15:21+00:00","mainEntityOfPage":{"@id":"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/"},"wordCount":1346,"commentCount":3,"publisher":{"@id":"https:\/\/www.inovex.de\/de\/#organization"},"image":{"@id":"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#primaryimage"},"thumbnailUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/06\/android-embedded-porting.jpg","keywords":["IoT"],"articleSection":["Applications","English Content","General"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/","url":"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/","name":"Sensor Stack and Kernel Module","isPartOf":{"@id":"https:\/\/www.inovex.de\/de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#primaryimage"},"image":{"@id":"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#primaryimage"},"thumbnailUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/06\/android-embedded-porting.jpg","datePublished":"2015-12-09T16:36:54+00:00","dateModified":"2022-12-01T11:15:21+00:00","description":"This first part will take you on a walk through the integration of a proximity sensor into Android. We start investigating what occurs in kernel space.","breadcrumb":{"@id":"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#primaryimage","url":"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/06\/android-embedded-porting.jpg","contentUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/06\/android-embedded-porting.jpg","width":2300,"height":876,"caption":"Porting an Android Embedded Setup"},{"@type":"BreadcrumbList","@id":"https:\/\/www.inovex.de\/de\/blog\/android-sensor-integration-part-1-sensor-stack-and-kernel-module\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.inovex.de\/de\/"},{"@type":"ListItem","position":2,"name":"Android Sensor Integration Part 1: Sensor Stack and Kernel Module"}]},{"@type":"WebSite","@id":"https:\/\/www.inovex.de\/de\/#website","url":"https:\/\/www.inovex.de\/de\/","name":"inovex GmbH","description":"","publisher":{"@id":"https:\/\/www.inovex.de\/de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.inovex.de\/de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/www.inovex.de\/de\/#organization","name":"inovex GmbH","url":"https:\/\/www.inovex.de\/de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/","url":"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png","contentUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png","width":1921,"height":1081,"caption":"inovex GmbH"},"image":{"@id":"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/inovexde","https:\/\/x.com\/inovexgmbh","https:\/\/www.instagram.com\/inovexlife\/","https:\/\/www.linkedin.com\/company\/inovex","https:\/\/www.youtube.com\/channel\/UC7r66GT14hROB_RQsQBAQUQ"]},{"@type":"Person","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/person\/b7d6fd8c3ec8972f3b14f0205e25d022","name":"Anna-Lena Marx","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/person\/image\/a8cfb531252ec2ef604ef3033c45111b","url":"https:\/\/secure.gravatar.com\/avatar\/44ab0d3916e62a17054b8e4cea92702db304b9dcb6dd28fb9915484c1830409b?s=96&d=retro&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/44ab0d3916e62a17054b8e4cea92702db304b9dcb6dd28fb9915484c1830409b?s=96&d=retro&r=g","caption":"Anna-Lena Marx"},"url":"https:\/\/www.inovex.de\/de\/blog\/author\/amarx\/"}]}},"_links":{"self":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/21007","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/users\/35"}],"replies":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/comments?post=21007"}],"version-history":[{"count":1,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/21007\/revisions"}],"predecessor-version":[{"id":39758,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/21007\/revisions\/39758"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/media\/13054"}],"wp:attachment":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/media?parent=21007"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/tags?post=21007"},{"taxonomy":"service","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/service?post=21007"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/coauthors?post=21007"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}