<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>The Code Artist</title><link>http://thecodeartist.blogspot.com/</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/TheCodeArtist" /><description></description><language>en</language><managingEditor>noreply@blogger.com (Chinmay V S)</managingEditor><lastBuildDate>Tue, 18 Jun 2013 03:41:41 PDT</lastBuildDate><generator>Blogger http://www.blogger.com</generator><openSearch:totalResults xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/">24</openSearch:totalResults><openSearch:startIndex xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/">1</openSearch:startIndex><openSearch:itemsPerPage xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/">25</openSearch:itemsPerPage><feedburner:info uri="thecodeartist" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license><feedburner:emailServiceId>TheCodeArtist</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item><title>Sensors on Google Glass</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/sayHBO36K8I/sensors-on-google-glass.html</link><category>Magnetic-Field sensor</category><category>Google Glass</category><category>Accelerometer Sensor</category><category>Sensors</category><category>Orientation Sensor</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Mon, 13 May 2013 00:42:47 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-4206837575803792057</guid><description>&lt;div style="text-align: justify;"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-n8FiKXo8t5M/UYou70T5b5I/AAAAAAAABKg/RnxMPEO6yJ0/s1600/google-glass.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-n8FiKXo8t5M/UYou70T5b5I/AAAAAAAABKg/RnxMPEO6yJ0/s1600/google-glass.jpg" height="145" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Recently Google has shared the &lt;a href="https://android.googlesource.com/kernel/omap/+/glass-omap-xrr02" target="_blank"&gt;Linux Kernel source for the firmware running on the Google Glass&lt;/a&gt;. Having grown tired of watching&lt;span style="font-size: small;"&gt; &lt;/span&gt;online reviews about the monotonous "Glass this, glass that" voice commands, i was curious about the support for o&lt;span style="font-size: small;"&gt;t&lt;/span&gt;her forms of inpu&lt;span style="font-size: small;"&gt;t.&lt;/span&gt; (read gestures). A quick peek into the innards of the kernel source revealed quite a lo&lt;span style="font-size: small;"&gt;t...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h2 style="text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;FACT1. Google Glass runs on Texas Instruments OMAP4430.&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h4 style="text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Nothing revolutionary. A major win for TI (FWIW), considering that it has nonchalantly quit the mobile-SoC market citing a low RoI. This was already known as &lt;a href="http://www.engadget.com/2013/04/26/google-glass-runs-on-omap-4430" target="_blank"&gt;some guy who actually had the Google &lt;span style="font-size: small;"&gt;G&lt;/span&gt;lass&lt;span style="font-size: small;"&gt;,&lt;/span&gt; ran adb and found out&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;b&gt;Refer&lt;/b&gt;: &lt;a href="https://android.googlesource.com/kernel/omap/+/glass-omap-xrr02/arch/arm/configs/notle_defconfig" target="_blank"&gt;arch/arm/configs/notle_defconfig&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h2&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;b&gt;FACT2. Google Glass has a built-in &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;b&gt; Accel, &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;Gyro &amp;amp; Compass.&lt;/b&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;b&gt;Invensense MPU6050 &lt;/b&gt;= 3axis gyro + 3 axis accel.&lt;br /&gt;&lt;b&gt;Asahi Kasei AKM8975 &lt;/b&gt;= 3axis geomagnetic sensor(compass).&lt;br /&gt;Combining facts 1 and 2 we can see that the device spec for SoC and sensors perfectly matches the popular Samsung Galaxy S2 (variant &lt;a href="http://www.gsmarena.com/samsung_i9100g_galaxy_s_ii-4327.php" target="_blank"&gt;&lt;b&gt;I9100G&lt;/b&gt;&lt;/a&gt;).&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Rather than having independent ICs for both, the Google Glass uses MPU9150. &lt;a href="http://www.invensense.com/mems/gyro/mpu9150.html" target="_blank"&gt;&lt;b&gt;Invensense MPU9150&lt;/b&gt;&lt;/a&gt; is a single SiP which contains MPU6050 and AK8975 ICs within. This is fully hardware-compatible with existing MPU6050 board designs with the additional benefit of... (as Invensense quotes&lt;span style="font-size: small;"&gt; on its website&lt;/span&gt;) "&lt;i&gt;...providing a simple upgrade path and making it easy to fit on space constrained boards.&lt;/i&gt;" Perfect for Google Glass.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;b&gt;Refer:&lt;/b&gt; &lt;a href="https://android.googlesource.com/kernel/omap/+/glass-omap-xrr02/arch/arm/mach-omap2/board-notle.c" target="_blank"&gt;arch/arm/mach&lt;span style="font-size: small;"&gt;-&lt;/span&gt;omap2/board&lt;span style="font-size: small;"&gt;&lt;span style="font-size: small;"&gt;-&lt;/span&gt;notle.c&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: small;"&gt; line:&lt;/span&gt;1710&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h2&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;b&gt;FACT3. Google Glass has a "glasshub"&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h2&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;I stumbled upon this by accident as i was searching for the sensor drivers. The glasshub appears to be a external micro&lt;span style="font-size: small;"&gt;-&lt;/span&gt;controller that communicates with OMAP4430 over I2C. This is the hardware that supports the "wink" command. Strangely enough, it supports upto 20winks! Looks like someone didn't learn their lesson with triple and quadruple mouse-clicks designs. On the other hand, this will be most essential when someone attempts to write a Google Glass app to detect seizures. Forward thinking as always, Google.&lt;br /&gt;&lt;br /&gt;The glasshub also reports IR data and proximity (not sure about the underlying hardware though).&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;b&gt;Refer: &lt;/b&gt;&lt;a href="https://android.googlesource.com/kernel/omap/+/glass-omap-xrr02/arch/arm/mach-omap2/board-notle.c" target="_blank"&gt;arch/arm/mach&lt;span style="font-size: small;"&gt;-&lt;/span&gt;omap2/board&lt;span style="font-size: small;"&gt;&lt;span style="font-size: small;"&gt;-&lt;/span&gt;notle.c&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: small;"&gt; line:&lt;/span&gt;1&lt;span style="font-size: small;"&gt;843 &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="https://android.googlesource.com/kernel/omap/+/glass-omap-xrr02/drivers/input/misc/glasshub.c" target="_blank"&gt;drivers/input/mis/glasshub.c&lt;/a&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;h2&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h2&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;b&gt;FACT4. Google Glass has a "Proximity" sensor.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h2&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Not to be confused with the "glasshub" there is another independent module&lt;span style="font-size: small;"&gt;,&lt;/span&gt; the &lt;b&gt;LiteON LTR-506ALS&lt;/b&gt;. A very good sign, this IC is extremely customisable when it comes thresholds/IR-pulse-freq/pulse-count/poll-rate. Maybe, just maybe, we c&lt;span style="font-size: small;"&gt;oul&lt;/span&gt;d hack the whole setup &lt;span style="font-size: small;"&gt;into&lt;/span&gt; a rudimentary IR remote. While being used primarily for ambient light sensing, it also supports proximity sensing. &lt;span style="font-size: small;"&gt;T&lt;/span&gt;his means that we can have the Google Glass detecting our finger/hand swipes in front of our face. Quite the most exciting tech of the lot as it will provide the illusion of being able to actually handle the projected images.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;b&gt;Refer:&lt;/b&gt; &lt;a href="https://android.googlesource.com/kernel/omap/+/glass-omap-xrr02/arch/arm/mach-omap2/board-notle.c" target="_blank"&gt;arch/arm/mach&lt;span style="font-size: small;"&gt;-&lt;/span&gt;omap2/board&lt;span style="font-size: small;"&gt;&lt;span style="font-size: small;"&gt;-&lt;/span&gt;notle.c&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: small;"&gt; line:&lt;/span&gt;17&lt;span style="font-size: small;"&gt;27&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="https://android.googlesource.com/kernel/omap/+/glass-omap-xrr02/drivers/input/misc/ltr506als.c" target="_blank"&gt;drivers/input/misc/ltr506als.c&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;span style="font-family: Verdana,sans-serif;"&gt;Overall quite a good amount of&lt;br /&gt; "sensory" tech inside for me to play with.&lt;br /&gt;Me so excited. ;-) ;-) wink wink&lt;/span&gt;&lt;/div&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-2ZoET5eGmWg/UYoqtCQ67zI/AAAAAAAABKQ/pkE5pn6AK9E/s1600/PiB.jpeg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-2ZoET5eGmWg/UYoqtCQ67zI/AAAAAAAABKQ/pkE5pn6AK9E/s1600/PiB.jpeg" height="288" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Hey Google, Can i haz a Google Glass?&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=sayHBO36K8I:75TBkutPBK0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=sayHBO36K8I:75TBkutPBK0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=sayHBO36K8I:75TBkutPBK0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=sayHBO36K8I:75TBkutPBK0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/sayHBO36K8I" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-13T13:12:47.538+05:30</app:edited><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-n8FiKXo8t5M/UYou70T5b5I/AAAAAAAABKg/RnxMPEO6yJ0/s72-c/google-glass.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">8</thr:total><georss:featurename xmlns:georss="http://www.georss.org/georss">Puttappa layout, New Thippasandra, Bangalore, Karnataka, India</georss:featurename><georss:point xmlns:georss="http://www.georss.org/georss">12.971433099459315 77.65763282775879</georss:point><georss:box xmlns:georss="http://www.georss.org/georss">12.970466099459316 77.65637232775879 12.972400099459314 77.65889332775879</georss:box><feedburner:origLink>http://thecodeartist.blogspot.com/2013/05/sensors-on-google-glass.html</feedburner:origLink></item><item><title>Internet Radio : Part1 - Shoutcast Protocol</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/Y0u6o38b0O8/shoutcast-internet-radio-protocol.html</link><category>streaming</category><category>curl</category><category>C</category><category>Programming</category><category>Shoutcast</category><category>CodeProject</category><category>internet-radio</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Sun, 24 Feb 2013 00:03:28 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-3925164578973094658</guid><description>&lt;div style="text-align: justify;"&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;div class="separator" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: center;"&gt;
&lt;a href="http://www.windowsphone.com/en-us/store/app/ppinng-tuner/dcde42c7-c1cd-4865-86d7-ef6321d5544e" target="_blank"&gt;&lt;img border="0" src="http://cdn.marketplaceimages.windowsphone.com/v8/images/2fce99e6-1ff9-4adb-ad37-580fde7c48a0?imageType=ws_icon_tiny" /&gt;&lt;/a&gt;&lt;/div&gt;
Audiophiles and Music lovers having a WindowsPhone will want to skip the chase and quickly try out the hot new &lt;b&gt;&lt;a href="http://www.windowsphone.com/en-us/store/app/ppinng-tuner/dcde42c7-c1cd-4865-86d7-ef6321d5544e" target="_blank"&gt;Ppinng!tuner for Windows Phone&lt;/a&gt;&lt;/b&gt;. Ppinng!tuner is a lightweight Internet Radio app that plays 8kbps news-streams and high-quality songs at 320kbps with equal ease.&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
NOTE: If you spent the last decade 100miles below the surface of the
 earth studying the growth of algae under an antarctic glacier, then you
 will be surprised to learn that we can now listen to radio over the 
internet. Just like tuning-in to particular frequencies for particular 
stations in the olden days; now we can "tune-in" to specific radio 
stations over the internet. Without further ado, lets jump-in into the 
world of "Internet Radio".&lt;br /&gt;
&lt;br /&gt;
Most apps claiming to support Internet Radio, in fact support a industry standard - &lt;b&gt;&lt;a href="http://en.wikipedia.org/wiki/SHOUTcast" target="_blank"&gt;Shoutcast&lt;/a&gt;&lt;/b&gt;. It was a protocol devised by nullsoft in the 90's and first implemented in their popular player &lt;b&gt;&lt;a href="http://en.wikipedia.org/wiki/Winamp" target="_blank"&gt;Winamp&lt;/a&gt;&lt;/b&gt;(stop
 reading if you haven't heard of Winamp!). Inspite of being a 
proprietary protocol with not much documentation to go with, Shoutcast 
has become the de-facto industry standard for streaming audio. This is 
mainly due to its simplicity and similarity with the existing hyper-text
 transfer protocol (dear old http! wink wink). &lt;b&gt;&lt;a href="http://en.wikipedia.org/wiki/Icecast" target="_blank"&gt;Icecast&lt;/a&gt;&lt;/b&gt; is a similar open-source implementation compatible with Shoutcast.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h2 style="text-align: justify;"&gt;
Initial handshake between Shoutcast client-server &lt;/h2&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-qlzhouvRNpA/USIWJEiWbyI/AAAAAAAABAo/TSb62M1uApM/s1600/shoutcast-initial.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-qlzhouvRNpA/USIWJEiWbyI/AAAAAAAABAo/TSb62M1uApM/s1600/shoutcast-initial.jpg" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;High-level overview of Internet-radio over Shoutcast. &lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div style="text-align: justify;"&gt;
&lt;h4&gt;
[STEP1] Station Listing&lt;/h4&gt;
The client app connects to a station listing/aggregator on the internet and obtains a list of stations alongwith their details like genres, language, now-playing, bitrate among other things.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
&lt;/h4&gt;
&lt;h4&gt;
[STEP2] Station Lookup&lt;/h4&gt;
The user can then select one of the stations as desired. Then the client obtains the ip-address(&amp;amp; port) of the server running that particular station from the station-listing/aggregator. Networking enthusiasts will notice that this step is exactly like a DNS lookup i.e. the client obtains the network address for a particular station name; the station-listing/aggregator acting like a DNS-server for Radio stations. Also note that sometimes the station-listing will provide only a domain-name and then an additional actual DNS lookup is needed to obtain the ip-address of the streaming server. Popular station-listing/aggregator sites like &lt;b&gt;&lt;a href="http://dir.xiph.org/" target="_blank"&gt;Xiph&lt;/a&gt;&lt;/b&gt;, &lt;b&gt;&lt;a href="http://shoutcast.com/"&gt;Shoutcast.com&lt;/a&gt;&lt;/b&gt; and &lt;b&gt;&lt;a href="http://vtuner.com/setupapp/guide/asp/BrowseStations/startpage.asp" target="_blank"&gt;vTuner&lt;/a&gt;&lt;/b&gt; provide huge web-friendly lists of live radio stations.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
[STEP3|4] Station Connection&lt;/h4&gt;
1. The client attempts to connect to the server using the ip-address(and port) obtained during station lookup. &lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="https://lh6.googleusercontent.com/-og3mEkbCP3c/USIsqstdvpI/AAAAAAAABBM/UUxRs2a6qd0/s1600/shoutcast-connect-request.png" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-og3mEkbCP3c/USIsqstdvpI/AAAAAAAABBM/UUxRs2a6qd0/s400/shoutcast-connect-request.png" height="210" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;a href="https://lh6.googleusercontent.com/-og3mEkbCP3c/USIsqstdvpI/AAAAAAAABBM/UUxRs2a6qd0/s1600/shoutcast-connect-request.png" target="_blank"&gt;Connection request from shoutcast client (click to enlarge)&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
2. The server responds with "ICY 200 OK" (a custom &lt;a href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#2xx_Success" target="_blank"&gt;200 OK success code&lt;/a&gt;)...&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-OgXyHSSH8SQ/USIssBf3TmI/AAAAAAAABBU/AdHnv3ctvlI/s1600/ICY200OK.png" imageanchor="1" style="margin-left: auto; margin-right: auto;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-OgXyHSSH8SQ/USIssBf3TmI/AAAAAAAABBU/AdHnv3ctvlI/s400/ICY200OK.png" height="208" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-OgXyHSSH8SQ/USIssBf3TmI/AAAAAAAABBU/AdHnv3ctvlI/s1600/ICY200OK.png" target="_blank"&gt;ICY 200 OK reply from shoutcast server (click to enlarge)&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
3. ...and the stream header...&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="https://lh4.googleusercontent.com/-M1IqNOvFT10/USIs1Dtlt-I/AAAAAAAABBc/KV1a4DPp71U/s1600/shoutcast-header.png" imageanchor="1" style="margin-left: auto; margin-right: auto;" target="_blank"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-M1IqNOvFT10/USIs1Dtlt-I/AAAAAAAABBc/KV1a4DPp71U/s400/shoutcast-header.png" height="210" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;a href="https://lh4.googleusercontent.com/-M1IqNOvFT10/USIs1Dtlt-I/AAAAAAAABBc/KV1a4DPp71U/s1600/shoutcast-header.png" target="_blank"&gt;Shoutcast stream header (click to enlarge)&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
4. ..and finally the server starts sending encoded audio in a continuous stream of packets(which the client app can decode and playback) until the client 
disconnects(stops ACK-ing and signals a disconnect). &lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/-dTB_v67HT1o/USIs2smMDmI/AAAAAAAABBk/i19r2PC7sg0/s1600/shoutcast-data.png" imageanchor="1" style="margin-left: auto; margin-right: auto;" target="_blank"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-dTB_v67HT1o/USIs2smMDmI/AAAAAAAABBk/i19r2PC7sg0/s400/shoutcast-data.png" height="210" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/-dTB_v67HT1o/USIs2smMDmI/AAAAAAAABBk/i19r2PC7sg0/s1600/shoutcast-data.png" target="_blank"&gt;Encoded audio data stream (click to enlarge)&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://docs.google.com/file/d/0B86sbaayeRPSXzBhUVkwTXRJSFk/edit?usp=sharing" target="_blank"&gt;&lt;b style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://upload.wikimedia.org/wikipedia/commons/d/db/Wireshark_Icon.png" height="32" width="32" /&gt;&lt;/b&gt;&lt;/a&gt;&lt;/div&gt;
&lt;a href="https://docs.google.com/file/d/0B86sbaayeRPSXzBhUVkwTXRJSFk/edit?usp=sharing" target="_blank"&gt;Download the entire WireShark capture of packets&lt;/a&gt; exchanged by the shoutcast client and server during initial station connection.&lt;b&gt; &lt;/b&gt;&lt;/blockquote&gt;
&lt;br /&gt;
&amp;nbsp;The above steps are similar to what a browser does when it connects to a website (and hence in-browser streaming audio playback of shoutcast streams IS possible).&lt;br /&gt;
&lt;br /&gt;
Shoutcast has &lt;a href="http://forums.radiotoolbox.com/viewtopic.php?t=74" target="_blank"&gt;subtle differences&lt;/a&gt; over http during the &lt;b&gt;station connection&lt;/b&gt; step above. Shoutcast supports "&lt;b&gt;Icy-MetaData&lt;/b&gt;" - an additonal field in the request header. When set, its a request to the shoutcast server to embed metadata about the stream at periodic intervals(once every "&lt;b&gt;icy-metaint&lt;/b&gt;" bytes) in the encoded audio stream itself. The value of "&lt;b&gt;icy-metaint&lt;/b&gt;" is decided by the shoutcast server configuration and is sent to the client as part of the initial reply.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-BJMe7DT59P0/USIblA2sp_I/AAAAAAAABA4/YHLZ82QMD6g/s1600/shoutcast-metadata.jpg" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-BJMe7DT59P0/USIblA2sp_I/AAAAAAAABA4/YHLZ82QMD6g/s1600/shoutcast-metadata.jpg" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Shoutcast stream format when ICY:MetaData is set to 1&lt;/td&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
This poses a slight complication during playback. If the received audio stream is directly queued for playback, then the embedded metadata appears as periodic glitches. Following is one such sample recording.
This audio clip was retrieved from a radio stream whose icy:metaint = 
32768; i.e. the metadata is embedded in the audio stream once every 
32KBytes. Stream bit-rate is 4KBps. &lt;b&gt;So during playback a glitch is 
present once every 32KB/4KB = 8seconds (0:08s, 0:16s, 0:24s, 0:32s,...).&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;iframe frameborder="no" height="166" scrolling="no" src="https://w.soundcloud.com/player/?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F79796804&amp;amp;color=ff7f00&amp;amp;auto_play=false&amp;amp;show_artwork=false" width="100%"&gt;&lt;/iframe&gt;

&lt;br /&gt;
&lt;br /&gt;
To view/analyse the stream data in a hex editor, &lt;a href="https://soundcloud.com/thecodeartist/shoutcast-metadata" target="_blank"&gt;download the actual clip&lt;/a&gt; and check out the following offsets :&lt;br /&gt;
&lt;br /&gt;
[0:08s] 0x0815A - 0x0817A count N = 2, meta = 1+ (16 x 2) = 33(0x21h)bytes&lt;br /&gt;
[0:16s] 0x1017B - 0x1017B count N = 0, meta = 1byte&lt;br /&gt;
[0:24s] 0x1817C - 0x1817C count N = 0, meta = 1byte &lt;br /&gt;
[0:32s] 0x2017D - 0x2017D count N = 0, meta = 1byte&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-GYwRA3LCmXY/USMMRODF3JI/AAAAAAAABB4/iUsA-9lQpIY/s1600/stream-metadata-hex.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-GYwRA3LCmXY/USMMRODF3JI/AAAAAAAABB4/iUsA-9lQpIY/s480/stream-metadata-hex.jpg" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Embedded metadata from 0x0815A to 0x0817a.&lt;br /&gt;
Note the first byte is 02 i.e. metadata is 2x16=32(0x20h)bytes following it.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
Also note that the first 345(0x159h)bytes of the &lt;a href="https://soundcloud.com/thecodeartist/shoutcast-metadata" target="_blank"&gt;actual clip&lt;/a&gt; are the reply header of the 
stream(plain-text in ASCII) sent by the shoutcast server. Technically 
these are NOT part of the audio stream as well.&lt;br /&gt;
&lt;br /&gt;
NOTE: If you simply want to obtain the audio stream (no embedded metadata) then set the "&lt;b&gt;Icy-MetaData" field in the request header to 0 &lt;/b&gt;or simply do NOT pass it as part of the initial request header.&lt;br /&gt;
&lt;br /&gt;
Finally here is a small bit of code that implements all that we have learnt so far - a simple shoutcast client in a few lines of C, that connects to any shoutcast server and logs the audio stream data to stdout. It uses the curl library to initiate connection requests to the shoutcast server.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/TheCodeArtist/2f1b9fa68197e39ca9bc.js"&gt;&lt;/script&gt;&lt;a href="https://gist.github.com/TheCodeArtist/2f1b9fa68197e39ca9bc"&gt;https://gist.github.com/TheCodeArtist/2f1b9fa68197e39ca9bc&lt;/a&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-size: small;"&gt;Stripping off the comments and the clean-up code following line:50, it comes down to 13 lines of C code. Pretttty neat eh?...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
Usage:&lt;br /&gt;
$&amp;gt; &lt;b&gt;sudo apt-get install libcurl4-gnutls-dev&lt;/b&gt;&lt;br /&gt;
$&amp;gt; &lt;b&gt;gcc simple.c -o simple -l libcurl&lt;/b&gt;&lt;br /&gt;
$&amp;gt; &lt;b&gt;./simple &lt;/b&gt;&amp;lt;&lt;i&gt;shoutcast-server-ip-addr:port&lt;/i&gt;&amp;gt;&lt;b&gt; &amp;gt; &lt;/b&gt;&amp;lt;&lt;i&gt;test-file&lt;/i&gt;&amp;gt; &lt;/blockquote&gt;
&lt;br /&gt;
&lt;span style="font-size: small;"&gt;After running the above commands, the &lt;i&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&amp;lt;&lt;/span&gt;test-file&lt;span style="font-size: small;"&gt;&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/span&gt; &lt;test .file=""&gt;will contain the audio stream of that particular internet radio station. The &lt;test-file&gt; can be played back in any player that supports decoding the stream format(AAC, MP3, OGG etc. depending on the radio station) Make sure to comment out line 38 in simple.c to have a glitch-free(no embedded metadata) audio stream.&lt;/test-file&gt;&lt;/test&gt;&lt;br /&gt;
&lt;br /&gt;
This concludes part 1 of the series on how internet radio works. In part2 we will analyse the challenges and issues faced during de-packetising, parsing and queuing the audio stream buffers for local playback. &lt;a href="http://feeds.feedburner.com/TheCodeArtist" target="_blank"&gt;&lt;b&gt;Stay tuned for updates&lt;/b&gt;&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;div class="separator" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: center;"&gt;
&lt;a href="http://www.windowsphone.com/en-us/store/app/ppinng-tuner/dcde42c7-c1cd-4865-86d7-ef6321d5544e" target="_blank"&gt;&lt;img border="0" src="http://cdn.marketplaceimages.windowsphone.com/v8/images/2fce99e6-1ff9-4adb-ad37-580fde7c48a0?imageType=ws_icon_tiny" /&gt;&lt;/a&gt;&lt;/div&gt;
If you enjoyed reading about how internet radio works, then you might also want to try out the hot new &lt;b&gt;&lt;a href="http://www.windowsphone.com/en-us/store/app/ppinng-tuner/dcde42c7-c1cd-4865-86d7-ef6321d5544e" target="_blank"&gt;Ppinng!tuner for Windows Phone&lt;/a&gt;&lt;/b&gt;. Ppinng!tuner is a&amp;nbsp; lightweight Internet Radio app that plays 8kbps news-streams and high-quality songs at 320kbps with equal ease.&lt;/blockquote&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=Y0u6o38b0O8:mnt8piJikt0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=Y0u6o38b0O8:mnt8piJikt0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=Y0u6o38b0O8:mnt8piJikt0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=Y0u6o38b0O8:mnt8piJikt0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/Y0u6o38b0O8" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2013-02-24T13:33:28.927+05:30</app:edited><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-qlzhouvRNpA/USIWJEiWbyI/AAAAAAAABAo/TSb62M1uApM/s72-c/shoutcast-initial.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><georss:featurename xmlns:georss="http://www.georss.org/georss">Bangalore, Karnataka, India</georss:featurename><georss:point xmlns:georss="http://www.georss.org/georss">12.9715987 77.59456269999998</georss:point><georss:box xmlns:georss="http://www.georss.org/georss">12.4764197 76.94911569999998 13.4667777 78.24000969999999</georss:box><feedburner:origLink>http://thecodeartist.blogspot.com/2013/02/shoutcast-internet-radio-protocol.html</feedburner:origLink></item><item><title>HDD, FS, O_SYNC : Throughput vs. Integrity</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/gK4-95HFm6g/hdd-filesystems-osync.html</link><category>linux-kernel</category><category>linux</category><category>CodeProject</category><category>SATA</category><category>page-cache</category><category>HDD</category><category>data-barrier</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Mon, 03 Dec 2012 23:24:35 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-4993649928680510170</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
Today we will spend some time over filesystems, block-devices, throughput and data-integrity. But first, a few "MYTHBUSTER" statements.&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;blockquote class="tr_bq"&gt;
#1: Even the fastest HDD today can do ONLY 650KBps natively.&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;blockquote class="tr_bq"&gt;
#2: O_SYNC on a filesystem does NOT guarantee a write to the HDD.&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;blockquote class="tr_bq"&gt;
#3: Raw-I/O over BLOCK devices DOES guarantee data-integrity.&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;b&gt;Hard to believe, right? Lets analyse these statements one by one...&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Verdana,sans-serif;"&gt;The fastest Hard-disk drives today run at 10,000RPM (compared to regular
 ones at 5400,7200). Also the faster HDDs have transitioned to a 4096 
byte internal block-size (compared to 512 bytes on regular ones).&lt;/span&gt; &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-ksvQJ3xe-n8/UDzF09TQOtI/AAAAAAAAA9E/Sj6uFQy-3fw/s1600/hdd-params.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-ksvQJ3xe-n8/UDzF09TQOtI/AAAAAAAAA9E/Sj6uFQy-3fw/s1600/hdd-params.jpg" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;span style="font-size: small;"&gt;Details of &lt;b&gt;&lt;a href="http://en.wikipedia.org/wiki/Hard_disk_drive#Components" target="_blank"&gt;HDD components&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
To read/write one particular sector from/to the HDD, the head needs to be first aligned radially in the proper position. Next one waits as the rotating disk platter positions the desired sector under the disk-head. Now one is able read/write to the sector.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-bqwnoZXFodA/UDzGukxpIyI/AAAAAAAAA9M/gasjxs9XYiM/s1600/disk-head-platter.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-bqwnoZXFodA/UDzGukxpIyI/AAAAAAAAA9M/gasjxs9XYiM/s1600/disk-head-platter.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;div style="text-align: center;"&gt;
Unit of data on HDD = 1 sector =4096 bytes&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
MAX RPM = 10,000 = 10,000/60 = 166.667 rotations/second&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
Seek-time = 1/166.667 = 0.006s&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
Throughput = 4096/0.006 = 682666.667 ~ &lt;u&gt;&lt;b&gt;650KBps&lt;/b&gt;&lt;/u&gt;&lt;/div&gt;
&lt;br /&gt;
The above calculation assumes the worst possible values for both the I/O-size(1 sector) and seek-time(1 entire rotation). This condition though is quite easily seen in real life scenarios like database applications which use the HDD as a raw block-device.&lt;br /&gt;
&lt;br /&gt;
Better speeds in the range of 20-50MBps are commonly obtained by a combination of several strategies like:&lt;/div&gt;
&lt;ul style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;li&gt;Multi-block I/O.&lt;/li&gt;
&lt;li&gt;Native Command Queueing.&lt;/li&gt;
&lt;li&gt;RAID stripping. &lt;/li&gt;
&lt;/ul&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
Now lets consider a regular I/O request at the HDD level:&lt;br /&gt;
&lt;h2&gt;
HDD Read:&lt;/h2&gt;
&lt;/div&gt;
&lt;ol style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;li&gt;The kernel raises a disk read request to the HDD.The HDD has a small amount of disk-cache (RAM) which it checks to see if the requested data exists.&lt;/li&gt;
&lt;li&gt;If NOT found in the disk-cache then the disk-head is moved to the data location on the platter.&lt;/li&gt;
&lt;li&gt;The data is read into disk-cache and a copy is returned to the kernel.&lt;/li&gt;
&lt;/ol&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;h2&gt;
HDD Write:&lt;/h2&gt;
&lt;/div&gt;
&lt;ol style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;li&gt;The kernel raises a disk write request to the HDD.&lt;/li&gt;
&lt;li&gt;The HDD has a small amount of cache (RAM) where the data to be written is placed.&lt;/li&gt;
&lt;li style="font-family: Verdana,sans-serif;"&gt;An on-board disk controller is in-charge of the saving the contents of the cache to the platter. It operates on the following set of rules:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;li&gt;[Rule1] Write cache to platter as soon as possible.&lt;/li&gt;
&lt;li&gt;[Rule2] Re-order write operations in sequence of platter location.&lt;/li&gt;
&lt;li&gt;[Rule3] Bunch several random writes together into one sequence.&lt;/li&gt;
&lt;/ul&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-Vlm3TrD1nvQ/UDzJDy8axDI/AAAAAAAAA9U/QByOAxFAC_s/s1600/T-800-disk-controller.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-Vlm3TrD1nvQ/UDzJDy8axDI/AAAAAAAAA9U/QByOAxFAC_s/s1600/T-800-disk-controller.jpg" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;span style="font-size: small;"&gt;"Hasta la vista, baby!"&lt;br /&gt;HUD of the disk-IO firmware running on a &lt;b&gt;&lt;a href="http://www.youtube.com/watch?v=jp5KTSaFhY0" rel="nofollow" target="_blank"&gt;T-800 Terminator&lt;/a&gt;&lt;/b&gt; ;-)&lt;b&gt;&lt;a href="http://www.youtube.com/watch?v=9MeaaCwBW28" target="_blank"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
[Rule1] &lt;u&gt;minimises data loss&lt;/u&gt;. As cache is volatile i.e. any power-outage will mean that data (in the HDD-cache), which is NOT yet written to the HDD-platter, is lost.&lt;br /&gt;
&lt;br /&gt;
[Rule2] &lt;u&gt;optimises the throughput&lt;/u&gt;. As serialising access reduces the time spent in seeking by the read-write head.&lt;br /&gt;
&lt;br /&gt;
[Rule3] &lt;u&gt;reduces power consumption, disk-wear&lt;/u&gt; by allowing the disk to be stopped from constantly spinning all the time. Only when the cache is filled to a certain limit the disk motor is powered on and the cache is flushed to the platter, following which the motor is powered-down again until the next cache flush.&lt;br /&gt;
&lt;br /&gt;
Its obvious that [1] [2] [3] are counter-productive and the right balance needs to be struck between the three to have data-integrity, high-throughput, low-power-consumption &amp;amp; longer disk-life. Several complex algorithms have been devised to handle this in modern-day HDD controllers. &lt;br /&gt;
&lt;br /&gt;
The problem though is that by default performance is sacrificed in favour of the other two. This is just a "default" setting though and the beauty of the Linux-Kernel being open-source is that one is free to stray from the "default" setting.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
If you are doing &lt;u&gt;mostly sequential raw block-I/O&lt;/u&gt; on a SATA HDD, you would be a prime candidate for this &lt;b&gt;&lt;a href="https://gist.github.com/93dddcd6a21dc81414ba" target="_blank"&gt;patch&lt;/a&gt;&lt;/b&gt;, which effectively moves the operation-point of the HDD closer to high-performance region in the map.&lt;/blockquote&gt;
&amp;nbsp;&amp;nbsp;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-6fqn622U-oI/UDzJmRM3aGI/AAAAAAAAA9c/l7W0gcoMoJY/s1600/perf-power-data.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-6fqn622U-oI/UDzJmRM3aGI/AAAAAAAAA9c/l7W0gcoMoJY/s1600/perf-power-data.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Moving on, we now focus on how the use of O_SYNC affects I/O on filesystems as well as the raw block device.&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-GAfGxWre7UM/UDzKLJDqziI/AAAAAAAAA9k/4-1Wiy-i9N4/s1600/data-barriers-hdd-write.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-GAfGxWre7UM/UDzKLJDqziI/AAAAAAAAA9k/4-1Wiy-i9N4/s1600/data-barriers-hdd-write.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;br /&gt;
&lt;h2&gt;
Regular write on a regular filesystem&lt;/h2&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;blockquote class="tr_bq" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;b&gt;fd = open("/media/mount1/file");&lt;/b&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
Consider the first case where one does a regular write(NO O_SYNC flag) on a regular filesystem on a HDD. The data is copied from the APP to the FS i.e. userspace-app(RAM) into the kernel filesystem page-cache(RAM) and control returns. During this, one does NOT cross any data-barriers and hence data is NOT guaranteed to be written to the HDD. This makes the entire process of a regular write on an fs extremely fast.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h2&gt;
Synchronous write on a regular filesystem&lt;/h2&gt;
&lt;div style="text-align: justify;"&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;b style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;fd = open("/media/mount1/file", O_SYNC);&lt;/b&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
The second case illustrated above depicts a synchronous write (with O_SYNC flag) on a regular filesystem on a HDD. The man page for open() call contains the following notes:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;blockquote class="tr_bq" style="font-family: Verdana,sans-serif;"&gt;
O_SYNC The file is opened for synchronous I/O. Any writes on the resulting file descriptor will block the calling process until the data has been physically written to the underlying hardware.&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;br /&gt;
Although using O_SYNC looks like a sureshot guarantee that data is indeed written to disk, there lies a catch in the implementation. Most HDDs contain a on-board cache on the HDD itself. A write command to the disk transfers the data from the kernel filesystem page-cache(RAM) to the HDD-cache(not the actual mechanical platter of the disk.) This process is limited by the bus(SATA, IDE etc) which is faster than the actual mechanical platter. When a HDD receives a write command, it copies the data into its internal HDD-cache and returns immediately. The HDD's internal firmware later transfers the data to the disk-platter according to its "3 rules" as discussed previously. Thus a write to HDD does NOT necessarily imply a write to the disk platter. Hence even synchronous writes on a filsystem do NOT imply 100% data integrity.&lt;br /&gt;
&lt;br /&gt;
Also a data-barrier exists along this path in the filesystem layer where metadata(inode,superblock) info is stored. This will help in identifying any data integrity on future access. Note that maintaining/updating inode,superblocks does NOT guarantee that the data is written to disk. Rather it makes the last sequence of writes atomic (i.e. all the writes get committed to disk or none). The inode,superblock info serves as a kind of checksum as they are updated accordingly following the atomic write operation. All this processing means that throughput incurs a slight penalty in this case.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;h2&gt;
Synchronous write on a block device&lt;/h2&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;b style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;fd = open("/dev/sda", O_SYNC);&lt;/b&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
The third case illustrated above is a synchronous write to the HDD directly via its block-device(eg. /dev/sda). In this case there is NO data-barrier in the filesystem. The O_SYNC is implemented by using the data-barrier present in the HDD i.e. flushing&amp;nbsp; the disk-cache explicity to ensure that all the data is indeed transferred to the disk-platter before returning. This incurs the maximum penalty and hence the throughput is the slowest of all 3 scenarios above.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Salient observations:&lt;/h2&gt;
&lt;/div&gt;
&lt;ol style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;li&gt;A data barrier is a module/function across which data integrity is guaranteed i.e if the function is called and it returns successfully, then the data is completely written to non-volatile memory(HDD, in this case). A data barrier introduces an order of magnitude change in:&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;Access-time (++)&lt;/li&gt;
&lt;li&gt;Throughput&amp;nbsp; (--)&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;A data barrier in the lower layers incurs a larger penalty than one in the upper layers. (Penalty : App &amp;lt; FS &amp;lt; Disk.)&lt;/li&gt;
&lt;li&gt;O_SYNC on HDD via filesystems does NOT guarantee a successful write to non-volatile disk-platter.&lt;/li&gt;
&lt;li&gt;O_SYNC on HDD via block-device directly guarantees data-integrity but offers very low throughput.&lt;/li&gt;
&lt;li&gt;The HDD data-barrier(FLUSH_CACHE) is NOT utilised when using regular filesystems to access the HDD.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href="https://gist.github.com/93dddcd6a21dc81414ba" target="_blank"&gt;Disabling HDD data-barrier&lt;/a&gt;&lt;/b&gt; and raw DIRECT-I/O via the block device provides maximum throughput to a HDD.&lt;/li&gt;
&lt;/ol&gt;
&lt;div style="text-align: justify;"&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;b style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;fd = open("/dev/sda", O_SYNC|O_DIRECT);&lt;/b&gt;&lt;/blockquote&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
Further reading : &lt;b&gt;&lt;a href="http://thecodeartist.blogspot.com/2012/06/improving-hdd-performance-linux.html" target="_blank"&gt;5 ways to improve HDD performance on Linux&lt;/a&gt;&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=gK4-95HFm6g:gmfMQhrFzJA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=gK4-95HFm6g:gmfMQhrFzJA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=gK4-95HFm6g:gmfMQhrFzJA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=gK4-95HFm6g:gmfMQhrFzJA:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/gK4-95HFm6g" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-04T12:54:35.309+05:30</app:edited><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-ksvQJ3xe-n8/UDzF09TQOtI/AAAAAAAAA9E/Sj6uFQy-3fw/s72-c/hdd-params.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2012/08/hdd-filesystems-osync.html</feedburner:origLink></item><item><title>SATA hotplug : Add/Remove sata HDD in a jiffy</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/SkKkYMOiPfs/sata-hotplug-addremove-sata-hdd-in.html</link><category>linux</category><category>CodeProject</category><category>SATA</category><category>HDD</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Sun, 16 Sep 2012 00:35:36 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-7410773548181587069</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div style="text-align: justify;"&gt;
Its not common knowledge that SATA HDDs are capable of being hot-plugged into almost any modern PC. However using them in a plug-n-play manner like portable external USB-HDDs is still not common.&lt;/div&gt;
&lt;br /&gt;
Here is how to use your SATA HDD like an portable HDD.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Tested on:&lt;/u&gt;&lt;br /&gt;
- Ubuntu 11.10&lt;br /&gt;
- DELL Optiplex 380&lt;br /&gt;
- Seagate Barracuda 1TB (SATA).&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;











1. Connect the SATA HDD to host PC. (sata-bus + power) &lt;/h2&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;img border="0" src="http://3.bp.blogspot.com/-pW_Norp8VCI/T9roDCtfy1I/AAAAAAAAA2k/rNvlFlgxmMg/s1600/sata-hdd.jpg" /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h2&gt;











2. Scan for new devices on SCSI host&lt;/h2&gt;
&lt;blockquote class="tr_bq"&gt;
sudo echo "- - -" &amp;gt; /sys/class/scsi_host/host&lt;b&gt;N&lt;/b&gt;/scan&lt;/blockquote&gt;
where &lt;b&gt;N&lt;/b&gt; is the host port number on your host PC to which you have plugged-in the SATA HDD. Usually N=1, assuming the primary HDD on host PC is connected on SATA0.&lt;br /&gt;
&lt;br /&gt;
"- - -" stands for wildcards in place of the&lt;br /&gt;
channel number, SCSI target ID, and LUN. &lt;a href="http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/5/html/Online_Storage_Reconfiguration_Guide/adding_storage-device-or-path.html" target="_blank"&gt;&lt;b&gt;More Info&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;











3. Mount the newly detected device locally &lt;/h2&gt;
&lt;blockquote class="tr_bq"&gt;
sudo mount /dev/sd&lt;b&gt;X&lt;/b&gt; /media/temphdd&lt;/blockquote&gt;
where &lt;b&gt;X&lt;/b&gt; is a/b/c/d etc. Usually X=b, assuming the primary HDD on host PC is enumerated as sda an there are no other block devices.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;











4. Copy all your data to/from the HDD present at /media/tempHDD. &lt;/h2&gt;
&lt;br /&gt;
&lt;h2&gt;











5. Once finished, unmount the device&lt;/h2&gt;
&lt;blockquote class="tr_bq"&gt;
sudo umount /media/temphdd&lt;/blockquote&gt;
&lt;br /&gt;
&lt;h2&gt;











6. Powering down the SATA HDD&lt;/h2&gt;
&lt;blockquote class="tr_bq"&gt;
sudo echo 1 &amp;gt; /sys/block/sd&lt;b&gt;X&lt;/b&gt;/device/delete&lt;/blockquote&gt;
Ensure that you refer to the proper device (sdb, sdc etc.) as above in step 3.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;











7. Disconnect the SATA HDD from host PC.&lt;/h2&gt;
Thats it! Thats how one can use the hotplug feature of SATA HDDs to efectively use them as portable external HDDs.&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=SkKkYMOiPfs:qLMU1g-0BMk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=SkKkYMOiPfs:qLMU1g-0BMk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=SkKkYMOiPfs:qLMU1g-0BMk:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=SkKkYMOiPfs:qLMU1g-0BMk:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/SkKkYMOiPfs" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2012-09-16T13:05:36.038+05:30</app:edited><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-pW_Norp8VCI/T9roDCtfy1I/AAAAAAAAA2k/rNvlFlgxmMg/s72-c/sata-hdd.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2012/06/sata-hotplug-addremove-sata-hdd-in.html</feedburner:origLink></item><item><title>5 ways to improve HDD speed on Linux</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/LKqjxsyN0aA/improving-hdd-performance-linux.html</link><category>C</category><category>Programming</category><category>linux-kernel</category><category>linux</category><category>CodeProject</category><category>cache</category><category>page-cache</category><category>HDD</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Sun, 17 Feb 2013 01:45:38 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-1133135425967887361</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
LINUX &lt;b&gt;LINUX&lt;/b&gt; LINUX &lt;b&gt;LINUX&lt;/b&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;b&gt;LINUX&lt;/b&gt; LINUX &lt;b&gt;LINUX&lt;/b&gt; LINUX&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;span style="font-size: x-small;"&gt;(If you still think this post is about making windows load faster, then press ALT+F4 to continue)&lt;/span&gt;&lt;/div&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-AipPFQfn-C8/T9rqKsY4lBI/AAAAAAAAA2s/FBKzaCn_qqw/s1600/Y-U-no-go-faster-hdd.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-AipPFQfn-C8/T9rqKsY4lBI/AAAAAAAAA2s/FBKzaCn_qqw/s1600/Y-U-no-go-faster-hdd.jpg" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Our dear Mr. Client&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
&lt;div style="text-align: justify;"&gt;
Its a fine sunny sunday morning. Due tomorrow, is your presentation to a client on improving disk-I/O. You pull yourself up by your boots and manage to climb out of bed and onto your favorite chair...&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-OE-880QqLoo/T9sJmEbsLqI/AAAAAAAAA3I/pknLzIaFO4c/s1600/blurry-window.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-OE-880QqLoo/T9sJmEbsLqI/AAAAAAAAA3I/pknLzIaFO4c/s1600/blurry-window.jpg" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;I think you forgot to wear your glasses...&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;img border="0" src="http://4.bp.blogspot.com/-W-_DuM3mnbQ/T9sJsF-3IQI/AAAAAAAAA3Q/jNd3_n4WbXw/s1600/clear-window.jpg" /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
Aahh thats better... You jump into the couch and turn on your laptop and launch &lt;u&gt;(your favorite presentation app here)&lt;/u&gt;. As you sip your morning coffee and wait for the app to load, you look out of the window and wonder what it could be doing.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-ZCvvVTTP9Pg/T9sJy0mC5oI/AAAAAAAAA3Y/Irk17AweJWU/s1600/disk-io-simple.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-ZCvvVTTP9Pg/T9sJy0mC5oI/AAAAAAAAA3Y/Irk17AweJWU/s1600/disk-io-simple.jpg" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Looks simple, right? Then why is it taking so long?&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;img border="0" src="http://4.bp.blogspot.com/-U3stpdaHv3g/T9sJ8ExdvFI/AAAAAAAAA3g/b_66LGqcUG0/s1600/we-need-to-go-deeper.jpg" /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
If you would be so kind enough to wipe your rose-coloured glasses clean, you would see that this is what is ACTUALLY happening&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;img border="0" src="http://2.bp.blogspot.com/-I8SzXiayCrU/T9sKCKVNqVI/AAAAAAAAA3o/YGngspgi9-U/s1600/disk-io-detailed.jpg" /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
0. The app (running in RAM) decides that it wants to play spin-the-wheel with your hard-disk.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
1. It initiates a disk-I/O request to read some data from the HDD to RAM(userspace).&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
2. The kernel does a quick check in its page-cache(again in RAM) to see if it has this data from any earlier request. Since you just switched-on your computer,... &lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
3. ...the kernel did NOT find the requested data in the page-cache. "Sigh!" it says and starts its bike and begins it journey all the way to HDD-land. On its way, the kernel decides to call-up its old friend "HDD-cache" and tells him that he will be arriving shortly to collect a package of data from HDD-land. HDD-cache, the good-friend as always, tells the kernel not to worry and thet everything will be ready by the time he arrives in HDD-land.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
4. HDD-cache starts spinning the HDD-disk...&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
5. ...and locates and collects the data.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
6. The kernel reaches HDD-land and picks-up the data package and starts back.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
7. Once back home, it saves a copy of the package in its cache in case the app asks for it again. (Poor kernel has NO way of knowing that the app has no such plans).&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
8. The kernel gives the package of data to the app...&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
9. ...which promptly stores it in RAM(userspace).&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
Do keep in mind that this is how it works in case of extremely disciplined, well-behaved apps. At this point misbehaving apps tend to go - &lt;/div&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
"Yo kernel, ACTUALLY, i didn't allocate any RAM, i wanted to just see if the file existed. Now that i know it does, can you please send me this other file from some other corner of HDD-land."&lt;/blockquote&gt;
...and the story continues...&lt;br /&gt;
&lt;br /&gt;
Time to go refill your coffee-cup. Go go go...&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-_tkdpkqDJPE/T9sKJJO3zSI/AAAAAAAAA3w/fksNDwUYlEM/s1600/coffee-n-donuts.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-_tkdpkqDJPE/T9sKJJO3zSI/AAAAAAAAA3w/fksNDwUYlEM/s1600/coffee-n-donuts.jpg" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Hmmm... you are back with some donuts too. Nice caching!&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
So as you sit there having coffee and donuts, you wonder how does one really improve the disk-I/O performance. Improving performance can mean different things to different people:&lt;/div&gt;
&lt;br /&gt;
&lt;ol style="text-align: left;"&gt;
&lt;li&gt;Apps should NOT slow down waiting for data from disk.&lt;/li&gt;
&lt;li&gt;One disk-I/O-heavy app should NOT slow down another app's disk-I/O.&lt;/li&gt;
&lt;li&gt;Heavy disk-I/O should NOT cause increased cpu-usage.&lt;/li&gt;
&lt;li&gt;(&lt;u&gt;Enter your client's requirement here&lt;/u&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
So when the disk-I/O throughput is PATHETIC, what does one do?...&lt;/div&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-JVjisO18cNQ/T9sIMYjSacI/AAAAAAAAA24/goAuZbMe5QQ/s1600/5-ways-optimise-hdd.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-JVjisO18cNQ/T9sIMYjSacI/AAAAAAAAA24/goAuZbMe5QQ/s1600/5-ways-optimise-hdd.jpg" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;5 WAYS to optimise your HDD throughput!&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;





































1. Bypass page-cache for "read-once" data.&lt;/h2&gt;
&lt;div style="text-align: justify;"&gt;
What exactly does page-cache do? It caches recently accessed pages from the HDD. Thus reducing seek-times for subsequent accesses to the same data. The key here being subsequent. The page-cache does NOT improve the performance the first time a page is accessed from the HDD. So if an app is going to read a file once and just once, then bypassing the page-cache is the better way to go. This is possible by using the &lt;b&gt;O_DIRECT&lt;/b&gt; flag. This means that the kernel does NOT considered this particular data for the page-cache. Reducing cache-contention means that other pages (which wouold be accessed repeatedly) have a better chance of being retained in the page-cache. This improves the cache-hit ratio i.e better performance.&lt;/div&gt;
&lt;code class="tr_bq"&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;void ioReadOnceFile()&lt;br /&gt;
{&lt;br /&gt;
/*&amp;nbsp; Using direct_fd and direct_f bypasses kernel page-cache.&lt;/span&gt;
&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;
&amp;nbsp;*&amp;nbsp; - direct_fd is a low-level file descriptor&lt;br /&gt;
&amp;nbsp;*&amp;nbsp; - direct_f is a filestream similar to one returned by fopen()&lt;br /&gt;
&amp;nbsp;*&amp;nbsp; NOTE: Use getpagesize() for determining optimal sized buffers.&lt;br /&gt;
&amp;nbsp;*/&lt;br /&gt;&lt;br /&gt;
int direct_fd = open("filename", O_DIRECT | O_RDWR);&lt;/span&gt;
&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;
FILE *direct_f = fdopen(direct_fd, "w+");&lt;br /&gt;&lt;br /&gt;
/* direct disk-I/O done HERE*/&lt;/span&gt;
&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&lt;br /&gt;
fclose(f);&lt;/span&gt;
&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;
close(fd);&lt;br /&gt;
}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;




































2. Bypass page-cache for large files.&lt;/h2&gt;
&lt;div style="text-align: justify;"&gt;
Consider the case of a reading in a large file (ex: a database) made of a huge number of pages. Every subsequent page accessed get into the page-cache only to be dropped out later as more and more pages are read. This severely reduces the cache-hit ratio. In this case the page-cache does NOT provide any performance gains. Hence one would be better off bypassing the page-cache when accessing large files.&lt;/div&gt;
&lt;br /&gt;
&lt;code class="tr_bq"&gt;
&lt;span style="font-size: x-small;"&gt;void ioLargeFile()&lt;br /&gt;
{&lt;br /&gt;
/*&amp;nbsp; Using direct_fd and direct_f bypasses kernel page-cache.&lt;/span&gt;
&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;
&amp;nbsp;*&amp;nbsp; - direct_fd is a low-level file descriptor&lt;br /&gt;
&amp;nbsp;*&amp;nbsp; - direct_f is a filestream similar to one returned by fopen()&lt;br /&gt;
&amp;nbsp;*&amp;nbsp; NOTE: Use getpagesize() for determining optimal sized buffers.&lt;br /&gt;
&amp;nbsp;*/&lt;br /&gt;&lt;br /&gt;
int direct_fd = open("largefile.bin", O_DIRECT | O_RDWR | O_LARGEFILE);&lt;/span&gt;
&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;
FILE *direct_f = fdopen(direct_fd, "w+");&lt;br /&gt;&lt;br /&gt;
/* direct disk-I/O done HERE*/&lt;/span&gt;
&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&lt;br /&gt;
fclose(f);&lt;/span&gt;
&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;
close(fd);&lt;br /&gt;
}&lt;/span&gt;
&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;

























3. If (cpu-bound) then scheduler == no-op;&lt;/h2&gt;
&lt;div style="text-align: justify;"&gt;
The io-scheduler optimises the order of I/O operations to be queued on to the HDD. As seek-time is the heaviest penalty on a HDD, most I/O schedulers attempt to minimise the seek-time. This is implemented as a variant of the elevator algorithm i.e. re-ordering the randomly ordered requests from numerous processes to the order in which the data is present on the HDD. require a significant amount of CPU-time.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Certain tasks that involve complex operations tend to be limited by how fast the cpu can process vast amounts of data. A complex I/O-scheduler running in the background can be consuming precious CPU cycles, thereby reducing the system performance. In this case, switching to a simpler algorithm like no-op reduces the CPU load and can improve system performance.&lt;/div&gt;
&lt;code class="tr_bq"&gt;&lt;span style="font-size: x-small;"&gt;echo noop &amp;gt; /sys/block/&amp;lt;block-dev&amp;gt;&lt;block -device="-device"&gt;/queue/scheduler&lt;/block&gt;&lt;/span&gt;&lt;br /&gt;&lt;block -device="-device"&gt;&lt;/block&gt;&lt;/code&gt;&lt;block -device="-device"&gt;&lt;br /&gt;
&lt;/block&gt;&lt;br /&gt;
&lt;h2&gt;

































4. Block-size: Bigger is Better&lt;/h2&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;b&gt;Q. How will you &lt;a href="http://www.amazon.com/gp/product/B000JBY0RY/ref=as_li_qf_sp_asin_tl?ie=UTF8&amp;amp;tag=thec045-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=B000JBY0RY"&gt;move Mount Fuji&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=thec045-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=B000JBY0RY" style="border: none !important; margin: 0px !important;" width="1" /&gt;
 to bangalore?&lt;/b&gt;&lt;br /&gt;
Ans. Bit by bit.&lt;/blockquote&gt;
&lt;div style="text-align: justify;"&gt;
While this will eventually get the job done, its definitely NOT the most optimal way. From the kernel's perspective, the most optimal size for I/O requests is the the filesystem blocksize (i.e the page-size). As all I/O in the filesystem (and the kernel page-cache) is in terms of pages, it makes sense for the app to do transfers in multiples of pages-size too. Also with multi-segmented caches making their way into HDDs now, one would hugely benefit by doing I/O in multiples of block-size.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-K3fmQj6PRmo/T9sKTHLBvaI/AAAAAAAAA34/fzfOrGbu4kY/s1600/block-size-vs-throughput.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-K3fmQj6PRmo/T9sKTHLBvaI/AAAAAAAAA34/fzfOrGbu4kY/s1600/block-size-vs-throughput.jpg" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Barracuda 1TB HDD : Optimal I/O block size 2M (=4blocks)&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
The following command can be used to determine the optimal block-size &lt;br /&gt;
&lt;code class="tr_bq"&gt;&lt;span style="font-size: x-small;"&gt;stat --printf="bs=%s optimal-bs=%S\n" --file-system /dev/&amp;lt;block-dev&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&lt;/span&gt; &lt;br /&gt;
&lt;block -device="-device"&gt;
&lt;/block&gt;
&lt;br /&gt;
&lt;h2&gt;


5. SYNC vs. ASYNC (&amp;amp; read vs. write)&lt;/h2&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-vsDYg0I-UnA/T9sKY45vDqI/AAAAAAAAA4A/wHnX4rU8SKw/s1600/disk-io-detailed-async.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-vsDYg0I-UnA/T9sKY45vDqI/AAAAAAAAA4A/wHnX4rU8SKw/s1600/disk-io-detailed-async.jpg" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;ASYNC I/O i.e. non-blocking mode is effectively faster with cache&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
&lt;div style="text-align: justify;"&gt;
&lt;block -device="-device"&gt;&lt;u&gt;&lt;b&gt;When an app initiates a SYNC I/O read&lt;/b&gt;&lt;/u&gt;, the kernel queues a read operation for the data and returns only after the entire block of requested data is read back. During this period, the Kernel will mark the app's process as blocked for I/O. Other processes can utilise the CPU, resulting in a overall better performance for the system.&lt;/block&gt;&lt;br /&gt;
&lt;block -device="-device"&gt;&lt;/block&gt;&lt;br /&gt;
&lt;block -device="-device"&gt;&lt;u&gt;&lt;b&gt;When an app initiates a SYNC I/O write&lt;/b&gt;&lt;/u&gt;, the kernel queues a write operation for the data puts the app's process in a blocked I/O. Unfortunately what this means is that the current app's process is blocked and cannot do any other processing (or I/O for that matter) until this write operation completes.&lt;/block&gt;&lt;br /&gt;
&lt;block -device="-device"&gt;&lt;/block&gt;&lt;br /&gt;
&lt;block -device="-device"&gt;&lt;u&gt;&lt;b&gt;When an app initiates an ASYNC I/O read&lt;/b&gt;&lt;/u&gt;, the read() function usually returns after reading a subset of the large block of data. The app needs to repeatedly call read() with the size of data remaining to be read, until the entire required data is read-in. Each additional call to read introduces some overhead as it introduces a context-switch between the userspace and the kernel. Implementing a tight loop to repeatedly call read() wastes CPU cycles that other processes could have used. Hence one usually implements blocking using select() until the next read() returns non-zero bytes read-in. i.e the ASYNC is made to block just like the SYNC read does.&lt;/block&gt;&lt;br /&gt;
&lt;block -device="-device"&gt;&lt;/block&gt;&lt;br /&gt;
&lt;block -device="-device"&gt;&lt;u&gt;&lt;b&gt;When an app initiates an ASYNC I/O write&lt;/b&gt;&lt;/u&gt;, the kernel updates the corresponding pages in the page-cache and marks them dirty. Then the control quickly returns to the app which can continue to run. The data is &lt;a href="http://www.westnet.com/%7Egsmith/content/linux-pdflush.htm" target="_blank"&gt;flushed to HDD&lt;/a&gt; later at a more optimal time(low cpu-load) in a more optimal way(sequentially bunched writes).&lt;/block&gt;&lt;br /&gt;
&lt;block -device="-device"&gt;&lt;/block&gt;&lt;br /&gt;
&lt;block -device="-device"&gt;Hence, &lt;b&gt;SYNC-reads&lt;/b&gt; and &lt;b&gt;ASYNC-writes&lt;/b&gt; are generally a good way to go as they allow the kernel to optimise the order and timing of the underlying I/O requests.&lt;/block&gt;&lt;br /&gt;
&lt;block -device="-device"&gt;&lt;/block&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;block -device="-device"&gt;&lt;/block&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
&lt;block -device="-device"&gt;There you go. I bet you now have quite a lot of things to say in your presentation about improving disk-IO. ;-)&lt;/block&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;block -device="-device"&gt;&lt;span id="goog_989967194"&gt;&lt;/span&gt;&lt;span id="goog_989967195"&gt;&lt;/span&gt;PS: If your client fails to comprehend all this (just like when he saw inception for the first time), then do not despair. Ask him to go buy a &lt;a href="http://ark.intel.com/compare/66247" target="_blank"&gt;freaking-fast SSD&lt;/a&gt; and he will never bother you again.&lt;/block&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;block -device="-device"&gt;More on &lt;b&gt;&lt;a href="http://thecodeartist.blogspot.com/2012/08/hdd-filesystems-osync.html" target="_blank"&gt;How data-barriers affect HDD Throughput and Data-integrity&lt;/a&gt;&lt;/b&gt;. &lt;/block&gt;&lt;/div&gt;
&lt;block -device="-device"&gt;&lt;/block&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=LKqjxsyN0aA:vn0q5nU8Weo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=LKqjxsyN0aA:vn0q5nU8Weo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=LKqjxsyN0aA:vn0q5nU8Weo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=LKqjxsyN0aA:vn0q5nU8Weo:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/LKqjxsyN0aA" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2013-02-17T15:15:38.259+05:30</app:edited><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-AipPFQfn-C8/T9rqKsY4lBI/AAAAAAAAA2s/FBKzaCn_qqw/s72-c/Y-U-no-go-faster-hdd.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2012/06/improving-hdd-performance-linux.html</feedburner:origLink></item><item><title>Omnivison ov3640 i2c sccb</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/9iDWaa4s9do/omnivison-ov3640-i2c-sccb.html</link><category>Omnivision</category><category>Programming</category><category>sccb</category><category>i2c</category><category>Camera</category><category>ov3640</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Tue, 11 Sep 2012 13:07:15 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-4216154803100092755</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-af92_nBJ4eQ/T52g0Et_U0I/AAAAAAAAA0U/AS2jsQN_j2U/s1600/ov3640-camera-module.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="233" src="http://1.bp.blogspot.com/-af92_nBJ4eQ/T52g0Et_U0I/AAAAAAAAA0U/AS2jsQN_j2U/s400/ov3640-camera-module.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;h2 style="font-family: Verdana,sans-serif; text-align: center;"&gt;











TASK : Write a device-driver for Omnivision ov3640 camera&lt;/h2&gt;
&lt;h2 style="font-family: Verdana,sans-serif; text-align: center;"&gt;











Timeline : A.S.A.P (is there any other way? :P)&lt;/h2&gt;
For the aptitude champs out there, here is a quick one:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;blockquote class="tr_bq"&gt;
Q. If you are sitting facing west and running I2C at 0.00000000055kbps and a bear appears in front of you, what color is the bear?&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Not sure? Read on...&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;h2 style="font-weight: normal;"&gt;











&lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;DAY 1 : Initial study&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;b&gt;A bit about ov3640&lt;/b&gt;: The ov3640 (color) image sensor is a 1/4-inch 3.2-megapixel CMOS image sensor that is capable of QXGA(2048x1536)@15FPS using OmniPixel3™ technology in a small footprint package. It provides full-frame, sub-sampled, windowed or arbitrarily scaled 8-bit/10-bit images in various formats via the control of the &lt;a href="http://www.google.co.in/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=2&amp;amp;ved=0CDgQFjAB&amp;amp;url=http%3A%2F%2Fwww.ovt.com%2Fdownload_document.php%3Ftype%3Ddocument%26DID%3D63&amp;amp;ei=aZ6dT-KmO83orQfzg5xS&amp;amp;usg=AFQjCNFJ0PH4AGGT5wKG57iybhAq5qRj3w" target="_blank"&gt;Serial Camera Control Bus (SCCB)&lt;/a&gt; interface or MIPI interface. It supports both a digital video parallel port and a serial MIPI port.&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Searching the "&lt;a href="http://en.wikipedia.org/wiki/Internets" target="_blank"&gt;internets&lt;/a&gt;", an old "v4l2-int" styled driver for ov3640 is available for the linux-kernel. This will have to do for now. Can scavenge the camera configuration register-settings from it.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
The &lt;a href="http://www.ovt.com/download_document.php?type=sensor&amp;amp;sensorid=7" target="_blank"&gt;Omnivision ov3640 product-brief&lt;/a&gt; contains the following functional block-diagram of ov3640:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-QfW7HFW-ly0/T52N7DSnsTI/AAAAAAAAAzc/ZFAPzPvqddk/s1600/ov3640-functional-block-diagram.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="386" src="http://1.bp.blogspot.com/-QfW7HFW-ly0/T52N7DSnsTI/AAAAAAAAAzc/ZFAPzPvqddk/s540/ov3640-functional-block-diagram.jpg" width="540" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
The camera is controlled using the &lt;a href="http://www.google.co.in/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=2&amp;amp;ved=0CDgQFjAB&amp;amp;url=http%3A%2F%2Fwww.ovt.com%2Fdownload_document.php%3Ftype%3Ddocument%26DID%3D63&amp;amp;ei=aZ6dT-KmO83orQfzg5xS&amp;amp;usg=AFQjCNFJ0PH4AGGT5wKG57iybhAq5qRj3w" target="_blank"&gt;SCCB&lt;/a&gt; bus. Again back to the "&lt;a href="http://en.wikipedia.org/wiki/Internets" target="_blank"&gt;internets&lt;/a&gt;". SCCB is an i2c-clone i.e a two-wire serial protocol that has significant differences from I2C to merits its own specification.&lt;/div&gt;
&lt;ol style="text-align: left;"&gt;
&lt;li&gt;According to spec, SCCB supports only upto 100Khz (not more).&lt;/li&gt;
&lt;li&gt;I2C spec requires pullups with open-collector(drain) drivers everywhere. SCCB requires CMOS-like drivers which are always either +VDD or GND i.e no pullups.&lt;/li&gt;
&lt;li&gt;In I2C, after every 8bits transferred, the 9th bit is designated ACK. The slave pulls SDA low to ack. SCCB designates the 9th bit "dont-care". SCCB spec states that the master continues regardless of ACK/NACK in the 9th bit.&lt;/li&gt;
&lt;/ol&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; text-align: left;"&gt;
&lt;h2&gt;











DAY 2 : First attempt&lt;/h2&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Following the omnivision product-brief and the datasheet, the ov3640 camera-module is connected with the CPU as follows:&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-7m3VxzTcdTA/T52Otr2wA5I/AAAAAAAAAzk/YPHry-jIxHg/s1600/ov3640-omap-interface-not-working.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-7m3VxzTcdTA/T52Otr2wA5I/AAAAAAAAAzk/YPHry-jIxHg/s1600/ov3640-omap-interface-not-working.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
So far SCCB looked to be a simpler less restrictive version of I2C. Having worked extensively on I2C previously, was under the impression that setting up the basic comunication between the CPU and ov3640 would be a walk in the park. Wrote a simple skeleton i2c-driver and registered it with the kernel. Scavenged the I2C read/write routines from the old ov3640 driver and booted-up the device...&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
...and the driver failed to load as I2C-read failed. The ID register of ov3640 did NOT match the expected ID. Inserting logs in the code showed that the I2C-read routine was failing. The CPU was NOT getting an ACK from the ov3640 sensor. A true WTF moment as the I2C routines in the driver were tested to be working properly in earlier devices.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Oh well, maybe should really not expect an ACK i suppose. What with ov3640 being an SCCB device and not I2C. Started digging into the I2C core driver. found a provision to ignore this NACK(absense of ACK from slave). Updated the ov3640 driver to set the IGNORE_NACK flag and tried again. Now the I2C-read routine completed successfully despite there being no ACK from the slave. But still the driver failed to load. Turns out the contents of the ID register, read over I2C, did NOT match the expected value. The I2C-read routine was returning the contents of the ID register as "0". Further debugging showed that attempting to read any register of ov3640 over I2C gave the same result- a nice big ZERO. It was evident now that something was terribly wrong.&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; text-align: justify;"&gt;
&lt;h2&gt;











DAY 3 : Challenge Accepted&lt;/h2&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Time to bring out the big guns. Switched to multimeter and oscilloscope. Tested the lines from CPU to the ov3640 connecters for proper continuity. Booted-up the device and probed the I2C lines. The master was sending in the right values alright. But ov3640 was simply not responding. Suspect no.1 ? the I2C slave-id.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Ov3640 spec mentions that it responds to 2 I2C slave-IDs. 0x78 &amp;amp; 0x79. Had tried 0x78 so far. 0x79 also makes no difference - still no data from ov3640. Further digging through the docs i find one interesting line which mentions that the addresses are special in the sense that 0x78 is used to write and 0x79 to read the device. Hmmm... interesting. Lokks like these are 8bit addresses including the read/write bit of I2C. Which means the actual device slave-id is just the 7MSBs (common to 0x78 &amp;amp; 0x79) i.e. 0x3C. Face-palm!&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-i4Od6f4D5Yw/T52UHOIZftI/AAAAAAAAA0I/w_vOptBot-w/s1600/i2c-address.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="91" src="http://2.bp.blogspot.com/-i4Od6f4D5Yw/T52UHOIZftI/AAAAAAAAA0I/w_vOptBot-w/s400/i2c-address.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Changed the slave-id of the ov3640-driver and booted-up the device, but still no dice. It would be easier to light a fire with 2 stones and twig.&lt;/div&gt;
&lt;div style="font-family: Georgia,&amp;quot;Times New Roman&amp;quot;,serif; text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; text-align: justify;"&gt;
&lt;h2&gt;











DAY 4 : ...and let there be light&lt;/h2&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Lost all hopes of getting this to work. Swapped other camera modules. Tried a couple of other boards. But the ov3640 just does not seem to respond to anything. It is as if the module is not even powered-on.&lt;br /&gt;
&lt;br /&gt;
Maybe, mayyyybe thats wat it IS!&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Back to the schematics.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
I2C-CLK? check.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
I2C-DATA? check.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
CAM_XCLK? check.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
CAM-IO? check.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
CAM-digital? check.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
CAM-Analog? Do we really need to power the sensor array at this stage?&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Well what the heck nothing else seems to work anyway. Might as well try this. So quickly pulled down a line from an existing 3.3V power-rail on the board. Placed a diode along it to drop it down a bit and powered-on the board.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-eEs5Mqg08ds/T52PFXzfefI/AAAAAAAAAzs/llLqkY4QCoA/s1600/ov3640-omap-interface-working.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-eEs5Mqg08ds/T52PFXzfefI/AAAAAAAAAzs/llLqkY4QCoA/s1600/ov3640-omap-interface-working.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
And VOILA! It worked. The driver was able to read the ov3640 module properly.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-F81ol3dIT8Q/T52PeTxR6yI/AAAAAAAAAz0/auAohJ_P9DI/s600/ov3640-I2C-working-with-ACK.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="284" src="http://3.bp.blogspot.com/-F81ol3dIT8Q/T52PeTxR6yI/AAAAAAAAAz0/auAohJ_P9DI/s540/ov3640-I2C-working-with-ACK.png" width="540" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
The ov3640 even responded to the default settings (QXGA@15FPS). Pretty neat eh?&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Oh well... sure makes me look foolish, now that it works. :-)&lt;br /&gt;
Ah well there's always the first time for everything. ;-) ;-)&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
And now that it works, was able to summarise the following&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;h3&gt;











Hardware connections:&lt;/h3&gt;
&lt;/div&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;&lt;b&gt;CAM-Analog&lt;/b&gt; (2.8V for powering-on the module)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;CAM-IO 1.8V&lt;/b&gt; (1.8V for i2c-communication)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;CAM-Digital&lt;/b&gt; (1.5V generated by module)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;I2C_CLK&lt;/b&gt; (1.8V 400Khz-MAX for i2c-communication)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;I2C_DATA&lt;/b&gt; (1.8V bi-directional)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;CAM_XCLK&lt;/b&gt; (24Mhz reqd. for internal PLL)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;CAM_PCLK&lt;/b&gt; (generated by module)&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="text-align: justify;"&gt;
&lt;h3&gt;











Software configurations:&lt;/h3&gt;
&lt;/div&gt;
&lt;ul style="text-align: justify;"&gt;
&lt;li&gt;&lt;b&gt;I2C slave-id&lt;/b&gt; 0x3c&lt;/li&gt;
&lt;li&gt;ov3640 DOES provide an &lt;b&gt;ACK&lt;/b&gt; (its I2C, NOT sccb)&lt;/li&gt;
&lt;li&gt;Works on &lt;b&gt;I2C@400KHz&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
With the above specs, surely this begs the question that why does someone go all the way to define their own bus-specs when the hardware obviously works on I2C!!!! WHY Omnivision? WHY????&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;blockquote class="tr_bq"&gt;
Designing you own serial-bus? == $1,000,000&lt;br /&gt;
&lt;br /&gt;
Not using it in your own products? == $0&lt;br /&gt;
&lt;br /&gt;
The smile on my face when i finally figure it out? PRICELESS&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Somethings, money can't buy. For everything else , there is... Ah wait, i'm forgetting something now, right? Well here goes...&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;div style="text-align: justify;"&gt;
Q. If you are sitting facing west and running I2C at 0.00000000055kbps and a bear appears in front of you, what color is the bear?&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Ans. If it takes 4 days to transfer a byte, do you REALLY think i care!!&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
NOTE:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
[i]. No bears were harmed in the development of this camera-module.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
[ii]. The image captured above did NOT appear out of the blue with only the driver in place. Several days of tweaking the exposure/white-balance settings and an earthquake later, managed to get the Kernel-driver, Android camera-HAL and app to work together.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=9iDWaa4s9do:SScu61dFsgo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=9iDWaa4s9do:SScu61dFsgo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=9iDWaa4s9do:SScu61dFsgo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=9iDWaa4s9do:SScu61dFsgo:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/9iDWaa4s9do" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2012-09-12T01:37:15.805+05:30</app:edited><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-af92_nBJ4eQ/T52g0Et_U0I/AAAAAAAAA0U/AS2jsQN_j2U/s72-c/ov3640-camera-module.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">27</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2012/04/omnivison-ov3640-i2c-sccb.html</feedburner:origLink></item><item><title>Android Double-buffering, Page-Flip and HDMI</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/oasaTQMhXBE/android-double-buffering-page-flip-and.html</link><category>Double-buffering</category><category>Programming</category><category>SurfaceFlinger</category><category>CodeProject</category><category>Framebuffer</category><category>Android</category><category>Display</category><category>Page-Flipping</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Sun, 16 Sep 2012 00:35:36 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-7311487499378615192</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: center;"&gt;
&lt;span style="font-size: small;"&gt;(a.k.a The case of the disappearing charging-icon)&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;The following is an account of the final development stages of an android phone, which for obvious reasons will not be named. The bug in itself was a very simple matter and the consequent fix too. But the entire process of discovering what exactly was happening was quite fun. (Ya right! tell that to my manager :P)&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;a href="http://3.bp.blogspot.com/-Nn_od7TN5rI/TuYFLX9CoqI/AAAAAAAAAv4/pvpGEWsXzaU/s1600/sample-lockscreen.jpg" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-Nn_od7TN5rI/TuYFLX9CoqI/AAAAAAAAAv4/pvpGEWsXzaU/s1600/sample-lockscreen.jpg" /&gt;&lt;/a&gt;&lt;span style="font-size: small;"&gt;The android phone, i was working on, supported connecting an external-display/TV via MHL(&lt;a href="http://en.wikipedia.org/wiki/Mobile_High-definition_Link" target="_blank"&gt;Mobile-HD link&lt;/a&gt; i.e. HDMI-over-USB). Once connected, the entire UI would be displayed on the TV. The phone battery would also charge while connected.&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;The issue in question was initially raised as an application issue. It so happened that the &lt;u&gt;charging status was not being displayed properly on the lockscreen&lt;/u&gt;.&lt;/span&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;h2&gt;







&lt;span style="font-size: small;"&gt;I. The issue...&lt;/span&gt;&lt;/h2&gt;
&lt;span style="font-size: small;"&gt;With the device locked, when a external MHL-cable was connected to the android phone, it used to update the charging-icon. But if removed immediately, the charging-icon would continue to be displayed. This would not happen always. But sometimes even upto a minute after the cable was removed, the status would continue to be displayed as "charging".&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;The application developers banged their heads over the weekend and finally pushed the issue onto the underlying kernel drivers, stating that they were updating the charging-status as-&amp;amp;-when they get an update from the framework, which in turn depends on the fuelguage/battery-driver to obtain the battery-status.&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;a href="http://2.bp.blogspot.com/-tAyvuujwPVQ/TuYFVoDEw9I/AAAAAAAAAwA/IweIuJ__mDo/s1600/bang+head+here.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-tAyvuujwPVQ/TuYFVoDEw9I/AAAAAAAAAwA/IweIuJ__mDo/s320/bang+head+here.jpg" width="264" /&gt;&lt;/a&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;It was now the kernel developers turn to use the "stress-reduction kit". After hours of logging almost every single instruction in every single interrupt routine, it was quite evident that the battery driver was not at fault. It was promptly reporting the connect/disconnect events when(and only when) an MHL cable was inserted/removed. The android framework was getting the events and eventually the lockscreen application too.&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;So now the question was that if EVERYTHING was working as it was supposed to, why the charging-status was not being displayed correctly?&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;br /&gt;
&lt;h2&gt;







&lt;span style="font-size: small;"&gt;II. The peculiar observation...&lt;/span&gt;&lt;/h2&gt;
&lt;span style="font-size: small;"&gt;The peculiar thing about the disappearing charging-icon was that it was almost never for the same amount of time. Every time we tested it by plugging-in the cable, if it would disappear, it would do so for varying periods of time and then appear again onscreen.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;







&lt;span style="font-size: small;"&gt;III. What it meant...&lt;/span&gt;&lt;/h2&gt;
&lt;span style="font-size: small;"&gt;We finally got onto the right track after we saw that the icon ALWAYS re-appeared onscreen just as the clock on the lock-screen updated itself. As it turned out the culprit was the display driver. When plugging in the MHL cable, there was some amount of tinkering going on in the background to handle the multiple displays and/or switch to the secondary(external HDTV over MHL)&amp;nbsp; from the primary(mobile-LCD). As is the norm, the display was double-buffered to improve performance and prevent onscreen flickering and tearing. Plugging-in the MHL-cable just as the display driver was initiating a &lt;i&gt;swapbuffer()&lt;/i&gt; (i.e. a &lt;a href="http://en.wikipedia.org/wiki/Multiple_buffering#Page_flipping" target="_blank"&gt;page-flip operation&lt;/a&gt; to pick the back-buffer to display onscreen) the device would then initiate another &lt;i&gt;swapbuffer()&lt;/i&gt; which meant the stale buffer was displayed onscreen. to add to the misery the &lt;/span&gt;&lt;span style="font-size: small;"&gt;"smart" &lt;/span&gt;&lt;span style="font-size: small;"&gt;display driver was programmed to skip redundant &lt;i&gt;swapbuffer()&lt;/i&gt; calls. i.e. unless the display contents had changed from the time the previous call to &lt;i&gt;swapbuffer()&lt;/i&gt; it would not refresh the display unnecessarily. This meant that after plugging-in the MHL-cable, once the wrong screen (one without the chargin-icon) was displayed, it would not be refreshed unless something else changed onscreen.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: small;"&gt;Usually the onscreen clock forced a refresh of the buffers when the time was updated. As it showed time only down to the minute, it would mean that sometimes the display could be "stale" for as long as (but no longer than) a minute. An&lt;/span&gt; additional forced-refresh in the MHL-cable detection routine fixed the issue properly.&lt;br /&gt;
&lt;br /&gt;
A simple example of double-buffering is shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-B4Tc-NMCbJg/TvWchYEOO2I/AAAAAAAAAwU/FosNLhgqnBw/s450/double-buffering.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-B4Tc-NMCbJg/TvWchYEOO2I/AAAAAAAAAwU/FosNLhgqnBw/s520/double-buffering.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style="font-size: small;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;







&lt;span style="font-size: small;"&gt;IV. Could Triple-buffering have prevented this issue?&lt;/span&gt;&lt;/h2&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span style="font-size: small; font-weight: normal;"&gt;Triple-buffering involves 2 back-buffers. at any given moment, the display-driver can immediately pick one&lt;/span&gt;&lt;span style="font-size: small; font-weight: normal;"&gt; that is not being updated by the graphics h/w&lt;/span&gt;&lt;span style="font-size: small; font-weight: normal;"&gt; to display into the front-buffer.&lt;/span&gt;&lt;/blockquote&gt;
Triple buffering itself has 2 variants:&lt;br /&gt;
&lt;b&gt;(A)&lt;/b&gt; &lt;b&gt;Triple-buffering with no-sync.&lt;/b&gt; In this method the back-buffers are alternately updated by the graphics-h/w as fast as it can. At each Vsync, the display driver picks one of the buffers which is currently not being written to and swaps it with the front-buffer.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;(B)&lt;/b&gt; &lt;b&gt;Triple-buffering with Vsync.&lt;/b&gt; In this method, the back-buffers are updated by the graphics h/w as fast as it can. But the update stops if both the back-buffers are updated but have not been displayed in the front-buffer yet. The display-driver as usual swaps one of the back-buffers witht he fornt-buffer at each Vsync. at this point the previous front-buffer which is now a back buffer is considered "stale" and the graphics h/w fills it up with the updated frame.&lt;br /&gt;
&lt;br /&gt;
Triple-bufffering used could potentially correct the issue as one of the back-buffers would hold the properly updated screen data and it even if it was not picked-up right away, it would be picked immediately in the following next &lt;span style="font-size: small;"&gt;&lt;i&gt;swapbuffer()&lt;/i&gt; call. Also in double-buffering, the graphics h/w doesn't have to wait for access to the backbuffer till the &lt;i&gt;swapbuffer()&lt;/i&gt; completes the flip operation between the front and back buffers. This is not the case in triple-buffering, thus allowing the graphics h/w to run at full throttle thereby reducing the time that either of the backbuffers contains stale display data.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;Further reading: &lt;a href="http://en.wikipedia.org/wiki/Multiple_buffering" target="_blank"&gt;A detailed description of double/triple buffering&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=oasaTQMhXBE:QCLMoTnSPaY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=oasaTQMhXBE:QCLMoTnSPaY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=oasaTQMhXBE:QCLMoTnSPaY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=oasaTQMhXBE:QCLMoTnSPaY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/oasaTQMhXBE" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2012-09-16T13:05:36.036+05:30</app:edited><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-Nn_od7TN5rI/TuYFLX9CoqI/AAAAAAAAAv4/pvpGEWsXzaU/s72-c/sample-lockscreen.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2011/12/android-double-buffering-page-flip-and.html</feedburner:origLink></item><item><title>[patch] [resend] Preparing a modified patch</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/QFPUs545BLE/patch-resend-preparing-modified-patch.html</link><category>Programming</category><category>patch resend</category><category>git</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Sat, 11 Feb 2012 03:49:36 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-4774407325399048891</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;In case of any collaborated project (eg. linux-kernel), often after submitting a patch for review,&amp;nbsp; we often receive several comments and need to make appropriate changes and generate a new "version2" of the patch containing the changes. If we are using &lt;a href="http://en.wikipedia.org/wiki/Git_%28software%29" target="_blank"&gt;Git&lt;/a&gt; for revision control, then the entire process becomes a snap.&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h2&gt;






How to prepare a modified patch for resend in &lt;u&gt;5 easy steps&lt;/u&gt;:&lt;/h2&gt;
&lt;br /&gt;
STEP1.&lt;br /&gt;
&lt;code class="tr_bq"&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;git rebase -i &amp;lt;commit-id-just-before-our-changes&amp;gt;&lt;/span&gt;&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;
STEP2.&lt;br /&gt;
As discussed in the review, make the new changes to the source-files.&lt;br /&gt;
&lt;br /&gt;
STEP3.&lt;br /&gt;
&lt;code class="tr_bq"&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;git add &amp;lt;modified-filenames&amp;gt;&lt;/span&gt;&lt;/code&gt;
&lt;br /&gt;
&lt;br /&gt;
STEP4.&lt;br /&gt;
&lt;code class="tr_bq"&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;git commit --amend&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;
(shows editor with original commit-msg)&lt;br /&gt;
Edit the commit-msg (or leave as-is) and quit.&lt;br /&gt;
New commit is generated in the place of old commit.&lt;br /&gt;
&lt;br /&gt;
STEP5.&lt;br /&gt;
&lt;code class="tr_bq"&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;git format-patch HEAD~1&lt;/span&gt;&lt;/code&gt;
&lt;br /&gt;
DONE!! New patch version2 is ready for review now. :-)&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
If we do a diff between the PREV and NEW patch, we can see :&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
+ Changes made after review.&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
+ Time-Stamp change.&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
+ Hash change.&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=QFPUs545BLE:UDvvWVC66a4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=QFPUs545BLE:UDvvWVC66a4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=QFPUs545BLE:UDvvWVC66a4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=QFPUs545BLE:UDvvWVC66a4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/QFPUs545BLE" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-11T17:19:36.662+05:30</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2012/02/patch-resend-preparing-modified-patch.html</feedburner:origLink></item><item><title>Android Sensors and Location based services</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/wEWx_pU2oYA/android-sensors-and-location-based.html</link><category>Magnetic-Field sensor</category><category>Invensense</category><category>Proximity-sensor</category><category>nGPS</category><category>Accelerometer Sensor</category><category>Light Sensor</category><category>Android</category><category>Sensors</category><category>Orientation Sensor</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Sat, 14 Jan 2012 08:24:59 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-6179143951810232618</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Here is the talk i presented about &lt;u&gt;Sensors and location based services on Android&lt;/u&gt; at &lt;a href="http://blog.blrdroid.org/" target="_blank"&gt;B.A.(U).G / BLR-DROID.&lt;/a&gt; Felt awesome talking to people, answering Qs about &lt;a href="http://thecodeartist.blogspot.com/2011/11/ngps-location-fix-without-gps.html" target="_blank"&gt;nGPS.&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;iframe frameborder="0" height="413" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/11039276" width="500"&gt;&lt;/iframe&gt; &lt;/div&gt;
&lt;br /&gt;
Download &lt;b&gt;&lt;a href="http://www.slideshare.net/cvs26/sensors-and-location-based-services/download" target="_blank"&gt;Sensors and location based services on Android&lt;/a&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=wEWx_pU2oYA:quunXEsYm8Q:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=wEWx_pU2oYA:quunXEsYm8Q:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=wEWx_pU2oYA:quunXEsYm8Q:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=wEWx_pU2oYA:quunXEsYm8Q:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/wEWx_pU2oYA" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-14T21:54:59.836+05:30</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2012/01/android-sensors-and-location-based.html</feedburner:origLink></item><item><title>Booting Android completely over ethernet</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/sfZzLerxzqI/booting-android-completely-over.html</link><category>Programming</category><category>linux-kernel</category><category>NFS</category><category>u-boot</category><category>tftp</category><category>CodeProject</category><category>Android</category><category>Test-Driven-Development</category><category>boot</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Sun, 16 Sep 2012 00:35:36 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-4333206887207912301</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div style="font-family: inherit; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;When developing embedded-systems, initial development stages often involve huge number of "&lt;b&gt;Modify-Build-Flash-Test&lt;/b&gt;" cycles. &lt;/span&gt;&lt;span style="font-size: small;"&gt;Test-Driven-Development methodology further promotes this style of development. &lt;/span&gt;&lt;span style="font-size: small;"&gt;This leads to a break in the "flow" at the &lt;b&gt;Flash&lt;/b&gt; stage. Flashing the device with a newly built set of binaries interrupts the otherwise smooth "&lt;b&gt;Modify-Build-Test&lt;/b&gt;" flow. Also errors tend to creep-in in the form of an older binary being copied/flashed, often causing confusion during debugging and&amp;nbsp; endless grief to the developer.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: inherit; text-align: justify;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="font-family: inherit; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;A simple way to avoid this is to have the binaries on the host-machine (a PC) and boot the embedded device directly using those binaries. In case of Android embedded system development, these binaries are the Linux-Kernel and the Android filesystem image.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: inherit; text-align: justify;"&gt;&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;&lt;u&gt;&lt;span style="font-size: small;"&gt;Pre-requisites:&lt;/span&gt;&lt;/u&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;The embedded device&lt;/li&gt;
&lt;li&gt;A linux PC &lt;/li&gt;
&lt;li&gt;Ethernet connectivity between the two&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;b&gt;NOTE&lt;/b&gt;&lt;/span&gt;: Below listed parts 1, 2 &amp;amp; 3 involve setting-up the "host" Linux PC. Part 4 describes configuring the device to boot directly using the binaries present on the "host". It is assumed that a functional bootloader (u-boot) is present on the device (internal-flash/mmc-card) and that ethernet-support(either direct or over usb) is enabled.&lt;/div&gt;&lt;div style="font-family: inherit; text-align: justify;"&gt;&lt;span style="font-size: small;"&gt;   &lt;/span&gt;&lt;/div&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;h1&gt;&lt;br /&gt;
&lt;span class="mw-headline" id="Part1: Linux kernel over tftp"&gt;Part1: Linux kernel over tftp&lt;/span&gt;&lt;/h1&gt;&lt;h2&gt;&lt;span class="mw-headline" id="Install_tftpd_and_related_packages"&gt;1. Install tftpd and related packages&lt;/span&gt;&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;&lt;b&gt;host-PC$ &lt;/b&gt;sudo apt-get install xinetd tftpd tftp
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h2&gt;&lt;span class="mw-headline" id="Create_.2Fetc.2Fxinetd.d.2Ftftp"&gt;2. Create /etc/xinetd.d/tftp &lt;/span&gt;&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;&lt;b&gt;host-PC$ &lt;/b&gt;cat &amp;lt;&amp;lt;EOF | sudo tee /etc/xinetd.d/tftp
service tftp
{
    protocol        = udp
    port            = 69
    socket_type     = dgram
    wait            = yes
    user            = nobody
    server          = /usr/sbin/in.tftpd
    server_args     = /srv/tftp
    disable         = no
}
EOF
&lt;/code&gt;
&lt;/pre&gt;&lt;h2&gt;&lt;span class="mw-headline" id="Make tftp-server directory"&gt;3. Make tftp-server directory&lt;/span&gt;&lt;/h2&gt;&lt;code&gt;&lt;b&gt;host-PC$ &lt;/b&gt;mkdir &amp;lt;tftp-server-path&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;host-PC$ &lt;/b&gt;chmod -R 777 &amp;lt;tftp-server-path&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;host-PC$ &lt;/b&gt;chown -R nobody &amp;lt;tftp-server-path&amp;gt; &lt;/code&gt; &lt;br /&gt;
&lt;h2&gt;&lt;span class="mw-headline" id="Start_tftpd_through_xinetd"&gt;4. Start tftpd through xinetd&lt;/span&gt;&lt;/h2&gt;&lt;code&gt;&lt;b&gt;host-PC$ &lt;/b&gt; sudo /etc/init.d/xinetd restart&amp;nbsp;&lt;/code&gt; &lt;br /&gt;
This concludes the tftp part of the setup process on the host.&lt;br /&gt;
&lt;h1&gt;&lt;br /&gt;
&lt;span class="mw-headline" id="Android fs over NFS"&gt;Part2: Android fs over NFS&lt;/span&gt;&lt;/h1&gt;&lt;h2&gt;&lt;span class="mw-headline" id="Install nfs packages"&gt;1. Install nfs packages &lt;/span&gt;&lt;/h2&gt;&lt;code&gt;&lt;b&gt;host-PC$ &lt;/b&gt;sudo apt-get install nfs-kernel-server nfs-common&amp;nbsp;&lt;/code&gt; &lt;/div&gt;&lt;br /&gt;
&lt;h2&gt;&lt;span class="mw-headline" id="Modify /etc/exports"&gt;2. Add this line to /etc/exports&lt;/span&gt; &lt;/h2&gt;&lt;code&gt;&amp;lt;rootfs-path&amp;gt;   *(rw,sync,no_subtree_check,no_root_squash)  &lt;/code&gt; &lt;/div&gt;&lt;br /&gt;
&lt;h2&gt;&lt;span class="mw-headline" id="Restart service"&gt;3. Restart service&lt;/span&gt; &lt;/h2&gt;&lt;code&gt;&lt;b&gt;host-PC$ &lt;/b&gt;sudo service nfs-kernel-server restart &lt;/code&gt; &lt;br /&gt;
&lt;h2&gt;&lt;span class="mw-headline" id="Update exports for the NFS server"&gt;4. Update exports for the NFS server&lt;/span&gt; &lt;/h2&gt;&lt;code&gt;&lt;b&gt;host-PC$ &lt;/b&gt;exportfs -a &lt;/code&gt; &lt;br /&gt;
&lt;h2&gt;&lt;span class="mw-headline" id="Check NFS server"&gt;5. Check NFS server&lt;/span&gt;  &lt;/h2&gt;&lt;code&gt;&lt;b&gt;host-PC$ &lt;/b&gt;showmount -e &lt;/code&gt; &lt;/div&gt;&lt;br /&gt;
If everything went right, the &amp;lt;rootfs-path&amp;gt; will be listed in the output of showmount. &lt;br /&gt;
&lt;h1&gt;&lt;br /&gt;
&lt;span class="mw-headline" id="Where to put the files"&gt;Part3: Where to put the files&lt;/span&gt;&lt;/h1&gt;&lt;h2&gt;&lt;span class="mw-headline" id="Linux Kernel uImage"&gt;1. Linux Kernel uImage&lt;/span&gt;&lt;/h2&gt;On the "host" PC,&lt;br /&gt;
Copy the Linux-Kernel &lt;b&gt;uImage&lt;/b&gt; into &amp;lt;tftp-server-path&amp;gt;&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;&lt;/ul&gt;&lt;h2&gt;&lt;span class="mw-headline" id="Android rootfs"&gt;2. Android rootfs&lt;/span&gt;&lt;/h2&gt;On the "host" PC,&lt;br /&gt;
Copy the contents of the Android rootfs into &amp;lt;rootfs-path&amp;gt;&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;&lt;/ul&gt;&lt;h1&gt;&lt;br /&gt;
&lt;span class="mw-headline" id="Configuring the bootloader"&gt;Part4: Configuring the bootloader&lt;/span&gt;&lt;/h1&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2&gt;&lt;span class="mw-headline" id="Update bootargs"&gt;1. Update bootargs&lt;/span&gt;&lt;/h2&gt;Connect the embedded device to the host-PC over ethernet (either directly or via a switch/router) and power it on. As shown below, configure the bootloader to pick-up the kernel from the host-PC over tftp and to mount the filesystem from the host-PC over NFS. As both support configuring a static-ip for the embedded-device or obtaining one dynamically using dhcp, 4 combinations are possible (2 shown below). &lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;nfs(static-ip)&lt;/u&gt;&lt;u&gt; and &lt;/u&gt;&lt;u&gt;tftp(dhcp)&lt;/u&gt;&lt;br /&gt;
&lt;code&gt;&lt;b&gt;U-Boot# &lt;/b&gt;setenv bootargs 'console=ttyO0,115200n8 androidboot.console=ttyO0 mem=256M root=/dev/nfs ip=&amp;lt;client-device-ip&amp;gt; nfsroot=&amp;lt;nfs-server-ip&amp;gt;:&amp;lt;rootfs-path&amp;gt; rootdelay=2' &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;U-Boot# &lt;/b&gt;setenv serverip 'host-pc-ip'&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt; U-Boot# &lt;/b&gt;bootm &amp;lt;Load address&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;nfs(dhcp)&lt;/u&gt;&lt;u&gt; and&lt;/u&gt;&lt;u&gt; tftp(static-ip)&lt;/u&gt;&lt;br /&gt;
&lt;code&gt;&lt;b&gt;U-Boot# &lt;/b&gt;setenv bootargs 'console=ttyO0,115200n8 androidboot.console=ttyO0 mem=256M root=/dev/nfs ip=dhcp nfsroot=&amp;lt;nfs-server-ip&amp;gt;:&amp;lt;rootfs-path&amp;gt; rootdelay=2'&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;U-Boot# &lt;/b&gt;setenv serverip 'host-pc-ip'&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;U-Boot# &lt;/b&gt;setenv ipaddr 'client-device-ip'&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;U-Boot# &lt;/b&gt;tftp &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;U-Boot# &lt;/b&gt;bootm &amp;lt;Load address&amp;gt; &lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;&lt;span class="mw-headline" id="Boot"&gt;2. Boot ;-)&lt;/span&gt;&lt;/h2&gt;&lt;/div&gt;&lt;b&gt; &lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-family: inherit; font-size: small;"&gt;&lt;b&gt;Linux-Kernel loaded over tftp&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-LUeMVw97tMQ/Tvx735Nf2cI/AAAAAAAAAwk/xmA5fnfGeyA/s500/dhcp-boot.jpg" /&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;span style="font-family: inherit; font-size: small;"&gt;&lt;b&gt;Filesystem mounted over NFS&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.blogger.com/blogger.g?blogID=5879050571098780501" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-9nT6viM535U/TvyIDfw0axI/AAAAAAAAAxA/ksZrs0fL6qM/s500/nfs-mount.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=sfZzLerxzqI:szgTtfNJKLc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=sfZzLerxzqI:szgTtfNJKLc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=sfZzLerxzqI:szgTtfNJKLc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=sfZzLerxzqI:szgTtfNJKLc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/sfZzLerxzqI" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2012-09-16T13:05:36.019+05:30</app:edited><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-LUeMVw97tMQ/Tvx735Nf2cI/AAAAAAAAAwk/xmA5fnfGeyA/s72-c/dhcp-boot.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><georss:featurename xmlns:georss="http://www.georss.org/georss">HAL 3rd Stage, New Thipasandra, Bengaluru, Karnataka, India</georss:featurename><georss:point xmlns:georss="http://www.georss.org/georss">12.971062185172919 77.65342674902342</georss:point><georss:box xmlns:georss="http://www.georss.org/georss">12.967906685172919 77.64610574902342 12.974217685172919 77.66074774902343</georss:box><feedburner:origLink>http://thecodeartist.blogspot.com/2011/12/booting-android-completely-over.html</feedburner:origLink></item><item><title>Why __read_mostly does NOT work as it should</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/JsyNMiwMtz4/why-readmostly-does-not-work-as-it.html</link><category>ARM</category><category>Programming</category><category>linux-kernel</category><category>x86</category><category>CodeProject</category><category>cache</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Thu, 16 May 2013 03:16:43 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-4808524863142163783</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;/div&gt;
&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div class="separator" style="clear: both; text-align: justify;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
In modern SMP(multicore) systems, any processor can write to a memory location. The other
processors have to update their caches immediately.  For that reason, SMP systems implement the concept of "cacheline bouncing" to move "ownership" of cached-data between cores.  This is effective but expensive.&lt;br /&gt;
&lt;br /&gt;
Individual cores have private L1 caches which are extremely faster than the L2 and L3 caches which are shared between multiple cores. Typically, when a memory location is going to be ONLY read repeatedly, but never written to (for example a variable tagged with the &lt;i&gt;const&lt;/i&gt; modifier), each core on the SMP system can safely store its own copy of that variable in its private(non-shared) cache. As the variable is NEVER written, the cache-entry never gets invalidated or "dirty". Hence the cores never need to get into "cache line bouncing" for that variable.&lt;br /&gt;
&lt;br /&gt;
Take the case of the x86 architecture,&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;img border="0" height="320" src="https://lh6.googleusercontent.com/-PIETb3X6Qjk/Tt_Vdd4tfuI/AAAAAAAAAvI/3hf9nfocZuU/s480/intel-die-caches.jpg" style="margin-left: auto; margin-right: auto;" width="520" /&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;An Intel core i5 die showing the various caches present&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="font-size: x-small;"&gt;[NON-SMP]&lt;/span&gt; Intel Pentium 4 processor  has to communicate between threads over 
the front-side bus, thus requiring at least a 400-500 cycle delay.&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: x-small;"&gt;[SMP]&lt;/span&gt; Intel Core processor family allowed for communication over a shared
 L2 cache with a delay of only 20 cycles between pairs of cores and the 
front-side bus between multiple pairs on a quad-core design.&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: x-small;"&gt; [SMP]&lt;/span&gt; The use of a
 shared L3 cache in the Intel Core i7 processor means that going across a
 bus to synchronize with another core is NEVER required unless a 
multiple-socket system is being used.&lt;/li&gt;
&lt;/ul&gt;
The copies of "read-only" locations usually end-up being cached in the private caches of the individual cores, which are several orders of magnitude faster than the shared L3 cache.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: large;"&gt;How &lt;i&gt;__read_mostly&lt;/i&gt; is &lt;b&gt;supposed&lt;/b&gt; to work:&lt;/span&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
When a variable is tagged with the&lt;i&gt; __read_mostly&lt;/i&gt; annotation, it is a signal to the compiler that accesses to the variable will be mostly reads and rarely(but NOT never) a write.&lt;br /&gt;
&lt;br /&gt;
All variables tagged &lt;i&gt;__read_mostly&lt;/i&gt; are grouped together into a single section in the final executable.
 This is to improve performance by allowing the system to optimise access time 
to those variables in SMP systems by allowing each core to maintain its own copy of them variable in it local cache. Once in a while when the variable does get written to, "cacheline bouncing" takes place. But this is&amp;nbsp; acceptable as the the time spent by the cores constantly synchronising using locks and using the slower shared-cache would be far more than the time it takes for the multiple cores to operate on own copies in their independent caches.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;What &lt;i&gt;&lt;b&gt;actually&lt;/b&gt;&lt;/i&gt; happens: &lt;/span&gt;&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-size: x-small;"&gt;(&lt;/span&gt;NOTE: I&lt;/span&gt;n the following section, &lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-size: x-small;"&gt;"&lt;span style="font-size: x-small;"&gt;e&lt;/span&gt;lements"&lt;/span&gt; refers to memory&lt;span style="font-size: x-small;"&gt; block&lt;/span&gt;s&lt;span style="font-size: x-small;"&gt;&lt;span style="font-size: x-small;"&gt; &lt;/span&gt;which &lt;span style="font-size: x-small;"&gt;are &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-size: x-small;"&gt;are smaller&lt;span style="font-size: x-small;"&gt; &lt;/span&gt;than &lt;span style="font-size: x-small;"&gt;a&lt;span style="font-size: x-small;"&gt; single&lt;/span&gt;&lt;/span&gt; cache-line and&lt;span style="font-size: x-small;"&gt; &lt;/span&gt;are so sparse &lt;span style="font-size: x-small;"&gt;in main-me&lt;span style="font-size: x-small;"&gt;mo&lt;/span&gt;ry &lt;span style="font-size: x-small;"&gt;that&lt;span style="font-size: x-small;"&gt; &lt;/span&gt;a single&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; cache-line&lt;span style="font-size: x-small;"&gt; &lt;span style="font-size: x-small;"&gt;can&lt;span style="font-size: x-small;"&gt;not&lt;/span&gt;&lt;/span&gt; contain&lt;/span&gt;&lt;/span&gt; them both simultaneously.&lt;span style="font-size: x-small;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
The problem with the above approach is that once all the &lt;i&gt;__read_mostly&lt;/i&gt; variables are grouped into one section, the remaining "non-read-mostly" variables end-up&amp;nbsp; together too. This increases the chances that two frequently used elements (in the "non-read-mostly" region) will end-up competing for the same position (or cache-line, the basic fixed-sized block for memory&amp;lt;--&amp;gt;cache transfers) in the cache. Thus frequent accesses will cause excessive cache thrashing on that particular cache-line thereby degrading the overall system performance.&lt;br /&gt;
&lt;br /&gt;
This situation is slightly alleviated by the fact that modern cpu caches are mostly 8way or 16way set-associative. In a 16way associative cache, each element has a choice of 16 different cache-slots. This means that two very frequently accessed elements, though closely located in memory, can still end-up in 2 different slots in the cache, thereby preventing cache-thrashing (which would have occurred had both continued competing for the same cache-line slot). In other words a minimum of 17 elements frequently accessed and closely located in memory are required for 2 of them to begin competing for a common cache-line slot.&lt;br /&gt;
&lt;br /&gt;
While this is true in the case of INTEL and its x86 architecture, ARM still sticks to 4way &amp;amp; 2way set-associative caches even in its Cortex A8, which means that just 3 or 5 closely located, frequently accessed elements can result in cache-thrashing on an ARM system. (&lt;span style="font-size: x-small;"&gt;&lt;b&gt;Update&lt;/b&gt;&lt;/span&gt;: &lt;a href="http://thecodeartist.blogspot.com/2011/12/why-readmostly-does-not-work-as-it.html?showComment=1368693290291#c5777583867429395138" target="_blank"&gt;"Anonymous" rightly points out in the comments&lt;/a&gt; that 16-way set associative caches have made their way into modern SoCs, ARM Cortex A9 onwards.)&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;b&gt;kernel/arch/x86/include/asm/cache.h&lt;/b&gt; contains&lt;/span&gt;&lt;br /&gt;
&lt;code class="tr_bq"&gt;
&lt;span style="font-size: x-small;"&gt;#define __read_mostly __attribute__((__section__(".data..read_mostly"))) &lt;/span&gt;&lt;/code&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: x-small;"&gt;kernel/arch/arm/include/asm/cache.h:&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: x-small;"&gt; does NOT, thereby defaulting to the empty definition in&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: x-small;"&gt; kernel/include/linux/cache.h&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;code class="tr_bq"&gt;
&lt;span style="font-size: x-small;"&gt;#ifndef __read_mostly&lt;br /&gt;#define __read_mostly&lt;br /&gt;#endif&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt; &lt;/span&gt;&lt;/b&gt;&lt;/code&gt;
&lt;b&gt;&lt;span style="font-size: x-small;"&gt; &lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;u&gt;&lt;b&gt;UPDATE&lt;/b&gt;&lt;/u&gt;: The patch &lt;/span&gt;daf8741675562197d4fb4c4e9d773f53494203a5&lt;span style="font-family: Verdana,sans-serif;"&gt; enables &lt;/span&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;support for &lt;/span&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;__read_mostly&amp;nbsp; in the linux kernel for ARM architecture as well.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The reason for this? It turns out that most modern ARM SoCs have started
 using 8/16-way set associative caches. For example, the &lt;a href="http://infocenter.arm.com/help/topic/com.arm.doc.ddi0246a/DDI0246A_l2cc_pl310_r0p0_trm.pdf" target="_blank"&gt;ARM PL310 cache controller&lt;/a&gt; (as &lt;a href="http://thecodeartist.blogspot.com/2011/12/why-readmostly-does-not-work-as-it.html?showComment=1368693290291#c5777583867429395138" target="_blank"&gt;"Anonymous" rightly points out in the comments&lt;/a&gt;)
 available on the ARM Cortex-A9 supports 16-way set associativity. The 
above patch now makes sense on modern ARM SoCs as the probability of 
cache-thrashing is reduced by the larger "N" in the N-way associative 
caches.&lt;br /&gt;
&lt;br /&gt;
With the number of cores increasing rapidly and the on-die cache size growing slowly, one must always aim to:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Minimise access to
 the last level of shared cache to improve performance on multicore systems.&lt;/li&gt;
&lt;li&gt;Increase associativity of private caches (of individual cores) to eliminate cache-slot contention and reduce cache-thrashing.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=JsyNMiwMtz4:Wed8IDY3z6A:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=JsyNMiwMtz4:Wed8IDY3z6A:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=JsyNMiwMtz4:Wed8IDY3z6A:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=JsyNMiwMtz4:Wed8IDY3z6A:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/JsyNMiwMtz4" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2013-05-16T15:46:43.498+05:30</app:edited><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://lh6.googleusercontent.com/-PIETb3X6Qjk/Tt_Vdd4tfuI/AAAAAAAAAvI/3hf9nfocZuU/s72-c/intel-die-caches.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2011/12/why-readmostly-does-not-work-as-it.html</feedburner:origLink></item><item><title>nGPS : Location fix without GPS</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/Sns1ukGnt2o/ngps-location-fix-without-gps.html</link><category>Magnetic-Field sensor</category><category>Programming</category><category>nGPS</category><category>DroidCon2011</category><category>Android</category><category>GeomagneticField</category><category>Sensors</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Tue, 17 Jan 2012 04:34:21 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-4863516113311330916</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: center;"&gt;
&lt;span style="font-size: x-small;"&gt;&lt;i&gt;NOTE: Skip this post if you do NOT live on planet earth.&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: x-small;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: x-small;"&gt;&lt;i&gt;This is one of the ideas that i hit upon when preparing for a talk &lt;a href="http://thecodeartist.blogspot.com/2011/11/sensors-on-android-droidcon2011.html" target="_blank"&gt;Sensors on Android @DroidCon2011&lt;/a&gt;. It is an unusual application of the on-board sensors present most Android devices. Due to lack of time i was unable to present it in much detail during my talk. So here goes...&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;nGPS&lt;/b&gt;&lt;/span&gt; (NO GPS) is a way of obtaining a location fix without using any &lt;a href="http://en.wikipedia.org/wiki/Global_Positioning_System" target="_blank"&gt;GPS&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Assisted_GPS" target="_blank"&gt;AGPS&lt;/a&gt;, &lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/Wi-Fi_Positioning_System" title="Wi-Fi Positioning System"&gt;Wi-Fi Positioning&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Mobile_phone_tracking" title="Mobile phone tracking"&gt;cell-site triangulation&lt;/a&gt;  technologies.&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;blockquote class="tr_bq" style="font-family: Verdana,sans-serif;"&gt;
&lt;div&gt;
&lt;u&gt;&lt;span style="font-size: small;"&gt;Why would anyone want to use nGPS&lt;/span&gt;&lt;/u&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: small;"&gt;- Pure GPS based systems take upto 10mins for 1st fix.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: small;"&gt;- AGPS, Wi-Fi positioning require an active data-connection.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="font-size: small;"&gt;- Cell-site triangulation requires network coverage.&lt;/span&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;So without any of these technologies at our disposal, how do we obtain a "location-fix" i.e. a latitude-longitude pair representing our current position. The answer lies in the magnetic-field sensor.&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div align="justify" style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;The Earth's magnetic field, as measured by a magnetic sensor on the Earth's surface, is combination of of several 
    magnetic fields generated by various sources. These fields interact with each other and the net resultant what the magnetic sensor measures.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; font-family: Verdana,sans-serif; text-align: center;"&gt;
&lt;span style="font-size: small;"&gt;&lt;a href="http://cgz.e2bn.net/e2bn/leas/c99/schools/cgz/accounts/staff/rchambers/GeoBytes%20GCSE%20Blog%20Resources/Images/Plate%20Tectonics/Plate%20Tectonics/ConvectionCurrent_labelled.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; font-family: Verdana,sans-serif; text-align: center;"&gt;
&lt;span style="font-size: small;"&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; font-family: Verdana,sans-serif; text-align: center;"&gt;
&lt;span style="font-size: small;"&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://upload.wikimedia.org/wikipedia/commons/thumb/4/44/Structure_of_the_magnetosphere_mod.svg/669px-Structure_of_the_magnetosphere_mod.svg.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="153" src="http://upload.wikimedia.org/wikipedia/commons/thumb/4/44/Structure_of_the_magnetosphere_mod.svg/669px-Structure_of_the_magnetosphere_mod.svg.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: left;"&gt;
&lt;span style="font-size: large;"&gt;&lt;u&gt;World Magnetic Model (WMM)&lt;/u&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: left;"&gt;
&lt;span style="font-size: small;"&gt;Major contributors to a magnetic-field:&lt;/span&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: left;"&gt;
&lt;span style="font-size: small;"&gt;+ Conducting, fluid outer core.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;+ Earth's crust and upper mantle.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;+ Electrical currents in the atmosphere.&lt;/span&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: left;"&gt;
&lt;span style="font-size: small;"&gt;+ Local magnetic interference.&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: left;"&gt;
&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: left;"&gt;
&lt;span style="font-size: small;"&gt;By filtering the local magnetic interference due to other electronic/electrical devices, we have a unique magnetic-field signature present at each place on earth. The WMM aims to provide an accurate estimate of this field. A device (having a magnetic sensor) can measure the components of this field. Then comparing it with the WMM values of the earth's field, one can identify the latitude/longitude of the present location.&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: left;"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://www.ngdc.noaa.gov/geomagmodels/IGRFWMM.jsp?defaultModel=WMM" style="margin-left: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-POMJnPFfqbU/TtOAP0xMLEI/AAAAAAAAAuk/hJDKb9opCik/s1600/wmm.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style="font-size: small;"&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Android contains built-in support for the WMM using the &lt;/span&gt;&lt;b style="font-family: Verdana,sans-serif;"&gt;&lt;a href="http://developer.android.com/reference/android/hardware/GeomagneticField.html" target="_blank"&gt;GeomagneticField&lt;/a&gt; &lt;/b&gt;&lt;/span&gt;&lt;span style="font-family: Verdana,sans-serif; font-size: small;"&gt;class. The GeomagneticField class utilises the WMM internally to provide an estimated magnetic field at any given point on
 Earth at a given time. The important thing to note is that this class accepts the location (alongwith altitude and time) and provides the expected magnetic-field at that position (at that particular altitude and instant of time).&lt;/span&gt;&lt;br /&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;To determine the location using the GeomagneticField class, requires some reverse-lookup trickery on our part. More on it in another post.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;u&gt;UPDATE&lt;/u&gt; : A recent &lt;a href="http://thecodeartist.blogspot.com/2012/01/android-sensors-and-location-based.html" target="_blank"&gt;talk on Sensors and Location based services on Android&lt;/a&gt; at &lt;a href="http://www.meetup.com/blrdroid/events/47569402/?a=ea1_lnm&amp;amp;rv=ea1" target="_blank"&gt;blr-droid meetp#12&lt;/a&gt; featuring nGPS among other things.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=Sns1ukGnt2o:zVfpbZMdaKM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=Sns1ukGnt2o:zVfpbZMdaKM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=Sns1ukGnt2o:zVfpbZMdaKM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=Sns1ukGnt2o:zVfpbZMdaKM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/Sns1ukGnt2o" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-17T18:04:21.911+05:30</app:edited><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-POMJnPFfqbU/TtOAP0xMLEI/AAAAAAAAAuk/hJDKb9opCik/s72-c/wmm.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">16</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2011/11/ngps-location-fix-without-gps.html</feedburner:origLink></item><item><title>Tonight's the night : ICS</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/ss19lEERGX0/tonights-night-ics.html</link><category>Misc.</category><category>Android</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Tue, 22 Nov 2011 01:06:35 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-5988045338743118265</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;Two weeks after ICS was released, finally synced-up the entire source. 6GB.&lt;br /&gt;Gave a repo sync and woke-up and it was done! Sweet na?...&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;A good thing with ICS is that pandaboard is supported as-is.&lt;br /&gt;This means that i can&lt;/span&gt;&lt;span style="font-size: small;"&gt;... &lt;/span&gt;&lt;/div&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
&lt;span style="font-size: small;"&gt;$ source build/envsetup.sh&lt;br /&gt;$ lunch full_panda-eng&lt;br /&gt;$ make -j4&lt;/span&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: right;"&gt;
&lt;span style="font-size: small;"&gt; ...and i'm done! :-)&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: right;"&gt;
&lt;div style="text-align: left;"&gt;
&lt;pre style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;And so i have. Estimating 4hrs for a build on my "old" pc.
Tonight's the night... ;-)&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=ss19lEERGX0:_qatTEDM-VQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=ss19lEERGX0:_qatTEDM-VQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=ss19lEERGX0:_qatTEDM-VQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=ss19lEERGX0:_qatTEDM-VQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/ss19lEERGX0" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-22T14:36:35.458+05:30</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2011/11/tonights-night-ics.html</feedburner:origLink></item><item><title>Sensors on Android @ DroidCon2011</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/kCIqMbtA6xs/sensors-on-android-droidcon2011.html</link><category>Programming</category><category>DroidCon2011</category><category>Android</category><category>Sensors</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Mon, 11 Mar 2013 05:20:02 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-7905783747223968161</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Here is the talk i presented @ &lt;a href="http://funnel.hasgeek.com/droidcon/71-sensors-on-android" target="_blank"&gt;DroidCon2011&lt;/a&gt;&lt;br /&gt;
&amp;nbsp;&lt;iframe frameborder="0" height="413" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/10220894" width="500"&gt;&lt;/iframe&gt; &lt;br /&gt;
&lt;br /&gt;
Download &lt;a href="http://www.slideshare.net/cvs26/sensors-on-android-10220894/download" target="_blank"&gt;&lt;b&gt;Sensors on Android @ DroidCon2011&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Gathered lots of inspiration talking (and listening) to several bright minds @DroidCon2011. Will be posting a "few" of them here. So &lt;a href="http://feeds.feedburner.com/TheCodeArtist" target="_blank"&gt;&lt;b&gt;subscribe&lt;/b&gt;&lt;/a&gt; to TheCodeArtist or take a quick peek &lt;a href="http://thecodeartist.blogspot.com/search/label/DroidCon2011" target="_blank"&gt;&lt;b&gt;here&lt;/b&gt;&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;u&gt;&lt;b&gt;Update:&lt;/b&gt;&lt;/u&gt;&amp;nbsp; Here&lt;b&gt; &lt;/b&gt;is the complete video of the talk &lt;a href="https://www.youtube.com/watch?v=GG71M7x-eAA" target="_blank"&gt;&lt;b&gt;Sensors on Android at DroidCon-2011&lt;/b&gt;&lt;/a&gt;.&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="https://ytimg.googleusercontent.com/vi/GG71M7x-eAA/0.jpg" height="400" width="480"&gt;&lt;param name="movie" value="https://www.youtube.com/v/GG71M7x-eAA&amp;fs=1&amp;source=uds" /&gt;&lt;param name="bgcolor" value="#FFFFFF" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;embed width="480" height="400"  src="https://www.youtube.com/v/GG71M7x-eAA&amp;fs=1&amp;source=uds" type="application/x-shockwave-flash" allowfullscreen="true"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;
&lt;br /&gt;
&amp;nbsp; &lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=kCIqMbtA6xs:SjhSXzFQIco:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=kCIqMbtA6xs:SjhSXzFQIco:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=kCIqMbtA6xs:SjhSXzFQIco:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=kCIqMbtA6xs:SjhSXzFQIco:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/kCIqMbtA6xs" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-11T17:50:02.296+05:30</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2011/11/sensors-on-android-droidcon2011.html</feedburner:origLink></item><item><title>Chocosticks</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/iy_DBNyUt-U/chocosticks.html</link><category>Programming</category><category>Game</category><category>chocosticks</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Sun, 06 Nov 2011 03:53:34 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-5206730366902443700</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;object width="320" height="266" class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://i.ytimg.com/vi/kZNl0KTdMFM/0.jpg"&gt;&lt;param name="movie" value="http://www.youtube.com/v/kZNl0KTdMFM?version=3&amp;f=user_uploads&amp;c=google-webdrive-0&amp;app=youtube_gdata" /&gt;
&lt;param name="bgcolor" value="#FFFFFF" /&gt;
&lt;embed width="320" height="266"  src="http://www.youtube.com/v/kZNl0KTdMFM?version=3&amp;f=user_uploads&amp;c=google-webdrive-0&amp;app=youtube_gdata" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;blockquote class="tr_bq"&gt;
More info at &lt;a href="http://code.google.com/p/chocosticks"&gt;code.google.com/p/chocosticks&lt;/a&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=iy_DBNyUt-U:scZ3smhN5mI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=iy_DBNyUt-U:scZ3smhN5mI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=iy_DBNyUt-U:scZ3smhN5mI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=iy_DBNyUt-U:scZ3smhN5mI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/iy_DBNyUt-U" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-06T17:23:34.164+05:30</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2011/11/chocosticks.html</feedburner:origLink></item><item><title>AI : Heuristics</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/YxsySTYRMGE/ai-heuristics.html</link><category>AI</category><category>Programming</category><category>Artificial Intelligence</category><category>Heuristics</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Thu, 03 Nov 2011 05:22:55 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-3345324706126496688</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div style="text-align: center;"&gt;
&lt;div style="text-align: left;"&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Programming artificial 
intelligence into a piece of code is NOT about anticipating every single
 thing that can possibly happen. A heuristic approach is more practical 
to implement. Implementing a heuristic model has an added advantage that
 the system improves every time it is run.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
Missed Part1 of this series? &lt;a href="http://thecodeartist.blogspot.com/2011/01/ai-artificial-or-actual-intelligence.html"&gt;AI: Artificial or Actual intelligence&lt;/a&gt;&lt;br /&gt;
&amp;nbsp;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;b&gt;Heuristics&lt;/b&gt; (meaning "to find" or "discover")
 refers to techniques for learning, discovery and problem solving. Heuristic methods are used to speed up the process of 
finding a satisfactory solution. When an exhaustive search is 
impractical.&lt;/blockquote&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;u&gt;&lt;b&gt;&lt;/b&gt;&lt;/u&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;u&gt;&lt;b&gt;Implementing a heuristic model:&lt;/b&gt;&lt;/u&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;b&gt;1. &lt;/b&gt;Setup a generic system that runs by a "rulebook".&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style="text-align: left;"&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;The "rulebook" contains &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;set of very simple rules to start with. &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;b&gt;2. &lt;/b&gt;Design a "playbook" which is easily extensible.&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style="text-align: left;"&gt;
&lt;li&gt;Use arrays, linked-lists, b-trees, tables, a relational-database,... Anything. Just remember that the "playbook" is going to grow very fast. Eventually it will contain ALL the rules &amp;amp; tactics that exist.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;b&gt;3. &lt;/b&gt;Let the system run-wild.&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style="text-align: left;"&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;At each turn, the system follows the existing rules in the "rulebook". It picks the best move applicable in the current context from the "playbook"&amp;nbsp; At the end of each run, save the moves &amp;amp; the outcome to the "playbook" for reference in the next runs.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Thus the code "learns" the consequences of each move and gradually evolves (into something better) with each run. Care should be taken to formulate the "rulebook". It must be carefully devised to prevent the AI system from performing any illegal moves.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;u&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
&lt;u&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;Additional points of interest:&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
&lt;ul style="font-family: Verdana,sans-serif; text-align: left;"&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;Pruning&lt;/b&gt; : Removing obsolete/duplicate entries from the rulebook.&lt;br /&gt;- Reduces the "rulebook" size. Leads to faster decision making.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Character traits&lt;/b&gt; : Aggressive, defensive, favorite moves etc.&lt;br /&gt;- Useful in games. To provide multiple opponents.&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;Realistic AI&lt;/b&gt; : Possible to trick AI into making occasional mistakes.&lt;br /&gt;- Again useful in games. Makes gameplay more realistic &amp;amp; fun.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=YxsySTYRMGE:tQo6QAcmJEo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=YxsySTYRMGE:tQo6QAcmJEo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=YxsySTYRMGE:tQo6QAcmJEo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=YxsySTYRMGE:tQo6QAcmJEo:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/YxsySTYRMGE" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-03T17:52:55.396+05:30</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><georss:featurename xmlns:georss="http://www.georss.org/georss">Jeevanbheema Nagar Main Rd, HAL III Stage, New Thipasandra, Bengaluru, Karnataka, India</georss:featurename><georss:point xmlns:georss="http://www.georss.org/georss">12.968273037893827 77.65063494443893</georss:point><georss:box xmlns:georss="http://www.georss.org/georss">12.968031037893827 77.65032644443893 12.968515037893827 77.65094344443894</georss:box><feedburner:origLink>http://thecodeartist.blogspot.com/2011/09/ai-heuristics.html</feedburner:origLink></item><item><title>Simulating keypress events on Android</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/ZkG-4ZbHXG0/simulating-keyevents-on-android-device.html</link><category>Programming</category><category>keyevents</category><category>CodeProject</category><category>Android</category><category>adb</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Sun, 16 Sep 2012 00:35:36 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-7675200813478700747</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://lh5.googleusercontent.com/-XGYesWeOJqw/TYIpi_f7XzI/AAAAAAAAAX4/kqwTmkGaq5g/s1600/power-key-button.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="https://lh5.googleusercontent.com/-XGYesWeOJqw/TYIpi_f7XzI/AAAAAAAAAX4/kqwTmkGaq5g/s1600/power-key-button.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style="font-size: small;"&gt;Modern day smart-phones have already begun to migrate from the traditional "a-button-for-every-need" approach to the "huge-display-cum-touchscreen" form-factors. Android phones&amp;nbsp; are no exception. But, traditional buttons are still reqd. for a few oft used functions (power,back,home,menu etc.) And smart-phones continue to have them alongwith the primary touch-based-UI.&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;Android-OS provides a very easy method to simulate key/button press/release events via software. You might ask why do we need a software to generate the events when a hardware button is already present on the device. Here's why:&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul style="font-family: Verdana,sans-serif; text-align: left;"&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;During development/testing of the button-drivers itself.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;To implement automated rigorous tests. ( &lt;b&gt;&lt;a href="http://developer.android.com/guide/developing/tools/monkey.html"&gt;MonkeyTest&lt;/a&gt;&lt;/b&gt;? )&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;To implement/interface additional custom software keyboards. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;Just because we can!&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;The reason why i am doing it today is &lt;b&gt;REASON NUMBER 4&lt;/b&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;Now, the basic goal of this exercise is extremely simple:&lt;/span&gt;&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-size: small;"&gt;Q. How to generate a hardware-button-press event&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; WITHOUT actually pressing any key on the device?&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;span style="font-size: small;"&gt;Let us first understand what happens when a hardware button is pressed. &lt;/span&gt;&lt;span style="font-size: small;"&gt;Here is what happens when you press a button on an Android device:&lt;/span&gt;&lt;/div&gt;
&lt;ol style="font-family: Verdana,sans-serif; text-align: left;"&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;The h/w button triggers an interrupt.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;The ISR of the corresponding driver gets called (in kernel).&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;In the ISR, the driver generates an input-event.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;Android-framework (in userspace) gets the notification of the event.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;Android reads the input-event code &amp;amp; type.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;Compares it with the proper "keymap/keylayout" file.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;The proper button is identified.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;To simulate button presses we enter this procedure at STEP3.&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;Instead of the regular driver generating the input-event, we generate an input-event ourselves using a pre-built userspace binary. This will then be notified to the Android-framework and the rest continues as above.&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;So now all depends on the the pre-built userspace binary, which is...&lt;br /&gt;
[ drum-roll... ]&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;...&lt;b&gt;Input&lt;/b&gt;. (How convenient!) The syntax of&lt;b&gt; input&lt;/b&gt; is as follows&lt;b&gt;:&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;b&gt;input &lt;/b&gt;keyevent &amp;lt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;event_code&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;Now, before we try to send any keyevent, we need to find out the event-code that maps to the h/w key we want to simulate. The following table summarizes all the supported keycodes in Android:&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;span style="font-size: small;"&gt;&lt;a href="https://lh4.googleusercontent.com/-kb19V3eCj1g/TYIaEklPgmI/AAAAAAAAAXQ/cz1mEj9Wr_s/s1600/Android-input-keycodes.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://lh4.googleusercontent.com/-kb19V3eCj1g/TYIaEklPgmI/AAAAAAAAAXQ/cz1mEj9Wr_s/s1600/Android-input-keycodes.png" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-family: Verdana,sans-serif; font-size: small;"&gt;Additionally we can look up the keylayout (.kl) file on the device. Personally, I find keylayout a misnomer, as we are not talking about different keyboards here, but different mappings of an input-event-value to its functionality.&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt; &lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;Anyways you can always find the file in &lt;b&gt;system/usr/keylayout/xyz.kl&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;b&gt;NOTE: &lt;/b&gt;&lt;/span&gt;&lt;span style="font-family: Verdana,sans-serif; font-size: small;"&gt;For each keyboard device &lt;b&gt;xyz&lt;/b&gt;, the &lt;b&gt;android.keylayout.xyz&lt;/b&gt; system property must be set. If a keylayout file is not specified, Android will default to&lt;b&gt; /system/usr/keylayout/qwerty.kl&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;Now to generate a event of a specific keycode, we simply execute this on the terminal/serial console:&lt;/span&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;b&gt;input keyevent &amp;lt;keycode&amp;gt;&lt;/b&gt; &lt;/span&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;The value of &lt;b&gt;keycode&lt;/b&gt; can be any of the integer values from the above table. In case a serial-console is NOT available on your device, you can always run the command via adb as follows:&lt;/span&gt;&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-size: small;"&gt;&lt;b&gt;adb shell input keyevent &amp;lt;keycode&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;br /&gt;
&lt;span style="font-size: small;"&gt;That's how a hardware-button-press is simulated&lt;/span&gt;&lt;span style="font-size: small;"&gt; in software&lt;/span&gt;&lt;span style="font-size: small;"&gt;!!&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;u style="font-family: Verdana,sans-serif;"&gt;Further Reading: &lt;/u&gt;&lt;/span&gt;&lt;br /&gt;
&lt;ul style="font-family: Verdana,sans-serif; text-align: left;"&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;More on keycodes, keymaps &amp;amp; Android-Input in general:&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;a href="http://www.netmite.com/android/mydroid/development/pdk/docs/keymaps_keyboard_input.html"&gt;&lt;br /&gt;
Android/development/pdk/docs/keymaps_keyboard_input.html&lt;br /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;Android's Keyevent Class summary&lt;br /&gt;&lt;a href="http://developer.android.com/reference/android/view/KeyEvent.html"&gt;http://developer.android.com/reference/android/view/KeyEvent.html&lt;/a&gt; &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=ZkG-4ZbHXG0:UMshzS1GinE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=ZkG-4ZbHXG0:UMshzS1GinE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=ZkG-4ZbHXG0:UMshzS1GinE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=ZkG-4ZbHXG0:UMshzS1GinE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/ZkG-4ZbHXG0" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2012-09-16T13:05:36.040+05:30</app:edited><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://lh5.googleusercontent.com/-XGYesWeOJqw/TYIpi_f7XzI/AAAAAAAAAX4/kqwTmkGaq5g/s72-c/power-key-button.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">40</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2011/03/simulating-keyevents-on-android-device.html</feedburner:origLink></item><item><title>Quilt : This patch can be reverse applied</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/KbIpEp06CrY/quilt-this-patch-can-be-reverse-applied.html</link><category>Quilt</category><category>Programming</category><category>Patches</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Tue, 22 Mar 2011 23:19:16 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-8028268845331164344</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;Quilt&lt;/b&gt; is a very sweet little tool. Very easy for generating &amp;amp; maintaining a &lt;b&gt;series&lt;/b&gt; of&amp;nbsp; &lt;b&gt;patches&lt;/b&gt; to your code. Anyone involved in even a moderate bit of &lt;b&gt;quilt&lt;/b&gt;ing will often come across this message especially when trying to apply &lt;b&gt;import&lt;/b&gt;ed patches.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;blockquote style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Patch &amp;lt;&lt;b&gt;patch-name here&lt;/b&gt;&amp;gt; can be reverse-applied &lt;/span&gt;&lt;/blockquote&gt;&lt;div style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;What exactly does this message mean?&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;div style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;Quilt is basically trying to tell us that &lt;b&gt;ALL&lt;/b&gt; the changes in the patch (we are trying to apply) are already present in our code.The term "&lt;b&gt;reverse-applied&lt;/b&gt;" seems to be derived from some other version-control system.&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Verdana,sans-serif;"&gt;&lt;span style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Verdana,sans-serif; text-align: left;"&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;How-To &lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;Resolve this error?...&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-size: small;"&gt;Simply comment the patch file in the series file as follows:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-size: small;"&gt;prev patch file&lt;br /&gt;
#current patch file&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;-- this patch can be reverse-applied.&lt;br /&gt;
next patch file1&lt;br /&gt;
next patch file2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-size: small;"&gt;This effectively means that since all the changes provided by this patch are already present in your existing code, you are ignoring this patch completely and moving on to the next patch in the series.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-size: small;"&gt;Read more about quilt &lt;a href="http://linux.die.net/man/1/quilt"&gt;&lt;b&gt;here&lt;/b&gt;&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-size: small;"&gt;&lt;u&gt;&lt;b&gt;UPDATE:&lt;/b&gt;&lt;/u&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-size: small;"&gt;Also one can use the &lt;a href="http://linux.die.net/man/1/patch"&gt;&lt;b&gt;patch -R&lt;/b&gt;&lt;/a&gt; command to reverse-apply&lt;br /&gt;
(i.e. revert) the patch. This is equivalent to removing the changes made by the patch, without altering the series.&lt;br /&gt;
(i.e. without quilt in the picture.)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-size: small;"&gt;After the patch -R command succeeds, then &lt;b&gt;quilt push&lt;/b&gt; should work well and add the changes back and proceed to the next patch-file in the series.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: small;"&gt;&lt;span style="font-size: small;"&gt;Read more about patch &lt;a href="http://linux.die.net/man/1/patch"&gt;&lt;b&gt;here&lt;/b&gt;&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt; &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-size: small;"&gt; &lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=KbIpEp06CrY:0HssT6hzyTg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=KbIpEp06CrY:0HssT6hzyTg:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=KbIpEp06CrY:0HssT6hzyTg:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=KbIpEp06CrY:0HssT6hzyTg:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/KbIpEp06CrY" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-23T11:49:16.298+05:30</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2011/03/quilt-this-patch-can-be-reverse-applied.html</feedburner:origLink></item><item><title>Proximity Sensor on Android Gingerbread</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/UW_3buBIn5o/proximity-sensor-on-android-gingerbread.html</link><category>Proximity-sensor</category><category>Light Sensor</category><category>CodeProject</category><category>Android</category><category>Sensors</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Sun, 16 Sep 2012 00:35:36 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-9142332612803020465</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div class="separator" style="clear: both; font-family: Verdana,sans-serif; text-align: center;"&gt;
&lt;span style="font-size: small;"&gt;&lt;a href="http://3.bp.blogspot.com/_Z0O1Byloutc/TS1apHo0IOI/AAAAAAAAAQ4/7HCvijZeP3o/s1600/proximity-call.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://3.bp.blogspot.com/_Z0O1Byloutc/TS1apHo0IOI/AAAAAAAAAQ4/7HCvijZeP3o/s200/proximity-call.png" width="200" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;The proximity sensor is common on most smart-phones, the ones that have a touchscreen. This is because the primary function of a proximity sensor is to disable accidental touch events. The most common scenario being- The ear coming in contact with the screen and generating touch events, while on a call.&lt;/span&gt;&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;To solve the "&lt;b&gt;I didn't take that stupid picture, my ear did&lt;/b&gt;" issue, device manufacturers came up with the idea of a placing a proximity sensor close to the speaker, which will then detect any object in the vicinity of the speaker. If any object is present (ex. user's ear), then the touch events can be assumed to be accidental &amp;amp; ignored.&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;Now there are various technologies for proximity sensing:&lt;/span&gt;&lt;/div&gt;
&lt;ul style="font-family: Verdana,sans-serif;"&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;Electrical (Inductive, Capacitive)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;Optical. (IR, Laser)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;Magnetic.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt;Sonar.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;Of all these, the most non-intrusive and low-cost modules are the optical proximity sensors. These can detect bodies in the vicinity of the device upto 5cm. This is perfect for use on smart-phones.&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;Coming to &lt;a href="http://thecodeartist.blogspot.com/2010/12/sensors-on-android-23-gingerbread.html"&gt;Sensors on Android-Gingerbread&lt;/a&gt;, the proximity sensor is often implemented using a light sensor chip. Common ones are ISL29003/23 &amp;amp; GP2A by Intersil &amp;amp; Sharp respectively. Both these sensor-chips are primarily active light sensors, which provide the ambient light intensity in &lt;a href="http://en.wikipedia.org/wiki/Lux"&gt;LUX &lt;/a&gt;units.&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;blockquote&gt;
&lt;span style="font-size: small;"&gt;The distance value is measured in centimeters. Note that some proximity sensors only support a binary "close" or "far" measurement.&amp;nbsp; In this case, the sensor should report its maxRange value in the "far" state and a value less than maxRange in the "near" state.&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; font-family: Verdana,sans-serif; text-align: center;"&gt;
&lt;span style="font-size: small;"&gt;&lt;a href="http://3.bp.blogspot.com/_Z0O1Byloutc/TS1apHo0IOI/AAAAAAAAAQ4/7HCvijZeP3o/s1600/proximity-call.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; font-family: Verdana,sans-serif; text-align: center;"&gt;
&lt;span style="font-size: small;"&gt;&lt;a href="http://2.bp.blogspot.com/_Z0O1Byloutc/TS1Zwksdi1I/AAAAAAAAAQw/8VwY5plJvvY/s1600/proximity-sensorl.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/_Z0O1Byloutc/TS1Zwksdi1I/AAAAAAAAAQw/8VwY5plJvvY/s200/proximity-sensorl.png" width="133" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;a href="http://3.bp.blogspot.com/_Z0O1Byloutc/TS2FjzMNkRI/AAAAAAAAARQ/iYOEWNDLDls/s1600/proximity-threshold.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;Let us take an example. Say the device uses a GP2A chip placed close to the speaker facing the user (as shown in the adjoining pic). The normal&amp;nbsp; light response of the GP2A is such that it triggers a proximity-detect interrupt at a distance of approximately 5cms in normal lighting. &lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;This means that when the user receives a call and brings the phone closer to his ear, the ambient-light around the light/proximity-sensor slowly drops down below the threshold &amp;amp; the sensor detects this and switches the state from FAR to NEAR. This event can be detected by any android application which has registered a SensorEventListener.&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; font-family: Verdana,sans-serif; text-align: center;"&gt;
&lt;span style="font-size: small;"&gt;&lt;a href="http://3.bp.blogspot.com/_Z0O1Byloutc/TS2FjzMNkRI/AAAAAAAAARQ/iYOEWNDLDls/s1600/proximity-threshold.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="96" src="http://3.bp.blogspot.com/_Z0O1Byloutc/TS2FjzMNkRI/AAAAAAAAARQ/iYOEWNDLDls/s200/proximity-threshold.png" width="200" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;In most Android phones, the proximity sensor is implemented as a boolean-sensor. Its returns just two values "NEAR" &amp;amp; "FAR". &lt;i&gt;&lt;b&gt;Thresholding&lt;/b&gt;&lt;/i&gt; is done on the LUX value i.e. the LUX value of the light sensor is compared with a &lt;i&gt;&lt;b&gt;threshold&lt;/b&gt;&lt;/i&gt;.  A LUX-value more than threshold means the proximity sensor returns "FAR".  Anything less than the threshold value and the sensor&amp;nbsp; returns "NEAR". The actual value of threshold is  custom-defined depending on the sensor-chip in use and its  light-response, coupled with the location &amp;amp; orientation of the chip  on the smart-phone body. &lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;The proximity sensor is implemented very much like the other sensors except on one critical point - &lt;/span&gt;&lt;/div&gt;
&lt;blockquote style="font-family: Verdana,sans-serif;"&gt;
&lt;div style="text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;Proximity sensor is interrupt-based (not Poll-based). &lt;/span&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;All the other sensors are polled for at regular intervals, selected by the DELAY parameter used while registering a SensorEventListener. Proximity Sensor is interrupt based (NOT polling). This means that we get a proximity event only when the proximity changes (either &lt;b&gt;NEAR to FAR&lt;/b&gt; or &lt;b&gt;FAR to NEAR&lt;/b&gt;).&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: center;"&gt;
&lt;span style="font-size: small;"&gt;__________________________&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif; text-align: justify;"&gt;
&lt;span style="font-size: small;"&gt;Further Reading:&lt;/span&gt;&lt;/div&gt;
&lt;ul style="font-family: Verdana,sans-serif;"&gt;
&lt;li&gt;&lt;span style="font-size: small;"&gt; &lt;a href="http://thecodeartist.blogspot.com/2010/12/sensors-on-android-23-gingerbread.html"&gt;Complete overview of Sensors of Android Gingerbread&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="font-family: Verdana,sans-serif;"&gt;
&lt;span style="font-size: small;"&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=UW_3buBIn5o:TM6xuU_5vFk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=UW_3buBIn5o:TM6xuU_5vFk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=UW_3buBIn5o:TM6xuU_5vFk:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=UW_3buBIn5o:TM6xuU_5vFk:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/UW_3buBIn5o" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2012-09-16T13:05:36.043+05:30</app:edited><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_Z0O1Byloutc/TS1apHo0IOI/AAAAAAAAAQ4/7HCvijZeP3o/s72-c/proximity-call.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">31</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2011/01/proximity-sensor-on-android-gingerbread.html</feedburner:origLink></item><item><title>AI : Artificial or Actual Intelligence</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/2_mZD4GGIug/ai-artificial-or-actual-intelligence.html</link><category>AI</category><category>Programming</category><category>Artificial Intelligence</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Wed, 05 Oct 2011 06:55:38 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-2672461641575432218</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Here is a question for the programmer in you:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;
Q. How do you write a program that writes itself ?&lt;/blockquote&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
NOTE: The following article is NOT about &lt;a href="http://en.wikipedia.org/wiki/Quine_%28computing%29"&gt;quines&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Now coming back to the question, let us think for a moment. do we really need a program that can write itself. Or to put it more precisely, In what scenario is a self-modifying piece of code better than one which is not?&lt;br /&gt;
&lt;br /&gt;
The first obvious scenario that comes to mind is that : Catching Run-time Errors.&lt;br /&gt;
Currently there are two schools of thought on the whole run-time issue scene.&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Run-Time errors are critical and must and should be identified &amp;amp; fixed.&lt;/li&gt;
&lt;li&gt;There is no such thing as a Run-Time error.&lt;br /&gt;
( There are only Exceptions &lt;b&gt;;)&lt;/b&gt; )&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;/ul&gt;
&lt;ol&gt;&lt;/ol&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/_Z0O1Byloutc/TR1vxm1BsfI/AAAAAAAAAQk/KivzwYo0Jis/s1600/agile-test-cycle.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="198" src="http://2.bp.blogspot.com/_Z0O1Byloutc/TR1vxm1BsfI/AAAAAAAAAQk/KivzwYo0Jis/s200/agile-test-cycle.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
The first school of thought is very harsh on developer. It expects developers to foresee the program's future and code in such a manner so as to be able to handle ANY situation that may arise ( however rarely). This also encourages Test-Driven programming which is sloppy to say the least. With every test-cycle discovering a series of "bugs" (that occur once 1 say 10,000 iterations) &amp;amp; adding a series of "minor" patches or fixes for each. By the time the code is considered "ready", its hardly efficient any more. Often the patches outnumber the original code itself.&lt;b style="color: red;"&gt;&lt;span style="font-size: xx-small;"&gt;[1]&lt;/span&gt;&lt;/b&gt; This goes to show that the "ready" code doesn't do its job efficiently, but also more importantly, no longer does it do what it was originally intended to. &lt;i&gt;You don't take a F1 car and add a tanker-trailer to carry gasoline just in case it runs out.&lt;/i&gt; Proper design is a prerequisite and oft ignored phase in most development projects&lt;span style="font-size: xx-small;"&gt; &lt;b style="color: red;"&gt;[2]&lt;/b&gt;&lt;/span&gt;.&lt;/div&gt;
&lt;br /&gt;
In the second school of thought, we find die-hard fans and wannabe fan-boys of&amp;nbsp; languages like JAVA that allow a developer to get away with anything and everything, as long as he feels comfortable doing it the way it is done. A guy trained in this school of thought will firmly believe that-&lt;br /&gt;
&lt;blockquote&gt;
&lt;i&gt;If a tree was going to fall, and you knew it would fall,&lt;br /&gt;
then hey! its not a problem anymore. Its expected behavior!&lt;/i&gt;&amp;nbsp;&lt;/blockquote&gt;
Rather than preventing the tree from falling,&lt;br /&gt;
you gently step aside &amp;amp; wait for it to fall...&lt;br /&gt;
&lt;div style="text-align: right;"&gt;
...and then proceed&lt;span style="font-size: xx-small;"&gt;&lt;span style="font-size: small;"&gt;&lt;b style="color: red;"&gt;&lt;span style="font-size: xx-small;"&gt; [3]&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
try {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; tree = forest.tree;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (tree.falling() == 1) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; throw new TreeFallingException("RUN!");&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; console.printLine("All iz well");&lt;br /&gt;
&lt;br /&gt;
} catch (TreeFallingException e) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; console.printLine("RUN! RUN! RUN!");&lt;br /&gt;
&lt;br /&gt;
} catch (Exception err) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; console.printLine("No tree, But RUN! " + err.WhyToRun());&lt;br /&gt;
&lt;br /&gt;
} finally {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; console.printLine("THE-END");&lt;br /&gt;
}&lt;/blockquote&gt;
&lt;br /&gt;
As we see, neither approach is perfect and both have their disadvantages.&lt;span style="font-size: large;"&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;Enter A.I. &lt;/b&gt;...&lt;/span&gt;&lt;br /&gt;
Imagine a platform where you have infinite memory. Now add infinite processing power to your kitty. With these two in your pocket, you can write a program to do pretty much anything, right? So whats the catch you might ask.&lt;br /&gt;
That IS &lt;b&gt;THE&lt;/b&gt; catch? &lt;b&gt;Your program has to be able to do EVERYTHING!&lt;/b&gt;&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;br /&gt;
More on this in a latter post.&lt;br /&gt;
&lt;br /&gt;
To wrap-up:&lt;br /&gt;
&lt;blockquote&gt;
&lt;b&gt;Q.&lt;/b&gt; How do you write a program that writes itself ?&lt;br /&gt;
&lt;b&gt;ANS:&lt;/b&gt; Quite simply, &lt;b&gt;You don't! ;-)&lt;/b&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;br /&gt;
Read part2 of this series &lt;a href="http://thecodeartist.blogspot.com/2011/09/ai-heuristics.html"&gt;AI: Heuristics&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;u&gt;Footnotes:&lt;/u&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;span style="font-size: xx-small;"&gt;&lt;span style="font-size: small;"&gt;&lt;b style="color: red;"&gt;&lt;span style="font-size: xx-small;"&gt;[1]&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: xx-small;"&gt;&lt;span style="font-size: small;"&gt; Each patch to the applied to the code is the evolving code itself. But developer intervenes individually.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b style="color: red;"&gt;&lt;span style="font-size: xx-small;"&gt;[2]&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: xx-small;"&gt;&lt;span style="font-size: small;"&gt; Today's average&amp;nbsp;developer, having been exposed to the horrors of coding a poor design, is in a position to understand the problems of not spending enough time in the design phase. But, Its often the tightly constrained project schedules and the uncertainty associated with new-technologies that mean that there is never enough time dedicated to the design-phase.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: xx-small;"&gt;&lt;span style="font-size: small;"&gt;&lt;b style="color: red;"&gt;&lt;span style="font-size: xx-small;"&gt;[3]&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: xx-small;"&gt;&lt;span style="font-size: small;"&gt; Each catch-block added to the&amp;nbsp;code is the evolving code itself. Again here the developer intervenes.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=2_mZD4GGIug:Lt7bLZ-_QuE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=2_mZD4GGIug:Lt7bLZ-_QuE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=2_mZD4GGIug:Lt7bLZ-_QuE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=2_mZD4GGIug:Lt7bLZ-_QuE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/2_mZD4GGIug" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-05T19:25:38.668+05:30</app:edited><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_Z0O1Byloutc/TR1vxm1BsfI/AAAAAAAAAQk/KivzwYo0Jis/s72-c/agile-test-cycle.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2011/01/ai-artificial-or-actual-intelligence.html</feedburner:origLink></item><item><title>Sensors on Android Gingerbread</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/lV15hACCkcA/sensors-on-android-gingerbread.html</link><category>Invensense</category><category>Programming</category><category>Gingerbread</category><category>Android</category><category>Sensors</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Tue, 10 Jul 2012 03:44:21 PDT</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-6151227713622239286</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Android 2.3 (codename Gingerbread) was officially released amidst huge hype and fanfare last week and BOY O BOY!!&amp;nbsp; people sure are queuing-up to have a peek. Sensors were the most hyped about sub-system. &lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
Just google-search "Android Gingerbread" &amp;amp;&lt;span id="main" style="visibility: visible;"&gt;&lt;span id="search" style="visibility: visible;"&gt;&lt;span class="tl"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; you will see a host of results of this pattern:&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;blockquote&gt;
&lt;h3 class="r"&gt;


&lt;i&gt;&lt;span style="font-size: large;"&gt;The big news in Android 2.3 Gingerbread&lt;br /&gt;
Support for new &lt;b&gt;sensors&lt;/b&gt;&lt;/span&gt;&lt;/i&gt;&lt;/h3&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
Android-Fans sure are blogging everywhere about the enhanced support for "NEW" sensors on gingerbread. But having worked on Android sensors since the days of cupcake, I beg to differ...&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;
&lt;b&gt;&lt;span style="font-size: small;"&gt;Gingerbread does NOT support any NEW sensors!&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
Here is what Android has to say in the official Gingerbread &lt;b&gt;&lt;a href="http://developer.android.com/sdk/android-2.3-highlights.html#gaming"&gt;release notes&lt;/a&gt;&lt;/b&gt;.&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
&lt;blockquote&gt;
&lt;div style="margin-bottom: 0.75em; margin-top: 1.25em;"&gt;
&lt;b&gt;Native input and sensor events&lt;/b&gt;&lt;/div&gt;
Applications that use native code can now receive and process input and sensor events directly in their native code, which dramatically improves efficiency and responsiveness. &lt;br /&gt;
Native libraries exposed by the platform let applications handle the same types of input events as those available through the framework. Applications can receive events from all supported sensor types and can enable/disable specific sensors and manage event delivery rate and queueing. &lt;br /&gt;
&lt;div style="margin-bottom: 0.75em; margin-top: 1.25em;"&gt;
&lt;b&gt;Gyroscope and other new sensors,&lt;br /&gt;
for improved 3D motion processing&lt;/b&gt;&lt;/div&gt;
Android 2.3 adds API support for several new sensor types, including gyroscope, rotation vector, linear acceleration, gravity, and barometer sensors. Applications can use the new sensors in combination with any other sensors available on the device, to track three-dimensional device motion and orientation change with high precision and accuracy. For example, a game application could use readings from a gyroscope and accelerometer on the device to recognize complex user gestures and motions, such as tilt, spin, thrust, and slice.&lt;/blockquote&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
That &lt;b&gt;IS&lt;/b&gt; quite a mouthful. But stripping-off the marketing-spiel we can say:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Gingerbread provides sensors-support to native C/C++ apps.&lt;/li&gt;
&lt;li&gt;Gingerbread provides more accurate and precise sensor-data.&lt;/li&gt;
&lt;li&gt;Gingerbread provides APIs to recognise complex user gestures.&lt;/li&gt;
&lt;li&gt;Gingerbread supports gyroscope and barometer.&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;div style="text-align: justify;"&gt;
While points [1], [2], [3] do mention tremendous improvements over FroYo, none of them has to do anything with any new sensors. Moving on to [4] we see the first mention of supposedly new sensors. But, here are two things that most people overlook:&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;div style="text-align: left;"&gt;
&lt;b&gt;- Both Gyroscope and Barometer (i.e. pressure) sensors were already available in previous releases of Android.&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;&lt;b&gt;
- The 4 "NEW" sensors (shown below) are just wrapper-APIs around existing hardware. They just provided "easy-to-digest" data.&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: right;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-d9ugZlsyo1A/T_wGgSaQ2FI/AAAAAAAAA5o/zkA9nabXxXU/s1600/Sensors-GB.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="280" src="http://1.bp.blogspot.com/-d9ugZlsyo1A/T_wGgSaQ2FI/AAAAAAAAA5o/zkA9nabXxXU/s320/Sensors-GB.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Real Sensors map 1-to-1 to actual Hardware. Data of Virtual Sensors, on the other hand, is exported to the apps by performing calculations on 1(or more) real sensors.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
These newly introduced wrapper-APIs process the raw sensor data into a format ready to use by the Android apps. This proves especially useful to the apps doing advanced 3D math. ( &lt;i&gt;read Games&lt;/i&gt; &lt;b&gt;;)&lt;/b&gt; )&lt;b&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;
&lt;/b&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
Gyroscope sensor was supported in FroYo and so was Barometer. Since it was early days for Android sensors not much attention was paid to them. Maybe even added as an afterthought to the existing array of Accelerometer,Compass,Orientation.&amp;nbsp;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
With Android apps ( &lt;i&gt;again read Games &lt;/i&gt;&lt;b&gt;;)&lt;/b&gt; ) really pushing them to the limit, the limitations of a "pure" accelerometer device became evident.&lt;/div&gt;
&lt;div style="text-align: justify;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;Step-In INVENSENSE...&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://www.fareastgizmos.com/entry_images/0108/29/invensense-thumb-450x236.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="104" src="http://www.fareastgizmos.com/entry_images/0108/29/invensense-thumb-450x236.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
Founded in 2003, InvenSense is based in Sunnyvale, California, Invensense is a market-leader in advanced MEMS gyroscope design. Their latest offering (based on SensorFusion technology) is a MotionProcessing library i.e. &lt;b&gt;&lt;a href="http://www.invensense.com/mems/gyro/documents/articles/120710_InvenSense_Announces_Worlds_First_MotionProcessing_Library_9-Axis_Sensor_Fusion_For_Android_Gingerbread.html"&gt;MPL on Android Gingerbread&lt;/a&gt;&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Apart from the rudimentary API which Android provided, Invensense Motion-Processing Library(MPL) sits alongside the Sensor-HAL and provides a feature-rich API to obtain Gestures, Glyphs &amp;amp; Pedometer data from sensors.&lt;br /&gt;
&lt;br /&gt;
All this data is derieved from a combination of Accelerometer/Gyroscope/Compass hardware modules. The MPL processes the individual data and combines them appropriately to overcome the individual limitations of each sensor &amp;amp; provide an overall better stream of precise &amp;amp; accurate (processed)samples. Also Advanced operation/Pattern-matching &amp;amp; count is done by the MPL and any app can then directly obtain data pertaining to gestures or step-counts(pedometer) etc. using the MPL APIs.&lt;br /&gt;
&lt;br /&gt;
Here is a "short" video by David Sachs(Invensense Tech) which explains the advantages of INVENSENSE MPL extensions on Android...&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://1.gvt0.com/vi/C7JQ7Rpwn2k/0.jpg" height="400" width="480"&gt;&lt;param name="movie" value="http://www.youtube.com/v/C7JQ7Rpwn2k&amp;fs=1&amp;source=uds" /&gt;
&lt;param name="bgcolor" value="#FFFFFF" /&gt;
&lt;embed width="480" height="400" src="http://www.youtube.com/v/C7JQ7Rpwn2k&amp;fs=1&amp;source=uds" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
To conclude, one can say that the Sensor sub-system has undergone a huge overhaul&amp;nbsp; in Gingerbread. And one can only hope that what it delivers is well worth all the hyped-up expectations.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;
_________________________&lt;/div&gt;
&lt;div style="text-align: center;"&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;b&gt;Related Posts:&lt;/b&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://thecodeartist.blogspot.com/2011/01/proximity-sensor-on-android-gingerbread.html"&gt;&lt;b&gt;Proximity Sensor on Android&lt;/b&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=lV15hACCkcA:IRs-r6U2a9s:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=lV15hACCkcA:IRs-r6U2a9s:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=lV15hACCkcA:IRs-r6U2a9s:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=lV15hACCkcA:IRs-r6U2a9s:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/lV15hACCkcA" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2012-07-10T16:14:21.023+05:30</app:edited><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-d9ugZlsyo1A/T_wGgSaQ2FI/AAAAAAAAA5o/zkA9nabXxXU/s72-c/Sensors-GB.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2010/12/sensors-on-android-gingerbread.html</feedburner:origLink></item><item><title>Bachelor of (Reverse) Engineering</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/yA1jDJ7lp_8/bachelor-of-reverse-engineering.html</link><category>Programming</category><category>Misc.</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Mon, 26 Dec 2011 05:31:54 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-5211009240716012067</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Just a thought - What makes newly graduated engineers (or "freshers" in layman terms) such bad programmers. Why is it that in the IT industry, experience counts more than anything else! Why is it that companies spend so much in training recently graduated engineers "freshers". More simply put,&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;
Q. What is the main difference between a&lt;br /&gt;
"&lt;b&gt;brilliant fresher&lt;/b&gt;" and an "&lt;b&gt;experienced pro&lt;/b&gt;"?&lt;/blockquote&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;The answer lies in the following fact. Most of what is taught in undergraduate courses (BE/B.Tech) is irrelevant to what one actually ends up doing as a "fresher" programmer. No one in his/her right mind would tell a fresher to design the framework of a new module. Also a programmer never has to write fresh code from scratch. The job at hand is, almost always, to fix bugs in existing code and sometimes to add a few "features" to existing software.&lt;br /&gt;
This means the good programmer needs to be:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Good at &lt;u&gt;reading&lt;/u&gt; code quickly.&lt;/li&gt;
&lt;li&gt;Good at &lt;u&gt;identifying&lt;/u&gt; the relevant parts quickly. &lt;/li&gt;
&lt;li&gt;Good at &lt;u&gt;understanding &lt;/u&gt;code quickly.&lt;/li&gt;
&lt;/ul&gt;
It might be surprising to know, but seldom are these emphasized enough. Rarely does any "fresher" ever focus on these aspects. Instead you will always find one totally engrossed in any of the following:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;u&gt;Writing&lt;/u&gt; code as efficiently as possible.&lt;/li&gt;
&lt;li&gt;&lt;u&gt;Writing &lt;/u&gt;it so that it is easier to understand.&lt;/li&gt;
&lt;li&gt;&lt;u&gt;Writing &lt;/u&gt;it in newer languages.&lt;/li&gt;
&lt;li&gt;&lt;u&gt;Writing &lt;/u&gt;code using newer IDEs.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Ask any "fresher" whats so special about him and he is sure to reply that he can &lt;u&gt;write&lt;/u&gt; better code than his peers. Little does he know that &lt;i&gt;&lt;b&gt;writing code is going to be the least of his worries&lt;/b&gt;&lt;/i&gt; (for the next few years atleast).&lt;br /&gt;
&lt;br /&gt;
To drive the point home lets look at the following code-snippet:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;
for(j = 0; j &amp;lt; MAX; j++) {&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; //some&lt;br /&gt;
&amp;nbsp; &amp;nbsp; //code&lt;br /&gt;
&amp;nbsp; &amp;nbsp; //here&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; //ISSUE #xyzxyz FIX: change order&lt;br /&gt;
&amp;nbsp;&amp;nbsp; i = (j &amp;lt; 2) ? !j : j;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; switch (i) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; case 0:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //case 0 code&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; break;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; case 1:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //case 1 code&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; break;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; case 2:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //case 2 code&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; break;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; //rest of the code here&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
}&lt;/code&gt;
&lt;br /&gt;
The above snippet is what one would encounter on an average day.

Note the following line:&lt;br /&gt;
&lt;code&gt;i = (j &amp;lt; &lt;span style="color: magenta;"&gt;2&lt;/span&gt;) ? !j : j;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Can You figure out what the ISSUE could have been.&lt;br /&gt;
And how the one-liner FIX solves it... ;-)&lt;br /&gt;
&lt;br /&gt;
(more on this in later post)&lt;/div&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=yA1jDJ7lp_8:rgEgRivQRMc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=yA1jDJ7lp_8:rgEgRivQRMc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=yA1jDJ7lp_8:rgEgRivQRMc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=yA1jDJ7lp_8:rgEgRivQRMc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/yA1jDJ7lp_8" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-26T19:01:54.949+05:30</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">6</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2010/09/bachelor-of-reverse-engineering.html</feedburner:origLink></item><item><title>What is NULL?</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/K8BZLgUuH4E/what-is-null.html</link><category>Programming</category><category>Misc.</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Wed, 30 Nov 2011 07:14:46 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-6685918113197939029</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;first-char&gt;W&lt;/first-char&gt; hat is NULL? A friend of mine recently told me how this question had stumped his teacher in college and left her speechless for quite some time. Inspired by that, I posed myself the following question:&lt;br /&gt;
&lt;blockquote&gt;
Q. In not more than 10 words,&lt;br /&gt;
Define &lt;b&gt;NULL&lt;/b&gt; in the context of a programming language.&lt;/blockquote&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;And i came up with the following few answers:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Null is absolutely Nothing. Zilch.&lt;/li&gt;
&lt;li&gt;Null is something which is NOT defined.&lt;/li&gt;
&lt;li&gt;Null is the return-value of a function which has nothing to return. &lt;b&gt;†&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Null is the value of the pointer which points to nothing&lt;b&gt;. ‡&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Null is the character at the end of a string. &lt;/li&gt;
&lt;li&gt;Null is the character with ASCII-code zero.&lt;/li&gt;
&lt;li&gt; Null is a byte with all its bits set to 0.&lt;/li&gt;
&lt;/ol&gt;
If you have good observation skills then you will notice that the list starts with a very general definition and then moves on to more specific ones.&lt;br /&gt;
&lt;br /&gt;
In fact, [&lt;b&gt;1&lt;/b&gt;] &amp;amp; [&lt;b&gt;2&lt;/b&gt;] are so generic that they are applicable even in other fields (ex. Mathematics).&lt;br /&gt;
&lt;br /&gt;
[&lt;b&gt;3&lt;/b&gt;], [&lt;b&gt;4&lt;/b&gt;], [&lt;b&gt;5&lt;/b&gt;] &amp;amp; [&lt;b&gt;6&lt;/b&gt;] are NOT definitions in the true sense. Rather they are commonly found implementations (or "Use-Cases") of NULL in programming languages.&lt;br /&gt;
&lt;br /&gt;
Finally [&lt;b&gt;7&lt;/b&gt;] gives us a one-line definition of&lt;b&gt; NULL&lt;/b&gt; i.e.&lt;b&gt; &lt;i&gt;a byte with all its bits set to 0&lt;/i&gt;.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Now with reference to [&lt;b&gt;7&lt;/b&gt;] we can see that-&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Since &lt;b&gt;ASCII-code zero&lt;/b&gt; is a byte with all bits set to 0, [&lt;b&gt;6&lt;/b&gt;] is the exact same definition but just in so many other words.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;[&lt;b&gt;5&lt;/b&gt;] is NOT a definition of NULL. Rather it is a commonly found usage of NULL. One sees NULL terminated strings everywhere. It is so common that even programming-languages that do NOT have any explicit support for NULL, support &lt;a href="http://msdn.microsoft.com/en-us/library/cc230353%28PROT.10%29.aspx"&gt;&lt;b&gt;lpStrZ&lt;/b&gt;&lt;/a&gt; i.e. null-terminated-strings.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;[&lt;b&gt;4&lt;/b&gt;] mentions yet another very common usage of NULL. Pointers are usually used to pass references to data between functions. As a special "use-case" whenever the "sender" function encounters a case wherein it has no (valid) data to pass, it assigns the value NULL to the pointer thereby signaling to the "receiver" function that the pointer reference is invalid.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;[&lt;b&gt;3&lt;/b&gt;] is yet another (not so common) usage of NULL. The following line&lt;code&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #38761d;"&gt;//end of function&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;span style="color: magenta;"&gt;(&lt;/span&gt;&lt;span style="color: blue;"&gt;0&lt;/span&gt;&lt;span style="color: magenta;"&gt;)&lt;/span&gt;;&lt;br /&gt;
}&lt;/code&gt;&lt;br /&gt;
found at the end of so many common functions in any given C-code is the line that implements it. By convention, any function that completes execution successfully and has nothing to report (except for the fact that it succeeded) returns a NULL (i.e. zero in this case). In case of errors the functions usually return non-zero values which indicate the kind of error they encounter.  &lt;/li&gt;
&lt;/ul&gt;
Thus, we can clearly see that there is nothing special about NULL. It is just another name for zero. The name NULL signifies the usage the value zero is put to i.e. to state that it points-to/stands-for/holds nothing.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Further reading:&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://boredzo.org/pointers"&gt;boredzo.org/pointers&lt;/a&gt;&lt;br /&gt;
" How a function pointer can even be the return value of a function...&lt;br /&gt;
...is &lt;i&gt;really&lt;/i&gt; mind-bending, so stretch your brain a bit so as not to risk injury."&lt;/li&gt;
&lt;li&gt;&lt;a href="http://c-faq.com/null/index.html%20"&gt;c-faq.com/null/index.html &lt;/a&gt;&lt;br /&gt;
20 Qs. 20 straight answers.&lt;br /&gt;
EVERYTHING you ever wondered about NULL pointers.&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="color: black; text-align: center;"&gt;
____________ _ _ ____________&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;b&gt;† &lt;/b&gt;If your function returns some data  in some cases and no data in other cases, then define it as a non-void  function and use NULL when you have nothing to return.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;b&gt;‡&lt;/b&gt;&amp;nbsp; Once a block of memory is freed, any pointers pointing to it must be set to NULL to prevent any accidental access.&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;BONUS&lt;/b&gt;:&amp;nbsp; Here is an even more intriguing question that the one i had started with:&lt;br /&gt;
&lt;blockquote&gt;
Q. What is the data-type of NULL?&lt;br /&gt;
&lt;b&gt;Hint:&lt;/b&gt; NULL is just yet another value like 13, 3.14 or 'c'.&lt;/blockquote&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=K8BZLgUuH4E:2CZmaAjDgMk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=K8BZLgUuH4E:2CZmaAjDgMk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=K8BZLgUuH4E:2CZmaAjDgMk:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=K8BZLgUuH4E:2CZmaAjDgMk:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/K8BZLgUuH4E" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-30T20:44:46.725+05:30</app:edited><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2010/08/what-is-null.html</feedburner:origLink></item><item><title>NULL</title><link>http://feedproxy.google.com/~r/TheCodeArtist/~3/F8h7Wxo7vhw/null.html</link><category>Misc.</category><author>noreply@blogger.com (Chinmay V S)</author><pubDate>Mon, 17 Jan 2011 05:19:06 PST</pubDate><guid isPermaLink="false">tag:blogger.com,1999:blog-5879050571098780501.post-7126843310973645809</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;img alt="" class="aligncenter" height="100" src="http://3.bp.blogspot.com/_Z0O1Byloutc/TF_vDAlxXrI/AAAAAAAAAMI/hyU8klqCcSY/s1600/Empty_set.png" title="NULL" width="100" /&gt;&lt;/div&gt;&lt;blockquote&gt;In the beginning when God created the heavens and the earth,&lt;br /&gt;
the earth was a formless void...&lt;br /&gt;
&lt;br /&gt;
...Then God said, ‘Let there be light’; and there was light. -&lt;a href="http://www.amazon.com/Thru-Bible-Commentary-Vol-ebook/dp/B000SK24TM?ie=UTF8&amp;amp;tag=chi0b-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969" target="_blank"&gt;Genesis 1:1&lt;/a&gt;&lt;/blockquote&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=F8h7Wxo7vhw:otJu70_Mu4o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=F8h7Wxo7vhw:otJu70_Mu4o:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/TheCodeArtist?a=F8h7Wxo7vhw:otJu70_Mu4o:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheCodeArtist?i=F8h7Wxo7vhw:otJu70_Mu4o:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TheCodeArtist/~4/F8h7Wxo7vhw" height="1" width="1"/&gt;</description><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-17T18:49:06.069+05:30</app:edited><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_Z0O1Byloutc/TF_vDAlxXrI/AAAAAAAAAMI/hyU8klqCcSY/s72-c/Empty_set.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://thecodeartist.blogspot.com/2010/08/null.html</feedburner:origLink></item></channel></rss>
