<div id="article_details" class="details">
<div class="article_title">
<span class="ico ico_type_Original"></span>
<h1>
<span class="link_title"><a href="/silingsong/article/details/7513157">
gsensor架构和原理分析
</a></span>
</h1>
</div>
<div class="article_manage clearfix">
<div class="article_l">
<span class="link_categories">
标签:
<a href="http://www.csdn.net/tag/struct" target="_blank" οnclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">struct</a><a href="http://www.csdn.net/tag/module" target="_blank" οnclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">module</a><a href="http://www.csdn.net/tag/%e6%95%b0%e6%8d%ae%e7%bb%93%e6%9e%84" target="_blank" οnclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">数据结构</a><a href="http://www.csdn.net/tag/linux%e5%86%85%e6%a0%b8" target="_blank" οnclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">linux内核</a><a href="http://www.csdn.net/tag/methods" target="_blank" οnclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">methods</a><a href="http://www.csdn.net/tag/algorithm" target="_blank" οnclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">algorithm</a>
</span>
</div>
<div class="article_r">
<span class="link_postdate">2012-04-26 11:46</span>
<span class="link_view" title="阅读次数">12014人阅读</span>
<span class="link_comments" title="评论次数"> <a href="#comments" οnclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_pinglun'])">评论</a>(11)</span>
<span class="link_collect tracking-ad" data-mod="popu_171"> <a href="javascript:void(0);" οnclick="javascript:collectArticle('gsensor%e6%9e%b6%e6%9e%84%e5%92%8c%e5%8e%9f%e7%90%86%e5%88%86%e6%9e%90','7513157');return false;" title="收藏" target="_blank">收藏</a></span>
<span class="link_report"> <a href="#report" οnclick="javascript:report(7513157,2);return false;" title="举报">举报</a></span>
</div>
</div>
<div class="embody" style="display:none" id="embody">
<span class="embody_t">本文章已收录于:</span>
<div class="embody_c" id="lib" value="{"err":0,"msg":"ok","data":[]}"></div>
</div>
<style type="text/css">
.embody{
padding:10px 10px 10px;
margin:0 -20px;
border-bottom:solid 1px #ededed;
}
.embody_b{
margin:0 ;
padding:10px 0;
}
.embody .embody_t,.embody .embody_c{
display: inline-block;
margin-right:10px;
}
.embody_t{
font-size: 12px;
color:#999;
}
.embody_c{
font-size: 12px;
}
.embody_c img,.embody_c em{
display: inline-block;
vertical-align: middle;
}
.embody_c img{
width:30px;
height:30px;
}
.embody_c em{
margin: 0 20px 0 10px;
color:#333;
font-style: normal;
}
</style>
<script type="text/javascript">
$(function () {
try
{
var lib = eval("("+$("#lib").attr("value")+")");
var html = "";
if (lib.err == 0) {
$.each(lib.data, function (i) {
var obj = lib.data[i];
//html += '<img src="' + obj.logo + '"/>' + obj.name + " ";
html += ' <a href="' + obj.url + '" target="_blank">';
html += ' <img src="' + obj.logo + '">';
html += ' <em><b>' + obj.name + '</b></em>';
html += ' </a>';
});
if (html != "") {
setTimeout(function () {
$("#lib").html(html);
$("#embody").show();
}, 100);
}
}
} catch (err)
{ }
});
</script>
<div class="category clearfix">
<div class="category_l">
<img src="http://static.blog.csdn.net/images/category_icon.jpg">
<span>分类:</span>
</div>
<div class="category_r">
<label>
<span οnclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_fenlei']);">Android<em></em></span>
</label>
</div>
</div>
<script type="text/javascript" src="http://static.blog.csdn.net/scripts/category.js"></script>
<div class="bog_copyright">
<p class="copyright_p">版权声明:本文为博主原创文章,未经博主允许不得转载。</p>
</div>
<div style="clear:both"></div><div style="border:solid 1px #ccc; background:#eee; float:left; min-width:200px;padding:4px 10px;"><p style="text-align:right;margin:0;"><span style="float:left;">目录<a href="#" title="系统根据文章中H1到H6标签自动生成文章目录">(?)</a></span><a href="#" οnclick="javascript:return openct(this);" title="展开">[+]</a></p><ol style="display:none;margin-left:14px;padding-left:14px;line-height:160%;"><li><a href="#t0">系统架构 Architecture</a></li><ol><li><a href="#t1">1 Android体系架构图</a></li><li><a href="#t2">2 Sensor子系统架构图</a></li></ol><li><a href="#t3">应用 Applications</a></li><ol><li><a href="#t4">1 应用开发五步曲</a></li><li><a href="#t5">1 工作模型</a></li><ol><li><a href="#t6">11 SensorManager的创建</a></li><li><a href="#t7">12 SensorThread数据接收处理</a></li><li><a href="#t8">13 SensorService的工作原理</a></li><li><a href="#t9">14 SensorDevice对HAL的访问</a></li></ol></ol><li><a href="#t10">硬件抽象层 HAL</a></li><ol><li><a href="#t11">1 Sensors HAL关键流程</a></li><ol><li><a href="#t12">11 打开Sensor设备</a></li><li><a href="#t13">12 轮循Sensor事件</a></li><li><a href="#t14">21 sensors_module_t</a></li><li><a href="#t15">23 sensors_poll_context_t</a></li></ol></ol><li><a href="#t16">驱动 driver</a></li><ol><li><a href="#t17">1 mma7660驱动框架</a></li><li><a href="#t18">2 mma7660操作流程</a></li><ol><li><a href="#t19">21 初始化</a></li><li><a href="#t20"></a></li><li><a href="#t21">
</a></li><li><a href="#t22">22 探测设备</a></li><li><a href="#t23">23 移除设备</a></li><li><a href="#t24">24 采集数据</a></li><li><a href="#t25">25 睡眠和唤醒</a></li></ol><li><a href="#t26">3 命令行调试</a></li><ol><li><a href="#t27">31 sysfs调试接口</a></li></ol></ol><li><a href="#t28">Hardware</a></li><ol><li><a href="#t29">1 mma7660模组</a></li><ol><li><a href="#t30">21 功能模块图</a></li><li><a href="#t31">22 硬件连接图</a></li><li><a href="#t32">23 运动检测原理</a></li><li><a href="#t33">24 I2C读写时序</a></li><li><a href="#t34">25 工作状态机</a></li><li><a href="#t35">26 寄存器定义</a></li><li><a href="#t36">27 事件检测</a></li></ol><li><a href="#t37">
</a></li></ol></ol></div><div style="clear:both"></div><div id="article_content" class="article_content">
<p>本文主要描述了在android2.3平台G-sensor相关软硬件的体系<a href="http://lib.csdn.net/base/16" class="replace_word" title="大型网站架构知识库" target="_blank" style="color:#df3434; font-weight:bold;">架构</a>和实现原理,按照Applications、Framework、HAL、Driver和Hardware五大层次分别介绍。</p>
<h1><a name="t0"></a>1.系统架构 (Architecture)</h1>
<h2><a name="t1"></a>1.1 Android体系架构图</h2>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335408473_7586.png" alt=""><br>
</div>
<div><br>
</div>
<h2><a name="t2"></a>1.2 Sensor子系统架构图</h2>
<p><img src="https://img-my.csdn.net/uploads/201204/26/1335408479_3054.png" alt=""></p>
<p><br>
</p>
<p><span style="color:black"> </span><span style="color:black; background:white">·</span><span style="color:black; background:white"> </span><strong><span style="color:black">Application Framework</span></strong></p>
<p><span style="color:black; background:white"> </span>Sensor<span style="color:black; background:white">应用程序通过</span><span style="color:black; background:white">Sensor</span><span style="color:black; background:white">应用框架来获取</span><span style="color:black; background:white">sensor</span><span style="color:black; background:white">数据,应用框架层的</span><span style="color:black; background:white">Sensor
Manager</span><span style="color:black; background:white">通过</span><span style="color:black; background:white">JNI</span><span style="color:black; background:white">与</span><span style="color:black; background:white">C++</span><span style="color:black; background:white">层进行通信。</span></p>
<p> <span style="color:black; background:white">·</span><span style="color:black; background:white"> </span><strong><span style="color:black">Sensor Libraries</span></strong></p>
<p><span style="color:black; background:white"> </span>Sensor<span style="color:black; background:white">中间层主要由</span><span style="color:black; background:white">Sensor Manager</span><span style="color:black; background:white">、</span><span style="color:black; background:white">Sensor
service</span><span style="color:black; background:white">和</span><span style="color:black; background:white">Sensor</span><span style="color:black; background:white">硬件抽象层组成。</span></p>
<p> <span style="color:black; background:white">·</span><span style="color:black; background:white"> </span><strong><span style="color:black">Input Subsystem</span></strong></p>
<p><span style="background:white"> </span><span style="background:white">通用的</span><span style="background:white">Linux</span><span style="background:white">输入框架专为与键盘、鼠标和触摸屏等输入设备而设计,并定义了一套标准事件集合。</span><span style="background:white">Sensor</span><span style="background:white">输入子系统采用</span>采用了通用的Linux输入框架,<span style="color:black; background:white">它通过</span><span style="color:black; background:white">/sys/class/input</span><span style="color:black; background:white">节点和用户空间进行交互。</span></p>
<p> <strong><span style="color:black; background:white">·</span><span style="color:black; background:white"> </span><span style="color:black">Event Dev</span></strong></p>
<p><span style="color:black; background:white"> </span>Evdev<span style="color:black; background:white">提供了一种访问</span><span style="color:black; background:white">/dev/input/eventX</span><span style="color:black; background:white">输入设备事件的通用方法。</span></p>
<p> <strong><span style="color:black; background:white">·</span><span style="color:black; background:white"> </span><span style="color:black">AccelerometerDriver</span></strong></p>
<p><span style="background:white"> </span><span style="background:white">此驱动通过</span><span style="background:white">SIRQ</span><span style="background:white">和</span><span style="background:white">I2C</span><span style="background:white">总线与</span><span style="background:white">MMA7660</span><span style="background:white">模组进行通信。</span><span style="background:white">SIRQ</span><span style="background:white">用来产生传感器事件中断。</span></p>
<p> </p>
<h1><a name="t3"></a>2 应用 (Applications)</h1>
<h2><a name="t4"></a>2.1 应用开发五步曲</h2>
<div>
<p>(1) 获取传感器管理器对象;</p>
<p><span style="font-family:monospace; white-space:pre; background-color:rgb(240,240,240)">mSensorManager =(SensorManager) getSystemService(SENSOR_SERVICE);</span></p>
<p>(2) 获取传感器对象;</p>
<p><span style="font-family:monospace; white-space:pre; background-color:rgb(240,240,240)">mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);</span></p>
<p>(3) 定义事件监听器;</p>
<p align="left"><span style="font-family:monospace; white-space:pre; background-color:rgb(240,240,240)">mEventListener =new SensorEventListener() {</span></p>
<p></p>
<div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 838px; top: 2422px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_1" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=1&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="annotation">@Override</span><span> </span></span></li><li class=""><span>publicvoid onSensorChanged(SensorEvent event) { </span></li><li class="alt"><span> <span class="keyword">float</span><span>[] values = event.values; </span></span></li><li class=""><span> mTextView.setText(<span class="string">"Accelerometer:"</span><span> + values[</span><span class="number">0</span><span>] +</span><span class="string">", "</span><span> </span></span></li><li class="alt"><span> + values[<span class="number">1</span><span>] +</span><span class="string">", "</span><span> + values[</span><span class="number">2</span><span>]); </span></span></li><li class=""><span>} </span></li><li class="alt"><span> </span></li><li class=""><span><span class="annotation">@Override</span><span> </span></span></li><li class="alt"><span>publicvoidonAccuracyChanged(Sensor sensor,<span class="keyword">int</span><span> accuracy) { </span></span></li><li class=""><span>} </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">
@Override
publicvoid onSensorChanged(SensorEvent event) {
float[] values = event.values;
mTextView.setText("Accelerometer:" + values[0] +", "
+ values[1] +", " + values[2]);
}
@Override
publicvoidonAccuracyChanged(Sensor sensor,int accuracy) {
}
};</pre>
<p></p>
<p>(4) 注册事件监听器;</p>
<p align="left"><span style="font-family:monospace; white-space:pre; background-color:rgb(240,240,240)">protectedvoid onResume() {</span></p>
<p></p>
<div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 838px; top: 2754px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_2" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=2&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">super</span><span>.onResume(); </span></span></li><li class=""><span> </span></li><li class="alt"><span>mSensorManager.registerListener(mEventListener, mSensor, </span></li><li class=""><span> SensorManager.SENSOR_DELAY_NORMAL); </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;"> super.onResume();
mSensorManager.registerListener(mEventListener, mSensor,
SensorManager.SENSOR_DELAY_NORMAL);
}</pre>
<p></p>
<p>(5) 卸载事件监听器;</p>
<p align="left"><span style="font-family:monospace; white-space:pre; background-color:rgb(240,240,240)">protectedvoid onPause() {</span></p>
<div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 838px; top: 2978px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_3" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_3" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=3&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span> </span><span class="keyword">super</span><span>.onPause(); </span></span></li><li class=""><span> </span></li><li class="alt"><span> mSensorManager.unregisterListener(mEventListener); </span></li><li class=""><span>} </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;"> super.onPause();
mSensorManager.unregisterListener(mEventListener);
}</pre><br>
<span style="font-size:24px"><strong>3 框架 (Framework)</strong></span></div>
<h2><a name="t5"></a>3.1 工作模型</h2>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335408958_8184.png" alt=""><br>
</div>
<div><br>
</div>
<h3><a name="t6"></a>3.1.1 SensorManager的创建</h3>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335409075_5364.png" alt=""><br>
</div>
<div><br>
</div>
<div>nativeClassInit(): 初始化Native类信息;<br>
sensors_module_init(): 创建Native SensorManager实例,从SensorService读取Sensor设备列表;<br>
sensors_module_get_next_sensor(): 从SensorService读取下一个Sensor设备;<br>
</div>
<div><br>
</div>
<div>
<h3><a name="t7"></a>3.1.2 SensorThread数据接收处理</h3>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335409392_3265.png" alt=""><br>
</div>
<div><br>
</div>
<div>sensors_create_queue(): 创建和SensorService共享的消息队列;<br>
sensors_data_poll(): 从消息队列中读取SensorService发过来的消息;<br>
</div>
<div><br>
</div>
<h3><a name="t8"></a>3.1.3 SensorService的工作原理</h3>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335409293_3348.png" alt=""><br>
</div>
<div><br>
</div>
<div>SensorDevice::poll(): 调用HAL接口读取数据;<br>
SensorEventConnection::sendEvents(): 往消息队列中写入消息,SensorThread后续会读取该消息;<br>
</div>
<div><br>
</div>
<div>
<h3><a name="t9"></a>3.1.4 SensorDevice对HAL的访问</h3>
</div>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335409149_3338.png" alt=""><br>
</div>
<br>
</div>
<h1><a name="t10"></a>4 硬件抽象层 (HAL)</h1>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335409930_1255.png" alt=""><br>
</div>
<div><span style="white-space:pre"></span>在linux操作系统中,应用同硬件之间的交互都是通过设备驱动来实现,Android系统为了降低应用开发人员开发难度,屏蔽硬件差异,定义出硬件抽象层,为开发人员提供获取各种设备相关的信息的接口。<br>
</div>
<h2><a name="t11"></a>4.1 Sensors HAL关键流程</h2>
<h3><a name="t12"></a>4.1.1 打开Sensor设备</h3>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335409941_9605.png" alt=""><br>
</div>
<div>SensorBase ::openInput() : 打开input子系统的sensor消息文件句柄;<br>
ioctl(EVIOCGABS(...)) : 获取ABS_X/ABS_Y/ABS_Z的加速度;<br>
</div>
<div><br>
</div>
<div>
<h3><a name="t13"></a>4.1.2 轮循Sensor事件</h3>
</div>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335409958_1800.png" alt=""><br>
</div>
<div>InputEventCircularReader::fill(): 调用read()从input子系统中读取事件放入环形缓冲区;<br>
InputEventCircularReader::readEvent(): 从环形缓冲区中读取事件;<br>
InputEventCircularReader::next(): 移动环形缓冲区当前指针;<br>
</div>
<div><span style="font-size:18px"><strong><br>
</strong></span></div>
<div><span style="font-size:18px"><strong>5.2 Sensors HAL关键数据结构</strong></span></div>
<h3><a name="t14"></a>5.2.1 sensors_module_t</h3>
<div><div class="dp-highlighter bg_cpp"><div class="bar"><div class="tools"><b>[cpp]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 832px; top: 7280px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_4" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_4" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=4&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-cpp"><li class="alt"><span><span class="keyword">struct</span><span> sensors_module_t { </span></span></li><li class=""><span> <span class="keyword">struct</span><span> hw_module_t common; </span></span></li><li class="alt"><span> </span></li><li class=""><span> <span class="comment">/**</span> </span></li><li class="alt"><span><span class="comment"> * Enumerate all available sensors. The list is returned in "list".</span> </span></li><li class=""><span><span class="comment"> * @return number of sensors in the list</span> </span></li><li class="alt"><span><span class="comment"> */</span><span> </span></span></li><li class=""><span> <span class="datatypes">int</span><span> (*get_sensors_list)(</span><span class="keyword">struct</span><span> sensors_module_t* module, </span></span></li><li class="alt"><span> <span class="keyword">struct</span><span> sensor_t </span><span class="keyword">const</span><span>** list); </span></span></li><li class=""><span>}; </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="cpp" style="display: none;">struct sensors_module_t {
struct hw_module_t common;
/**
* Enumerate all available sensors. The list is returned in "list".
* @return number of sensors in the list
*/
int (*get_sensors_list)(struct sensors_module_t* module,
struct sensor_t const** list);
};
</pre><br>
hw_get_module()会加载HAL模块,并返回HAL入口数据结构(hw_module_t)。HAL_MODULE_INFO_SYM默认是“HAL”,在hw_get_module中用dlsym获取。</div>
<div><div class="dp-highlighter bg_cpp"><div class="bar"><div class="tools"><b>[cpp]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 832px; top: 7624px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_5" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_5" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=5&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-cpp"><li class="alt"><span><span class="keyword">const</span><span> </span><span class="keyword">struct</span><span> sensors_module_t HAL_MODULE_INFO_SYM = { </span></span></li><li class=""><span> .common = { </span></li><li class="alt"><span> .tag = HARDWARE_MODULE_TAG, </span></li><li class=""><span> .version_major = 1, </span></li><li class="alt"><span> .version_minor = 0, </span></li><li class=""><span> .id = SENSORS_HARDWARE_MODULE_ID, </span></li><li class="alt"><span> .name = <span class="string">"MMA7660 Sensors Module"</span><span>, </span></span></li><li class=""><span> .author = <span class="string">"The Android Open Source Project"</span><span>, </span></span></li><li class="alt"><span> .methods = &sensors_module_methods, </span></li><li class=""><span> }, </span></li><li class="alt"><span> .get_sensors_list = sensors__get_sensors_list </span></li><li class=""><span>}; </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="cpp" style="display: none;">const struct sensors_module_t HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.version_major = 1,
.version_minor = 0,
.id = SENSORS_HARDWARE_MODULE_ID,
.name = "MMA7660 Sensors Module",
.author = "The Android Open Source Project",
.methods = &sensors_module_methods,
},
.get_sensors_list = sensors__get_sensors_list
};
</pre><br>
<span style="font-size:14px"><strong>5.2.2 hw_module_methods_t</strong></span></div>
<div> <span style="font-family:monospace; white-space:pre; background-color:rgb(240,240,240)">static struct hw_module_methods_t sensors_module_methods = {</span><div class="dp-highlighter bg_cpp"><div class="bar"><div class="tools"><b>[cpp]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 832px; top: 8004px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_6" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_6" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=6&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-cpp"><li class="alt"><span><span>.open = open_sensors </span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="cpp" style="display: none;"> .open = open_sensors
};
</pre>
<h3><a name="t15"></a>5.2.3 sensors_poll_context_t</h3>
<div><div class="dp-highlighter bg_cpp"><div class="bar"><div class="tools"><b>[cpp]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 832px; top: 8134px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_7" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_7" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=7&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-cpp"><li class="alt"><span><span class="keyword">struct</span><span> sensors_poll_context_t { </span></span></li><li class=""><span> <span class="keyword">struct</span><span> sensors_poll_device_t device; </span><span class="comment">// must be first</span><span> </span></span></li><li class="alt"><span> sensors_poll_context_t(); </span></li><li class=""><span> ~sensors_poll_context_t(); </span></li><li class="alt"><span> <span class="datatypes">int</span><span> activate(</span><span class="datatypes">int</span><span> handle, </span><span class="datatypes">int</span><span> enabled); </span></span></li><li class=""><span> <span class="datatypes">int</span><span> setDelay(</span><span class="datatypes">int</span><span> handle, int64_t ns); </span></span></li><li class="alt"><span> <span class="datatypes">int</span><span> pollEvents(sensors_event_t* data, </span><span class="datatypes">int</span><span> count); </span></span></li><li class=""><span> <span class="datatypes">int</span><span> handleToDriver(</span><span class="datatypes">int</span><span> handle); </span></span></li><li class="alt"><span>}; </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="cpp" style="display: none;">struct sensors_poll_context_t {
struct sensors_poll_device_t device; // must be first
sensors_poll_context_t();
~sensors_poll_context_t();
int activate(int handle, int enabled);
int setDelay(int handle, int64_t ns);
int pollEvents(sensors_event_t* data, int count);
int handleToDriver(int handle);
};
</pre><br>
<span style="font-size:14px"><strong>5.2.4 sensors_poll_device_t</strong></span><span style="font-size:14px"><strong></strong></span></div>
<div><br>
</div>
<div><div class="dp-highlighter bg_cpp"><div class="bar"><div class="tools"><b>[cpp]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 832px; top: 8460px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_8" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_8" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=8&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-cpp"><li class="alt"><span><span class="keyword">struct</span><span> sensors_poll_device_t { </span></span></li><li class=""><span><span class="keyword">struct</span><span> hw_device_t common; </span></span></li><li class="alt"><span> </span></li><li class=""><span> <span class="datatypes">int</span><span> (*activate)(</span><span class="keyword">struct</span><span> sensors_poll_device_t *dev, </span></span></li><li class="alt"><span> <span class="datatypes">int</span><span> handle, </span><span class="datatypes">int</span><span> enabled); </span></span></li><li class=""><span> </span></li><li class="alt"><span> <span class="datatypes">int</span><span> (*setDelay)(</span><span class="keyword">struct</span><span> sensors_poll_device_t *dev, </span></span></li><li class=""><span> <span class="datatypes">int</span><span> handle, int64_t ns); </span></span></li><li class="alt"><span> </span></li><li class=""><span> <span class="datatypes">int</span><span> (*poll)(</span><span class="keyword">struct</span><span> sensors_poll_device_t *dev, </span></span></li><li class="alt"><span> sensors_event_t* data, <span class="datatypes">int</span><span> count); </span></span></li><li class=""><span>}; </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="cpp" style="display: none;">struct sensors_poll_device_t {
struct hw_device_t common;
int (*activate)(struct sensors_poll_device_t *dev,
int handle, int enabled);
int (*setDelay)(struct sensors_poll_device_t *dev,
int handle, int64_t ns);
int (*poll)(struct sensors_poll_device_t *dev,
sensors_event_t* data, int count);
};
</pre><br>
<span style="font-size:14px"><strong>5.2.5 sensor_t</strong></span></div>
<span style="white-space:pre"></span>定义传感器的基本参数。<br>
</div>
<div><div class="dp-highlighter bg_cpp"><div class="bar"><div class="tools"><b>[cpp]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 832px; top: 8840px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_9" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_9" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=9&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-cpp"><li class="alt"><span><span class="keyword">static</span><span> </span><span class="keyword">const</span><span> </span><span class="keyword">struct</span><span> sensor_t sSensorList[] = { </span></span></li><li class=""><span> { <span class="string">"MMA7660 3-axis Accelerometer"</span><span>, </span></span></li><li class="alt"><span> <span class="string">"Freescale Semiconductor"</span><span>, </span></span></li><li class=""><span> 1, SENSORS_HANDLE_BASE+ID_A, </span></li><li class="alt"><span> SENSOR_TYPE_ACCELEROMETER, 3.0f*9.81f, (3.0f*9.81f)/64.0f, 0.35f, 0, { } }, </span></li><li class=""><span>}; </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="cpp" style="display: none;">static const struct sensor_t sSensorList[] = {
{ "MMA7660 3-axis Accelerometer",
"Freescale Semiconductor",
1, SENSORS_HANDLE_BASE+ID_A,
SENSOR_TYPE_ACCELEROMETER, 3.0f*9.81f, (3.0f*9.81f)/64.0f, 0.35f, 0, { } },
};
</pre><div class="dp-highlighter bg_cpp"><div class="bar"><div class="tools"><b>[cpp]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 832px; top: 9016px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_10" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_10" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=10&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-cpp"><li class="alt"><span><span class="keyword">struct</span><span> sensor_t { </span></span></li><li class=""><span> <span class="keyword">const</span><span> </span><span class="datatypes">char</span><span>* name; </span></span></li><li class="alt"><span> <span class="keyword">const</span><span> </span><span class="datatypes">char</span><span>* vendor; </span></span></li><li class=""><span> <span class="datatypes">int</span><span> version; </span></span></li><li class="alt"><span> <span class="datatypes">int</span><span> handle; </span></span></li><li class=""><span> <span class="datatypes">int</span><span> type; </span></span></li><li class="alt"><span> <span class="datatypes">float</span><span> maxRange; </span></span></li><li class=""><span> <span class="datatypes">float</span><span> resolution; </span></span></li><li class="alt"><span> <span class="datatypes">float</span><span> power; </span></span></li><li class=""><span> int32_t minDelay; </span></li><li class="alt"><span> <span class="keyword">void</span><span>* reserved[8]; </span></span></li><li class=""><span>}; </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="cpp" style="display: none;">struct sensor_t {
const char* name;
const char* vendor;
int version;
int handle;
int type;
float maxRange;
float resolution;
float power;
int32_t minDelay;
void* reserved[8];
};
</pre><br>
<br>
<h1><a name="t16"></a>6 驱动 (driver)</h1>
</div>
<h2><a name="t17"></a>6.1 mma7660驱动框架</h2>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335411209_2029.png" alt=""><br>
</div>
<div>mma7660与主机通信是通过I2C接口,因此mma7660驱动程序采用Linux系统的I2C子系统框架来实现,主要由3部分组成:</div>
<div> <br>
(1)<span style="white-space:pre"> </span>I2C核心<br>
<span style="white-space:pre"></span>I2C核心提供了I2C总线驱动和设备驱动的注册、注销方法,I2C通信方法(即“algorithm”)上层的、与具体适配器无关的代码以及探测设备、检测设备地址的上层代码等。这部分是与平台无关的。<br>
<span style="white-space:pre"></span>此部分在Linux内核的I2C驱动中实现,mma7660驱动使用其提供的功能接口来注册设备驱动。<br>
<br>
(2)<span style="white-space:pre"> </span>I2C总线驱动<br>
<span style="white-space:pre"></span>I2C总线驱动是对I2C硬件体系结构中适配器端的实现。I2C总线驱动主要包含了I2C适配器数据结构i2c_adapter、I2C适配器的algorithm数据结构i2c_algorithm和控制I2C适配器产生通信信号的函数。经由I2C总线驱动的代码,我们可以控制I2C适配器以主控方式产生开始位、停止位、读写周期,以及以从设备方式被读写、产生ACK等。不同的CPU平台对应着不同的I2C总线驱动。<br>
<span style="white-space:pre"></span>此部分在Linux内核的I2C驱动中实现,mma7660驱动直接获取其提供的adapter,并调用I2C核心的接口来注册。<br>
<br>
(3)<span style="white-space:pre"> </span>I2C设备驱动<br>
<span style="white-space:pre"></span>I2C设备驱动是对I2C硬件体系结构中设备端的实现。设备一般挂接在受CPU控制的I2C适配器上,通过I2C适配器与CPU交换数据。I2C设备驱动主要包含了数据结构i2c_driver和i2c_client,mma7660驱动需要实现其中的成员函数。<br>
<span style="white-space:pre"></span>在Linux内核源代码中的drivers目录下的i2c_dev.c文件,实现了I2C适配器设备文件的功能,应用程序通过“i2c-%d”文件名并使用文件操作接口open()、write()、read()、ioctl()和close()等来访问这个设备。应用层可以借用这些接口访问挂接在适配器上的I2C设备的存储空间或寄存器并控制I2C设备的工作方式。<br>
<br>
<h2><a name="t18"></a>6.2 mma7660操作流程</h2>
<h3><a name="t19"></a>6.2.1 初始化</h3>
<h3><a name="t20"></a><img src="https://img-my.csdn.net/uploads/201204/26/1335411221_5705.png" alt=""></h3>
<h3><a name="t21"></a><br>
</h3>
<h3><a name="t22"></a><span style="font-size:14px">6.2.2 探测设备</span></h3>
<div><span style="font-size:14px"><img src="https://img-my.csdn.net/uploads/201204/26/1335411232_5590.png" alt=""><br>
</span></div>
<div><span style="font-size:14px"><br>
</span></div>
<h3><a name="t23"></a>6.2.3 移除设备</h3>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335411240_4819.png" alt=""><br>
</div>
<div><br>
</div>
<h3><a name="t24"></a>6.2.4 采集数据</h3>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335411249_3082.png" alt=""><br>
</div>
<div><br>
</div>
<h3><a name="t25"></a>6.2.5 睡眠和唤醒</h3>
<span style="white-space:pre"></span>Suspend处理:关闭mma7660模组;<br>
<span style="white-space:pre"></span>Resume处理:使能mma7660模组;<br>
<div class="dp-highlighter bg_cpp"><div class="bar"><div class="tools"><b>[cpp]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 832px; top: 13520px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_11" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_11" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=11&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-cpp"><li class="alt"><span><span class="keyword">static</span><span> </span><span class="datatypes">int</span><span> mma7660_suspend(</span><span class="keyword">struct</span><span> i2c_client *client, pm_message_t mesg) </span></span></li><li class=""><span>{ </span></li><li class="alt"><span> <span class="datatypes">int</span><span> result; </span></span></li><li class=""><span>result = i2c_smbus_write_byte_data(client, MMA7660_MODE, </span></li><li class="alt"><span> MK_MMA7660_MODE(0, 0, 0, 0, 0, 0, 0)); </span></li><li class=""><span> assert(result==0); </span></li><li class="alt"><span> <span class="keyword">return</span><span> result; </span></span></li><li class=""><span>} </span></li><li class="alt"><span> </span></li><li class=""><span><span class="keyword">static</span><span> </span><span class="datatypes">int</span><span> mma7660_resume(</span><span class="keyword">struct</span><span> i2c_client *client) </span></span></li><li class="alt"><span>{ </span></li><li class=""><span> <span class="datatypes">int</span><span> result; </span></span></li><li class="alt"><span>result = i2c_smbus_write_byte_data(client, MMA7660_MODE, </span></li><li class=""><span> MK_MMA7660_MODE(0, 1, 0, 0, 0, 0, 1)); </span></li><li class="alt"><span> assert(result==0); </span></li><li class=""><span> <span class="keyword">return</span><span> result; </span></span></li><li class="alt"><span>} </span></li><li class=""><span> </span></li><li class="alt"><span><span class="keyword">static</span><span> </span><span class="keyword">struct</span><span> i2c_driver mma7660_driver = { </span></span></li><li class=""><span> .driver = { </span></li><li class="alt"><span> .name = MMA7660_DRV_NAME, </span></li><li class=""><span> .owner = THIS_MODULE, </span></li><li class="alt"><span> }, </span></li><li class=""><span> .<span class="keyword">class</span><span> = I2C_CLASS_HWMON, </span></span></li><li class="alt"><span> .suspend = mma7660_suspend, </span></li><li class=""><span> .resume = mma7660_resume, </span></li><li class="alt"><span> .probe = mma7660_probe, </span></li><li class=""><span> .detect = mma7660_detect, </span></li><li class="alt"><span><span class="comment">// .address_data = &addr_data,</span><span> </span></span></li><li class=""><span> .remove = __devexit_p(mma7660_remove), </span></li><li class="alt"><span> .id_table = mma7660_id, </span></li><li class=""><span>}; </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="cpp" style="display: none;">static int mma7660_suspend(struct i2c_client *client, pm_message_t mesg)
{
int result;
result = i2c_smbus_write_byte_data(client, MMA7660_MODE,
MK_MMA7660_MODE(0, 0, 0, 0, 0, 0, 0));
assert(result==0);
return result;
}
static int mma7660_resume(struct i2c_client *client)
{
int result;
result = i2c_smbus_write_byte_data(client, MMA7660_MODE,
MK_MMA7660_MODE(0, 1, 0, 0, 0, 0, 1));
assert(result==0);
return result;
}
static struct i2c_driver mma7660_driver = {
.driver = {
.name = MMA7660_DRV_NAME,
.owner = THIS_MODULE,
},
.class = I2C_CLASS_HWMON,
.suspend = mma7660_suspend,
.resume = mma7660_resume,
.probe = mma7660_probe,
.detect = mma7660_detect,
// .address_data = &addr_data,
.remove = __devexit_p(mma7660_remove),
.id_table = mma7660_id,
};
</pre>
<h2><a name="t26"></a>6.3 命令行调试</h2>
<h3><a name="t27"></a>6.3.1 sysfs调试接口</h3>
(1)<span style="white-space:pre"> </span>定义sysfs attribute相关数据结构;<br>
<div class="dp-highlighter bg_cpp"><div class="bar"><div class="tools"><b>[cpp]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 832px; top: 14286px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_12" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_12" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=12&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-cpp"><li class="alt"><span><span class="keyword">static</span><span> SENSOR_DEVICE_ATTR(all_axis_force, S_IRUGO, show_xyz_force, NULL, 0); </span></span></li><li class=""><span><span class="keyword">static</span><span> SENSOR_DEVICE_ATTR(x_axis_force, S_IRUGO, show_axis_force, NULL, 0); </span></span></li><li class="alt"><span><span class="keyword">static</span><span> SENSOR_DEVICE_ATTR(y_axis_force, S_IRUGO, show_axis_force, NULL, 1); </span></span></li><li class=""><span><span class="keyword">static</span><span> SENSOR_DEVICE_ATTR(z_axis_force, S_IRUGO, show_axis_force, NULL, 2); </span></span></li><li class="alt"><span><span class="keyword">static</span><span> SENSOR_DEVICE_ATTR(orientation, S_IRUGO, show_orientation, NULL, 0); </span></span></li><li class=""><span> </span></li><li class="alt"><span><span class="keyword">static</span><span> </span><span class="keyword">struct</span><span> attribute* mma7660_attrs[] = </span></span></li><li class=""><span>{ </span></li><li class="alt"><span> &sensor_dev_attr_all_axis_force.dev_attr.attr, </span></li><li class=""><span> &sensor_dev_attr_x_axis_force.dev_attr.attr, </span></li><li class="alt"><span> &sensor_dev_attr_y_axis_force.dev_attr.attr, </span></li><li class=""><span> &sensor_dev_attr_z_axis_force.dev_attr.attr, </span></li><li class="alt"><span> &sensor_dev_attr_orientation.dev_attr.attr, </span></li><li class=""><span> NULL </span></li><li class="alt"><span>}; </span></li><li class=""><span> </span></li><li class="alt"><span><span class="keyword">static</span><span> </span><span class="keyword">const</span><span> </span><span class="keyword">struct</span><span> attribute_group mma7660_group = </span></span></li><li class=""><span>{ </span></li><li class="alt"><span> .attrs = mma7660_attrs, </span></li><li class=""><span>}; </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="cpp" style="display: none;">static SENSOR_DEVICE_ATTR(all_axis_force, S_IRUGO, show_xyz_force, NULL, 0);
static SENSOR_DEVICE_ATTR(x_axis_force, S_IRUGO, show_axis_force, NULL, 0);
static SENSOR_DEVICE_ATTR(y_axis_force, S_IRUGO, show_axis_force, NULL, 1);
static SENSOR_DEVICE_ATTR(z_axis_force, S_IRUGO, show_axis_force, NULL, 2);
static SENSOR_DEVICE_ATTR(orientation, S_IRUGO, show_orientation, NULL, 0);
static struct attribute* mma7660_attrs[] =
{
&sensor_dev_attr_all_axis_force.dev_attr.attr,
&sensor_dev_attr_x_axis_force.dev_attr.attr,
&sensor_dev_attr_y_axis_force.dev_attr.attr,
&sensor_dev_attr_z_axis_force.dev_attr.attr,
&sensor_dev_attr_orientation.dev_attr.attr,
NULL
};
static const struct attribute_group mma7660_group =
{
.attrs = mma7660_attrs,
};
</pre><br>
<br>
(2)<span style="white-space:pre"> </span>在probe函数中创建sysfs文件系统;<br>
<div class="dp-highlighter bg_cpp"><div class="bar"><div class="tools"><b>[cpp]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 832px; top: 14836px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_13" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_13" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=13&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-cpp"><li class="alt"><span><span>result = sysfs_create_group(&client->dev.kobj, &mma7660_group); </span></span></li><li class=""><span><span class="keyword">if</span><span> (result != 0) { </span></span></li><li class="alt"><span> ERR(<span class="string">"sysfs_create_group err\n"</span><span>); </span></span></li><li class=""><span> <span class="keyword">goto</span><span> exit_sysfs_creat_failed; </span></span></li><li class="alt"><span>} </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="cpp" style="display: none;"> result = sysfs_create_group(&client->dev.kobj, &mma7660_group);
if (result != 0) {
ERR("sysfs_create_group err\n");
goto exit_sysfs_creat_failed;
}
</pre><br>
<br>
(3)<span style="white-space:pre"> </span>实现sysfs属性相关的读写函数;<br>
<div class="dp-highlighter bg_cpp"><div class="bar"><div class="tools"><b>[cpp]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 832px; top: 15090px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_14" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_14" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=14&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-cpp"><li class="alt"><span><span>ssize_t show_orientation(</span><span class="keyword">struct</span><span> device *dev, </span><span class="keyword">struct</span><span> device_attribute *attr, </span><span class="datatypes">char</span><span> *buf) </span></span></li><li class=""><span>{ </span></li><li class="alt"><span> <span class="datatypes">int</span><span> result; </span></span></li><li class=""><span>u8 tilt, new_orientation; </span></li><li class="alt"><span> </span></li><li class=""><span> mma7660_read_tilt(&tilt); </span></li><li class="alt"><span> DBG(<span class="string">"tilt [0x%x]\n"</span><span>, tilt); </span></span></li><li class=""><span> new_orientation = tilt & 0x1f; </span></li><li class="alt"><span> <span class="keyword">if</span><span> (orientation!=new_orientation) </span></span></li><li class=""><span> orientation = new_orientation; </span></li><li class="alt"><span> </span></li><li class=""><span> <span class="keyword">switch</span><span> ((orientation>>2)&0x07) { </span></span></li><li class="alt"><span> <span class="keyword">case</span><span> 1: </span></span></li><li class=""><span> result = sprintf(buf, <span class="string">"Left\n"</span><span>); </span></span></li><li class="alt"><span> <span class="keyword">break</span><span>; </span></span></li><li class=""><span> <span class="keyword">case</span><span> 2: </span></span></li><li class="alt"><span> result = sprintf(buf, <span class="string">"Right\n"</span><span>); </span></span></li><li class=""><span> <span class="keyword">break</span><span>; </span></span></li><li class="alt"><span> <span class="keyword">case</span><span> 5: </span></span></li><li class=""><span> result = sprintf(buf, <span class="string">"Downward\n"</span><span>); </span></span></li><li class="alt"><span> <span class="keyword">break</span><span>; </span></span></li><li class=""><span> <span class="keyword">case</span><span> 6: </span></span></li><li class="alt"><span> result = sprintf(buf, <span class="string">"Upward\n"</span><span>); </span></span></li><li class=""><span> <span class="keyword">break</span><span>; </span></span></li><li class="alt"><span> <span class="keyword">default</span><span>: </span></span></li><li class=""><span> <span class="keyword">switch</span><span>(orientation & 0x03) { </span></span></li><li class="alt"><span> <span class="keyword">case</span><span> 1: </span></span></li><li class=""><span> result = sprintf(buf, <span class="string">"Front\n"</span><span>); </span></span></li><li class="alt"><span> <span class="keyword">break</span><span>; </span></span></li><li class=""><span> <span class="keyword">case</span><span> 2: </span></span></li><li class="alt"><span> result = sprintf(buf, <span class="string">"Back\n"</span><span>); </span></span></li><li class=""><span> <span class="keyword">break</span><span>; </span></span></li><li class="alt"><span> <span class="keyword">default</span><span>: </span></span></li><li class=""><span> result = sprintf(buf, <span class="string">"Unknown\n"</span><span>); </span></span></li><li class="alt"><span> } </span></li><li class=""><span> } </span></li><li class="alt"><span> <span class="keyword">return</span><span> result; </span></span></li><li class=""><span>} </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="cpp" style="display: none;">ssize_t show_orientation(struct device *dev, struct device_attribute *attr, char *buf)
{
int result;
u8 tilt, new_orientation;
mma7660_read_tilt(&tilt);
DBG("tilt [0x%x]\n", tilt);
new_orientation = tilt & 0x1f;
if (orientation!=new_orientation)
orientation = new_orientation;
switch ((orientation>>2)&0x07) {
case 1:
result = sprintf(buf, "Left\n");
break;
case 2:
result = sprintf(buf, "Right\n");
break;
case 5:
result = sprintf(buf, "Downward\n");
break;
case 6:
result = sprintf(buf, "Upward\n");
break;
default:
switch(orientation & 0x03) {
case 1:
result = sprintf(buf, "Front\n");
break;
case 2:
result = sprintf(buf, "Back\n");
break;
default:
result = sprintf(buf, "Unknown\n");
}
}
return result;
}
</pre><div class="dp-highlighter bg_cpp"><div class="bar"><div class="tools"><b>[cpp]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 832px; top: 15842px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_15" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_15" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=15&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1" class="dp-cpp"><li class="alt"><span><span>ssize_t show_xyz_force(</span><span class="keyword">struct</span><span> device *dev, </span><span class="keyword">struct</span><span> device_attribute *attr, </span><span class="datatypes">char</span><span> *buf) </span></span></li><li class=""><span>{ </span></li><li class="alt"><span> <span class="datatypes">int</span><span> i; </span></span></li><li class=""><span> s8 xyz[3]; </span></li><li class="alt"><span> </span></li><li class=""><span> <span class="keyword">for</span><span> (i=0; i<3; i++) </span></span></li><li class="alt"><span> mma7660_read_xyz(i, &xyz[i]); </span></li><li class=""><span> </span></li><li class="alt"><span> <span class="keyword">return</span><span> sprintf(buf, </span><span class="string">"(%d,%d,%d)\n"</span><span>, xyz[0], xyz[1], xyz[2]); </span></span></li><li class=""><span>} </span></li><li class="alt"><span> </span></li><li class=""><span>ssize_t show_axis_force(<span class="keyword">struct</span><span> device *dev, </span><span class="keyword">struct</span><span> device_attribute *attr, </span><span class="datatypes">char</span><span> *buf) </span></span></li><li class="alt"><span>{ </span></li><li class=""><span> s8 force; </span></li><li class="alt"><span> <span class="datatypes">int</span><span> n = to_sensor_dev_attr(attr)->index; </span></span></li><li class=""><span> </span></li><li class="alt"><span>mma7660_read_xyz(n, &force); </span></li><li class=""><span> </span></li><li class="alt"><span> <span class="keyword">return</span><span> sprintf(buf, </span><span class="string">"%d\n"</span><span>, force); </span></span></li><li class=""><span>} </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="cpp" style="display: none;">ssize_t show_xyz_force(struct device *dev, struct device_attribute *attr, char *buf)
{
int i;
s8 xyz[3];
for (i=0; i<3; i++)
mma7660_read_xyz(i, &xyz[i]);
return sprintf(buf, "(%d,%d,%d)\n", xyz[0], xyz[1], xyz[2]);
}
ssize_t show_axis_force(struct device *dev, struct device_attribute *attr, char *buf)
{
s8 force;
int n = to_sensor_dev_attr(attr)->index;
mma7660_read_xyz(n, &force);
return sprintf(buf, "%d\n", force);
}
</pre><br>
<span style="font-size:14px"><strong>6.3.2 Gsensor调试实例</strong></span><br>
<div class="dp-highlighter bg_plain"><div class="bar"><div class="tools"><b>[plain]</b> <a href="#" class="ViewSource" title="view plain" οnclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" οnclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy</a><div style="position: absolute; left: 841px; top: 16340px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_16" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_16" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=16&width=18&height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="#" class="PrintSource" title="print" οnclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" οnclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol start="1"><li class="alt"><span><span>/sys/devices/platform/gl5201-i2c.1/i2c-1/1-004c # ls </span></span></li><li class=""><span>uevent </span></li><li class="alt"><span>name </span></li><li class=""><span>modalias </span></li><li class="alt"><span>subsystem </span></li><li class=""><span>power </span></li><li class="alt"><span>driver </span></li><li class=""><span>all_axis_force </span></li><li class="alt"><span>x_axis_force </span></li><li class=""><span>y_axis_force </span></li><li class="alt"><span>z_axis_force </span></li><li class=""><span>orientation </span></li><li class="alt"><span>input </span></li><li class=""><span>/sys/devices/platform/gl5201-i2c.1/i2c-1/1-004c # cat all_axis_force </span></li><li class="alt"><span>(-1,0,22) </span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div></div><pre name="code" class="plain" style="display: none;">/sys/devices/platform/gl5201-i2c.1/i2c-1/1-004c # ls
uevent
name
modalias
subsystem
power
driver
all_axis_force
x_axis_force
y_axis_force
z_axis_force
orientation
input
/sys/devices/platform/gl5201-i2c.1/i2c-1/1-004c # cat all_axis_force
(-1,0,22)
</pre>
<div><br>
</div>
<h1><a name="t28"></a>7 Hardware</h1>
<h2><a name="t29"></a>7.1 mma7660模组</h2>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335411959_8661.png" alt=""><br>
</div>
<div><span style="font-size:18px; white-space:pre"><strong>7.2 关键特性</strong></span></div>
<ul>
<li>Sampling Resolution: 6bit</li><li>Digital Output (I2C)</li><li>3mm x 3mm x 0.9mm DFN Package</li><li>Low Power Current Consumption: </li></ul>
<span style="white-space:pre"></span>Off Mode: 0.4 μA,<br>
<span style="white-space:pre"></span>Standby Mode: 2 μA, <br>
<span style="white-space:pre"></span>Active Mode: 47 μA at 1 ODR<br>
<ul>
<li>Configurable Samples per Second from 1 to 120 samples</li><li>Low Voltage Operation:</li></ul>
<span style="white-space:pre"></span>Analog Voltage: 2.4 V - 3.6 V<br>
<span style="white-space:pre"></span>Digital Voltage: 1.71 V - 3.6 V<br>
<ul>
<li>Auto-Wake/Sleep Feature for Low Power Consumption</li><li>Tilt Orientation Detection for Portrait/Landscape Capability</li><li>Gesture Detection Including Shake Detection and Tap Detection</li></ul>
<h3><a name="t30"></a>7.2.1 功能模块图</h3>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335411971_3727.png" alt=""><br>
</div>
<h3><a name="t31"></a>7.2.2 硬件连接图</h3>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335411990_5457.png" alt=""><br>
</div>
<h3><a name="t32"></a>7.2.3 运动检测原理</h3>
<div><span style="white-space:pre"></span>mma7660是一种电容式3轴g-sensor,其技术原理是在wafer的表面做出梳状结构,当产生动作时,由侦测电容差来判断变形量,反推出加速度的值。<br>
<span style="white-space:pre"></span>简单物理模型如下图:<br>
</div>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335412001_7062.png" alt=""><br>
</div>
<h3><a name="t33"></a>7.2.4 I2C读写时序</h3>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335412010_2840.png" alt=""><br>
</div>
<h3><a name="t34"></a>7.2.5 工作状态机</h3>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335412020_2893.png" alt=""><br>
</div>
<h3><a name="t35"></a>7.2.6 寄存器定义</h3>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335412030_4499.png" alt=""><br>
</div>
<h3><a name="t36"></a>7.2.7 事件检测</h3>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335412039_2123.png" alt=""><br>
</div>
<ul>
<li>方向和摇动检测 </li></ul>
<div><img src="https://img-my.csdn.net/uploads/201204/26/1335412045_9908.png" alt=""><br>
</div>
<ul>
<li>轻拍或倾斜检测</li></ul>
<img src="https://img-my.csdn.net/uploads/201204/26/1335412050_2213.png" alt=""><br>
<br>
<br>
<br>
<br>
</div>
<h2><a name="t37"></a>
<p align="center"></p>
</h2>
</div>
<!-- Baidu Button BEGIN -->
<div class="bdsharebuttonbox tracking-ad bdshare-button-style0-16" style="float: right;" data-mod="popu_172" data-bd-bind="1484191853351">
<a href="#" class="bds_more" data-cmd="more" style="background-position:0 0 !important; background-image: url(http://bdimg.share.baidu.com/static/api/img/share/icons_0_16.png?v=d754dcc0.png) !important" target="_blank"></a>
<a href="#" class="bds_qzone" data-cmd="qzone" title="分享到QQ空间" style="background-position:0 -52px !important" target="_blank"></a>
<a href="#" class="bds_tsina" data-cmd="tsina" title="分享到新浪微博" style="background-position:0 -104px !important" target="_blank"></a>
<a href="#" class="bds_tqq" data-cmd="tqq" title="分享到腾讯微博" style="background-position:0 -260px !important" target="_blank"></a>
<a href="#" class="bds_renren" data-cmd="renren" title="分享到人人网" style="background-position:0 -208px !important" target="_blank"></a>
<a href="#" class="bds_weixin" data-cmd="weixin" title="分享到微信" style="background-position:0 -1612px !important" target="_blank"></a>
</div>
<script>window._bd_share_config = { "common": { "bdSnsKey": {}, "bdText": "", "bdMini": "1", "bdMiniList": false, "bdPic": "", "bdStyle": "0", "bdSize": "16" }, "share": {} }; with (document) 0[(getElementsByTagName('head')[0] || body).appendChild(createElement('script')).src = 'http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion=' + ~(-new Date() / 36e5)];</script>
<!-- Baidu Button END -->
<link rel="stylesheet" href="http://static.blog.csdn.net/css/blog_detail.css">
<!--172.16.140.11-->
<!-- Baidu Button BEGIN -->
<script type="text/javascript" id="bdshare_js" data="type=tools&uid=1536434" src="http://bdimg.share.baidu.com/static/js/bds_s_v2.js?cdnversion=412276"></script>
<script type="text/javascript">
document.getElementById("bdshell_js").src = "http://bdimg.share.baidu.com/static/js/shell_v2.js?cdnversion=" + Math.ceil(new Date()/3600000)
</script>
<!-- Baidu Button END -->
<div id="digg" articleid="7513157">
<dl id="btnDigg" class="digg digg_enable" οnclick="btndigga();">
<dt>顶</dt>
<dd>2</dd>
</dl>
<dl id="btnBury" class="digg digg_enable" οnclick="btnburya();">
<dt>踩</dt>
<dd>0</dd>
</dl>
</div>
<div class="tracking-ad" data-mod="popu_222"><a href="javascript:void(0);" target="_blank"> </a> </div>
<div class="tracking-ad" data-mod="popu_223"> <a href="javascript:void(0);" target="_blank"> </a></div>
<script type="text/javascript">
function btndigga() {
$(".tracking-ad[data-mod='popu_222'] a").click();
}
function btnburya() {
$(".tracking-ad[data-mod='popu_223'] a").click();
}
</script>
<ul class="article_next_prev">
</ul>
<div style="clear:both; height:10px;"></div>
<div class="similar_article" style="display:none">
<h4>我的同类文章</h4>
<div class="similar_c" style="margin:20px 0px 0px 0px">
<div class="similar_c_t">
</div>
<div class="similar_wrap tracking-ad" data-mod="popu_141" style="max-height:195px;">
<a href="http://blog.csdn.net" style="display:none" target="_blank">http://blog.csdn.net</a>
<ul class="similar_list fl"></ul>
<ul class="similar_list fr"></ul>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
GetCategoryArticles('0', 'silingsong','foot','7513157');
});
</script>
</div>