http://blog.csdn.net/silingsong/article/details/7513157
来源:互联网 发布:信号与噪声算法 编辑:程序博客网 时间:2024/04/29 21:31
<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" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">struct</a><a href="http://www.csdn.net/tag/module" target="_blank" onclick="_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" onclick="_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" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">linux内核</a><a href="http://www.csdn.net/tag/methods" target="_blank" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">methods</a><a href="http://www.csdn.net/tag/algorithm" target="_blank" onclick="_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" onclick="_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);" onclick="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" onclick="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 onclick="_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="#" onclick="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="http://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="http://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" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" onclick="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" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" onclick="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" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" onclick="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" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" onclick="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" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" onclick="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" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" onclick="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="http://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="http://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="http://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="http://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="http://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="http://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="http://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="http://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" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" onclick="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" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" onclick="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" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" onclick="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" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" onclick="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" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" onclick="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" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" onclick="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" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" onclick="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" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" onclick="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" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" onclick="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" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" onclick="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" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" onclick="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" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" onclick="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" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" onclick="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" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" onclick="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="http://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="http://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="http://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="http://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="http://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" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" onclick="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" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" onclick="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" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" onclick="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" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" onclick="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" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" onclick="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" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" onclick="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" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" onclick="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" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" onclick="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_tshow_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" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" onclick="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" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" onclick="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" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><span data-mod="popu_168"> <a href="#" class="CopyToClipboard" title="copy" onclick="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" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a></span><a href="#" class="About" title="?" onclick="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 # lsueventnamemodaliassubsystempowerdriverall_axis_forcex_axis_forcey_axis_forcez_axis_forceorientationinput/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="http://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="http://my.csdn.net/uploads/201204/26/1335411971_3727.png" alt=""><br></div><h3><a name="t31"></a>7.2.2 硬件连接图</h3><div><img src="http://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="http://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="http://my.csdn.net/uploads/201204/26/1335412010_2840.png" alt=""><br></div><h3><a name="t34"></a>7.2.5 工作状态机</h3><div><img src="http://my.csdn.net/uploads/201204/26/1335412020_2893.png" alt=""><br></div><h3><a name="t35"></a>7.2.6 寄存器定义</h3><div><img src="http://my.csdn.net/uploads/201204/26/1335412030_4499.png" alt=""><br></div><h3><a name="t36"></a>7.2.7 事件检测</h3><div><img src="http://my.csdn.net/uploads/201204/26/1335412039_2123.png" alt=""><br></div><ul><li>方向和摇动检测 </li></ul><div><img src="http://my.csdn.net/uploads/201204/26/1335412045_9908.png" alt=""><br></div><ul><li>轻拍或倾斜检测</li></ul> <img src="http://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" onclick="btndigga();"> <dt>顶</dt> <dd>2</dd> </dl> <dl id="btnBury" class="digg digg_enable" onclick="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>
0 0
- http://blog.csdn.net/silingsong/article/details/7513157
- http://blog.csdn.net/IBM_hoojo/article/details/5688947
- http://blog.csdn.net/chenlaic/article/details/6143235
- http://blog.csdn.net/eaglewood2005/article/details/4335052
- http://blog.csdn.net/mchp/article/details/3995970
- http://blog.csdn.net/v_july_v/article/details/6015165
- http://blog.csdn.net/masterz/article/details/6232585
- http://blog.csdn.net/perfectpdl/article/details/6442847
- http://blog.csdn.net/eroswang/article/details/1967243
- http://blog.csdn.net/zhvsby/article/details/5986645
- http://blog.csdn.net/dz45693/article/details/6183645
- http://blog.csdn.net/david_lv/article/details/5798003
- http://blog.csdn.net/zxingchao2009/article/details/6299313
- http://blog.csdn.net/zhanxinhang/article/details/6783766
- http://blog.csdn.net/ruanruoshi/article/details/935510
- http://blog.csdn.net/yming0221/article/details/6538527
- http://blog.csdn.net/yming0221/article/details/6528490
- http://blog.csdn.net/yming0221/article/details/6704079
- 经典排序算法之:快速排序
- 在springmvc中配置静态资源访问路径的时候,js出现无效原因
- FaceID-2:Deep Learning Face Representation by Joint Identification-Verification 笔记
- SQL之三
- 安装Linux系统到u盘做系统安装盘
- http://blog.csdn.net/silingsong/article/details/7513157
- css常用
- 面试
- js实现类似list、map
- Java 循环语句之 continue
- 《iOS开发指南:从零基础到App Store上架》第2版和第3版的区别
- mysql研究的文章
- NVIDIA cuDNN-用于机器学习的GPU库
- 不能删除文件