<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客网-嵌入式-文章分类-嵌入式Linux技术资料</title><link>http://www.cnitblog.com/zouzheng/category/2078.html</link><description>要像阿甘一直向前奔跑！</description><language>zh-cn</language><lastBuildDate>Tue, 08 Apr 2008 07:04:16 GMT</lastBuildDate><pubDate>Tue, 08 Apr 2008 07:04:16 GMT</pubDate><ttl>60</ttl><item><title>Linux下patch的制作和应用</title><link>http://www.cnitblog.com/zouzheng/articles/42126.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Tue, 08 Apr 2008 06:40:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/42126.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/42126.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/42126.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/42126.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/42126.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 因为在u-boot移植过程中，有几处通用文件要修改，如果每次都要手动修改就太麻烦了。制作补丁可以解决这个问题。学习资料的收集比较简单，方法一类似于这种初级问题网上资料非常丰富，google或者baidu搜索一下，然后选择有价值的资料，方法二是阅读man在线文档。完成收集工作，当然最终要在自己的Linux上作实验，比较总结，消化吸收为自己的东西。要除去这么一种错误思想：一定要学全。要知道，一次学...&nbsp;&nbsp;<a href='http://www.cnitblog.com/zouzheng/articles/42126.html'>阅读全文</a><img src ="http://www.cnitblog.com/zouzheng/aggbug/42126.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2008-04-08 14:40 <a href="http://www.cnitblog.com/zouzheng/articles/42126.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>交叉编译Linux内核(2.6.22.6)</title><link>http://www.cnitblog.com/zouzheng/articles/40301.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Fri, 29 Feb 2008 08:46:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/40301.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/40301.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/40301.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/40301.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/40301.html</trackback:ping><description><![CDATA[动手编译内核之前，至少应该看看源码根目录下的README文件，并参考一些其他的资料，了解编译一个内核所需要的基本条件和环境，以及基本的步骤。<br>&nbsp;&nbsp;&nbsp; 我使用的交叉编译器是<a href="http://blog.chinaunix.net/u/26710/showart_394113.html" target=_blank>arm-iwmmxt-linux-gnueabi-gcc(4.2.1)</a>，选用的内核版本是Linux-2.6.22.6。以下操作均以普通用户身份进行：<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; (1)make mrproper<br>&nbsp;&nbsp;&nbsp; 编译之前检查内核源码树是否&#8220;纯净&#8221;(clean)，必作。<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; (2)make ARCH=arm CROSS_COMPILE=arm-iwmmxt-linux-gnueabi- menuconfig<br>&nbsp;&nbsp;&nbsp; 配置内核。2.6内核早已支持图形界面的xconfig和gconfig，不过还是推荐使用menuconfig，更容易配置。选择使用PXA270处理器的mainstone开发板作为目标系统进行试验(Intel HCDDBBVA0 Development Platform)，并精简不必要的选项和模块。<br>&nbsp;&nbsp;&nbsp; 内核配置选项中目标系统名称与具体开发板的对应关系可以查看arch/arm/mach-pxa/Kconfig文件。<br>&nbsp;&nbsp;&nbsp; 配置完毕选择保存，默认会将当前配置保存到.config文件，也可以指定一个文件名如test.config，下次配置时可以load这个文件加载相应的配置。<br><br>&nbsp;&nbsp;&nbsp; (3)make ARCH=arm CROSS_COMPILE=arm-iwmmxt-linux-gnueabi-<br>&nbsp;&nbsp;&nbsp; 编译内核。<br>&nbsp;&nbsp;&nbsp; 如果前面配置了PXA27x的Keyboard支持，则编译过程中会出现关于pxa27x_keyboard.c的错误："CKEN19_KEYPAD"未声明，这是一个<a href="http://ftp.frugalware.org/pub/frugalware/frugalware-current/source/base/kernel/pxa27x.diff" target=_blank>BUG</a>，修正如下：<br>
<table style="BORDER-RIGHT: rgb(153,153,153) 1px solid; BORDER-TOP: rgb(153,153,153) 1px solid; FONT-SIZE: 12px; BORDER-LEFT: rgb(153,153,153) 1px solid; WIDTH: 80%; BORDER-BOTTOM: rgb(153,153,153) 1px solid" align=center>
    <tbody>
        <tr>
            <td>
            <pre>--- a/drivers/input/keyboard/pxa27x_keyboard.c<br>+++ b/drivers/input/keyboard/pxa27x_keyboard.c<br>@@ -140,7 +140,7 @@ static int pxakbd_resume(struct platform_device *pdev)<br> 		KPREC = pdata-&gt;reg_kprec;<br> <br> 		/* Enable unit clock */<br>-		pxa_set_cken(CKEN19_KEYPAD, 1);<br>+		pxa_set_cken(CKEN_KEYPAD, 1);<br> 	}<br> <br> 	mutex_unlock(&amp;input_dev-&gt;mutex);</pre>
            </td>
        </tr>
    </tbody>
</table>
&nbsp;&nbsp;&nbsp; 另外，还可能遇到nvram.c中&#8220;undefined reference to `rtc_lock'&#8221;的错误。修正办法是：在nvram.c中&#8220;#include &lt;linux/mc146818rtc.h&gt;&#8221;，修改include/linux/mc146818rtc.h文件，将其中对&#8220;#include &lt;linux/spinlock.h&gt;&#8221;一段的条件编译选项&#8220;#ifdef __KERNEL__ ... #endif&#8221;去掉。<br><br>&nbsp;&nbsp;&nbsp; 编译完毕可以使用命令"echo $?"检查编译是否正常完成，正确结果为0。<br>&nbsp;&nbsp;&nbsp; 这时在内核源码树顶层目录生成了vmlinux(ELF格式的非压缩内核)以及相应的符号表文件System.map，可以直接下载到内存进行调试。另外还生成了arch/arm/boot/compressed/vmlinux(ELF格式的压缩内核)，还有arch/arm/boot/zImage(压缩内核映像文件)。<br>&nbsp;&nbsp;&nbsp; 查看vmlinux文件信息如下：<br>
<table style="BORDER-RIGHT: rgb(153,153,153) 1px solid; BORDER-TOP: rgb(153,153,153) 1px solid; FONT-SIZE: 12px; BORDER-LEFT: rgb(153,153,153) 1px solid; WIDTH: 80%; BORDER-BOTTOM: rgb(153,153,153) 1px solid" align=center>
    <tbody>
        <tr>
            <td><span style="COLOR: rgb(0,1,102)">[aaronwong@localhost linux-2.6.22.6]$ file vmlinux</span> <br>vmlinux: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, not stripped<br></td>
        </tr>
    </tbody>
</table>
<br>&nbsp;&nbsp;&nbsp; (4)make ARCH=arm CROSS_COMPILE=arm-iwmmxt-linux-gnueabi- INSTALL_MOD_PATH=${TESTROOTFS} modules_install<br>&nbsp;&nbsp;&nbsp; 安装内核模块。先定义一个${TESTROOTFS}，将模块安装到这里。<br><br>&nbsp;&nbsp;&nbsp; (5)安装内核。<br>&nbsp;&nbsp;&nbsp; a)cp vmlinux ${TESTROOTFS}/boot/vmlinux-2.6.22.6<br>&nbsp;&nbsp;&nbsp; b)cp System.map ${TESTROOTFS}/boot/System.map-2.6.22.6<br>&nbsp;&nbsp;&nbsp; c)cp .config ${TESTROOTFS}/boot/config-2.6.22.6<br>
<hr style="WIDTH: 100%; HEIGHT: 2px">
[推荐阅读]<br>1. <a href="http://www.arm.linux.org.uk/docs/kerncomp.php" target=_blank>Kernel Compilation</a><br>2. <a href="http://cross-lfs.org/view/clfs-sysroot/arm/bootable/kernel.html" target=_blank>Making the CLFS System Bootable-Linux-2.6.22.6</a><br>
<img src ="http://www.cnitblog.com/zouzheng/aggbug/40301.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2008-02-29 16:46 <a href="http://www.cnitblog.com/zouzheng/articles/40301.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>H.264标准三个框架  H.264学习笔记</title><link>http://www.cnitblog.com/zouzheng/articles/38450.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Fri, 04 Jan 2008 06:41:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/38450.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/38450.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/38450.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/38450.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/38450.html</trackback:ping><description><![CDATA[H.264的编解码框架与以前提出的标准如H.261、H.263及MPEG-1/2/4并无显著变化，也是基于混合编码的方案：以运动矢量代表图象序列各帧的运动内容，使用前面已解码帧对其进行运动估计和补偿或使用帧内预测技术，所得的图象参差值要经过变换、量化、熵编码等部分的处理。所以，新标准的性能提升在于各个部分的技术方案的改进及新算法的应用。新标准在提高图象传输的容错性方面做了大量工作，重新定义了适于图像的结构划分。在编码时，图象帧各部分被划分到多个slice结构中去，每个slice都可以被独立解码不受其它部分的影响。Slice由图象最基本的结构——宏块组成，每个宏块包含一个16&#215;16的亮度块和两个8&#215;8的色度块。为进一步提高鲁棒性，整个系统被划分为视频编码层和网络抽象层。视频编码层主要描述要传输的视频数据所承载的视频内容。而网络抽象层则是考虑不同的应用，如视频会议通信、H.32X连续包的视频传输或RTP/UDP/IP的通信。 H.264标准分成三个框架(profile)：Baseline、Main及X，代表了针对不同应用的算法集及技术限定。其中，Baseline主要包含了低复杂度、低延时的技术特征；主要是针对交互式的应用；考虑到了恶劣环境下的容错性，Baseline的内容基本都被其它更高级别的profile所包含。而Main profile是针对更高编码效率的应用，如视频广播。X profile 的设计主要针对流媒体的应用，在这一框架中所有容错技术和对比特流的灵活访问及切换技术都将包括其中。 Baseline profile的主要技术特征 ⑴ Baseline的解码器只对I slice及P slice进行操作。对于帧间预测，相比以前的标准，为了更精确的对图象的运动内容进行预测补偿，新标准允许宏块更进一步划分为16&#215;16、16&#215;8、8&#215;16、8&#215;8、8&#215;4、4&#215;8、4&#215;4的子块；运动估计精确到经由6-tap滤波器得到的1/4象素位置；运动矢量由相邻块预测得到，其预测的差值被编码传输。H.264支持多参考帧的预测，规定运动估计使用的参考帧数最多可达15帧，多参考帧的使用大大提高了对图像传输的容错性，抑制了错误在空间和时间上的蔓延。对于所有的slice编码类型，H.264支持两类帧内编码：4x4与16x16编码模式。对于4x4模式，每一个亮度4x4块有8种不同方向上的预测模式及DC预测模式。对于16x16模式，每个16x16亮度块有4种帧内预测模式。而对于宏块的8x8色度采样，采用与亮度16x16几乎相同的预测模式。为了保证slice的编码独立性，帧内预测是不允许跨越slice边界的。对于变换、量化部分。不同于以前标准对预测参差值的变换编码使用DCT变换，H.264使用了简单的整数变换。这种变换与DCT相比压缩性能几乎相同且有许多优势，其核心变换的计算只使用加减、移位运算，避免了精度的损失。对变换参差系数的量化使用了52级步长的量化器，而H.263标准只有31级。量化步长以12.5％递增，量化步长范围的扩大似的编码器能够更灵活和精确的进行控制，在比特率和图象质量之间达到折中。对熵编码部分。对于要传输的量化变换系数，若使用基于上下文的变长编码（CAVLC），它是根据前面已编码传输的量化变换系数值的大小来选择接下来系数编码要使用的变长编码表。由于变长编码表的设计是基于相应的统计条件，所以其性能要优于使用单一变长编码表。而对其它数据如头信息等，使用一种单一的变长编码表(Exp-Golomb code)。新标准仍然使用基于块的预测及重构方式，为了去除由此产生的影响图象主观质量的方块效应，H.264使用了去块效应滤波器。其主要思想是当块边界上两边差较小则使用滤波器使差别&#8220;平滑&#8221;掉,若边界上图象特征明显就不使用滤波。这样既为减弱&#8220;块效应&#8221;的影响又避免滤掉图象的客观特征。同时在相同主观质量下使得比特率减少5－10％。另外，对图象数据的组织及传输。在H.264标准中的图象宏块可以灵活的宏块组织顺序(FMO)划分为多个slice group；slice之间是相互独立的可以任意的顺序传输到解码端(ASO)。而且在比特流中slice可以使用重复的方式(RS)传输，这在slice数据出错的情况下可用来进行恢复，增强了图象传输的鲁棒性。同时slice间的相互独立性抑制了错误的空间传播，因此提高了比特流的容错性。 ⑵ Main profile的技术特征 Main profile包含Baseline profile的所有算法并具有额外的技术特征，但它并不支持FMO、ASO及RS等技术。只支持对I、P、B slice的处理操作。在此框架内提出了适配块划分尺寸的变换(ABT)的概念。此概念是针对帧间编码的，其主要思想是将对预测参差进行变换编码的块尺寸与用来进行运动补偿的块尺寸联系起来。这样就尽可能的利用最大的信号长度进行变换编码。但是由于复杂度的原因，进行变换的最大块尺寸被限制在8&#215;8以下。对熵编码部分，为更高效的进行编码，这里使用了基于上下文的算术编码（CABAC）使熵编码的性能进一步提高。相比较CAVLC，在相同图象质量下编码电视信号使用CABAC将会使比特率减少10-15％。另，Main profile不支持多个slice group的划分。 ⑶ 相关的编码问题如何对已提出的预测模式进行选择(mode decision)和使用运动估计策略(ME)历来都视频编码实现的重点研究课题。在H.263标准的实现软件中对模式的选择是简单的基于对阀值的比较。在新标准的测试软件中使用了拉格朗日率失真优化策略，它是基于使用每种图象块尺寸和每种预测模式而产生的参差及其传输的码率。这样，模式选择可以取得优化的率失真性能但这是以提高运算复杂度为代价的。此优化操作是对下面拉各朗日函数的最小化： J ＝ SATD + &#955;&#8226;R 其中，R为对应传输的各部分的比特率；&#955;为优化参数，其与量化参数有很强的相关性。SATD为经过哈德曼变换的4&#215;4块的预测参差绝对值总和。对于所有帧内、帧间宏块编码模式及多参考帧的选择都通过对拉各朗日函数的最小化来实现。通常，视频标准只是包括解码规范，而模式选择的技术研究是属于编码端的范畴，所以不列在标准之内.<br><br><br><a id=viewpost1_TitleUrl href="http://blog.yesky.com/blog/langboy/archive/2006/10/27/1583139.html"><strong>H.264学习笔记一</strong></a><br>
<p>2.1介绍<br>视频编码是对一个数字视频信号的编码和解码的过程.这一章讨论了数字图象和视频信号的结构和特征以及对于视频编码来说很重要的一些基本概念,比如采样格式等.数字视频是对于一人自然的视觉场景的从时间和空间上进行采样的表示方式.一个场景是由通过在时间上对于点进行采样来得到帧从而产生的(一种对于在时间上点在整个视频场景中的表示方法)或是一个场(由奇数或偶数行的空间采样组成).采样在一定的时间间隔上(通常是1/25或1/30秒时间间隔)进行重复，从而产生一个可动的视频信号。一般来说，需要三种采样集来表示一个有色的场景。表示数字视频的流行的方法是使用ITU-R 601标准并使用"中间集"。对于一个视觉场景的重建的准确性必须被计算来决定一个视频通信系统的性能，这是一个出了名的困难和极为不准确的过程。主观的测量方法是极耗时间而且它与观察者对于变换的反应程序不同而不同。客观的测量方法实现起来就更简单一些，但是目前还不能与人类实际视觉感完完全全匹配。</p>
<p>2.2 自然视频场景</p>
<p>一个经典的&#8220;现实世界&#8221;或&#8220;自然世界&#8220;的视频场景是由多个有各自特征形状，深度，纹理和亮度的物体构成的。视频场景的颜色和明亮度在不同的场景中根据不同程序的光滑度而定。一个与视频处理和压缩相关的经典的自然视频场景包括空间特征（纹理变换，物体的数目和形状，颜色等）和时间特征（物体运动，亮度的变化，视点的移动等）</p>
<p>2.3 捕捉<br>一个自然视频场景在空间和时间上是连续的。用数字的形式表示一个视频场景包括在空间对实际场景进行采样(通常是通过在视频图形面上用长方形格处理)和时间采样(以一系列以某时间间隔采样得到的静态帧组成)。数字视频就是在数字形式下的一个视频场景的采样的表示方式。每一个时-空采样（像素）用一个数或一组数来表示，用来描述采样点的亮度和色度。</p>
<p>为了得到一个二维的采样图像，摄像头把一个视频场景的二维投影聚焦到传感器上，比如一组电荷耦合装置(CCD)。在带色的图像捕捉过程中，每一个颜色成员都分别被过滤并投影到一组CCD中。</p>
<p>2.3.1 空间采样<br>一组CCD的输出就是一个模拟的视频信号，一组可以表示一个视频图像的电信号。在时间上对一点进行采样就形成了一个有定值的采样点图像或帧。最常用的采样方法是把采样点置于一个正方形或长方形格中进行操作。然后对于每个格交点处的点进行采样，重建过程就以采样值对应到像素上进行显示。重建图的视觉效果取决于采样点的数量。选择一个粗糙的采样格会得到一个低分辨率的采样图像，而增加采样点的数量就会增加采样图像的分辨率。</p>
<p>2.3.2 时间采样<br>一个可动的视频图像是通过对信号在周期性的时间间隔上进行快照得到的。重放这一系列的帧会得到一个运动的效果。一个高的时间采样率(帧率)会产生更加平滑的运动但是它就要求有更多的采样要被捕捉并被保存。在10帧每秒之下的帧率有些被用于一些很低码率的视频通信中(因为被传输的数据量非常的小)但是运动却看起来很笨拙而且不自然。在10-20帧每秒是比较经典的低码率视频。在25-30帧每秒进行采样是标准电视信号图象的采样帧率(配合隔行扫描采样来达到更好的运动效果）。50-60帧每秒就可以形成平滑的运动(代价就是帧率太过高，传输和存储的压力大).</p>
<p>2.3.3 帧和场<br>一个视频信号可以被通过对于一系列帧(渐进采样)或一个序列的隔行扫描的场(隔行扫描采样)来进行采样。在一个隔行扫描采样的视频序列里，一帧的一半的数据是在每个时间采样间隔进行采样的。一个场由奇数个或偶数个扫描线组成，而一个隔行扫描的视频序列包括一系列的视频帧。这种采样方式的优点在于与有相同帧数的同样码率的渐进序列相比，可以在一秒中传输两倍多的场，这样就可以形成更加平滑的运动。比如，一个PAL视频序列由50场/秒的码率组成，在回放过程中，运动可以比与之相同的25帧每秒的用渐进视频序列形成的运动显得更加的平滑。</p>
<p>2.4 颜色空间<br>大多数数字视频程序都依赖于彩色视频的显示，这样的话，就需要一个来捕捉并表示颜色空间的表示方法。一个单色的图像只需要一个在空间内表示一个像素点的亮度或流明度的值就可以了。但对于颜色图像来说，对于一个像素点至少需要三个数来把颜色信息准确地表示出来。用来表示亮度和颜色的方法叫做颜色空间。</p>
<p>2.4.1 RGB<br>在RGB颜色空间中，一个带颜色的图象采样是用三个值来表示一个象素点的相对的红，绿和蓝色比(三种光线的主样构成颜色)。任何颜色都可以通过把红，绿和蓝来通过不同的比例相混得到。RGB颜色空间更加适合于捕捉并显示颜色图像。捕捉RGB图像包括过滤出红，绿和蓝色的构成比率，并用一个单独的传感器数组来捕捉。CRT和LCD通过分别对每个像素点的红绿蓝值进行显示来得到各种颜色。从一个通常的观察距离来看，不同的构成部分可以达到颜色上的真实感。</p>
<p>2.4.2 YCbCr<br>人类视觉系统(HVS)相比亮度来说对于颜色不是那么敏感的。在RGB颜色空间中，三种颜色被平等地看待，并用相同的分辨率存放起来。但是通过把亮度与颜色信息分离，并对亮度值取更高的分辨率可以更有效地表示一个颜色图像。</p>
<p>YCbCr颜色空间和它的变换(通常写为YUV)是一种流行而高效的表示一个颜色图像的方法。Y是亮度值，由R,G,B的加权平均可以得到： Y=krR + kgG + kbB<br>这里k是加权因子。</p>
<p>颜色信号可以由不同的颜色差别来表示：<br>Cb = B-Y<br>Cr = R-Y<br>Cg = G-Y<br>对于一个颜色图像的完整的描述由给定Y和三个色差:Cb,Cr,Cg来表示。</p>
<p>目前为止，我们的表示方法好像并不那么好，因为相比RGB表示来说，我们这次用了四个参数。然后Cb+Cr+Cg是一个常数，那么我们只需要两个色度参数就可以了，第三个可以通过其他两个计算出来。在YCbCr空间中，只有Y和Cb,Cr值被传输和存储，而且Cb和Cr的分辨率可以比Y低，因为人类视觉系统对于亮度更加敏感。这就减少了表示图像的数据量。通常的观察情况下，RGB和YCbCr表示的图像看上去没有什么不同。对于色度采用比亮度低的分辨率进行采样是一种简单而有效的压缩办法。</p>
<p>一个RGB图像可以在捕捉之后转换为YCbCr格式用来减少存储和传输负担。在显示图象之前，再转回为RGB.注意没有必要去指明分别的加权值kg（因为kb+kr+kg=1)，而且G可以从YCbCr中解压出来，这说明不需要存储和传输Cg参数。</p>
<p>Y = kr R + (1-kb-kr)G + kb B<br>Cb = 0.5/(1-kb) * (B-Y)<br>Cr = 0.5/(1-kr) * (R-Y)</p>
<p>R = Y + (1-kr)/0.5 * Cr<br>G = Y - 2kb(1-kb)/(1-kb-kr) * Cb - 2kr(1-kr)/(1-kb-kr) * Cr<br>B = Y + (1-kb)/0.5 * Cb</p>
<p>ITU-R的BT.601决议定义了kb=0.114,kr=0.299，那么代换参数就有了如下等式：</p>
<p>Y = 0.299R + 0.587G + 0.114B<br>Cb = 0.564(B - Y )<br>Cr = 0.713(R - Y )</p>
<p>R = Y + 1.402Cr<br>G = Y - 0.344Cb - 0.714Cr<br>B = Y + 1.772Cb</p>
<p>2.4.3 YCbCr采样格式<br>4:4:4采样就是说三种元素Y,Cb,Cr有同样的分辨率,这样的话,在每一个像素点上都对这三种元素进行采样.数字4是指在水平方向上对于各种元素的采样率,比如说,每四个亮度采样点就有四个Cb的Cr采样值.4:4:4采样完整地保留了所有的信息值.4:2:2采样中(有时记为YUY2),色度元素在纵向与亮度值有同样的分辨率,而在横向则是亮度分辨率的一半(4:2:2表示每四个亮度值就有两个Cb和Cr采样.)4:2:2视频用来构造高品质的视频彩色信号.</p>
<p>在流行的4:2:0采样格式中(常记为YV12)Cb和Cr在水平和垂直方向上有Y分辨率的一半.4:2:0有些不同，因为它并不是指在实际采样中使用4:2:0，而是在编码史中定义这种编码方法是用来区别于4:4:4和4:2:2方法的).4:2:0采样被广泛地应用于消费应用中，比如视频会议，数字电视和DVD存储中。因为每个颜色差别元素中包含了四分之一的Y采样元素量，那么4:2:0YCbCr视频需要刚好4:4:4或RGB视频中采样量的一半。</p>
<p>4:2:0采样有时被描述是一个"每像素12位"的方法。这么说的原因可以从对四个像素的采样中看出.使用4:4:4采样，一共要进行12次采样，对每一个Y,Cb和Cr，就需要12*8=96位，平均下来要96/4=24位。使用4:2:0就需要6*8=48位，平均每个像素48/4=12位。</p>
<p>在一个4:2:0隔行扫描的视频序列中，对应于一个完整的视频帧的Y,Cb,Cr采样分配到两个场中。可以得到，隔行扫描的总采样数跟渐进式扫描中使用的采样数目是相同的。</p>
<p>2.5 视频格式<br>这本书中描述的视频压缩标准可以压缩很多种视频帧格式。实际中，捕捉或转化一个中间格式或一系列中间格式是很平常的事情。CIF就是一种常见的流行的格式，并由它衍生出了4CIF和Sub-QCif。帧分辨率的选择取决于应用程序，可使用的存储量以及传输带宽。比如说4CIF对于标准定义的电视和DVD视频来说是合适的,CIF和QCIF在视频会议中是常被使用的格式。QCIF和SQCIF对于移动设备的多媒体程序来说是合适的，在这样的情况下，显示分辨率和码率都是有限的。以下是各种格式的具体使用位数的需求（使用4:2:0采样，对于每个元素用8个位大小表示)：</p>
<p>格式：&nbsp;Sub-QCIF&nbsp;亮度分辨率：&nbsp;128*96&nbsp;&nbsp;每帧使用的位:&nbsp;147456<br>格式：&nbsp;QCIF&nbsp;&nbsp;亮度分辨率：&nbsp;176*144&nbsp;&nbsp;每帧使用的位:&nbsp;304128<br>格式：&nbsp;CIF&nbsp;&nbsp;亮度分辨率：&nbsp;352*288&nbsp;&nbsp;每帧使用的位:&nbsp;1216512<br>格式：&nbsp; 4CIF&nbsp;&nbsp;亮度分辨率：&nbsp;704*576&nbsp;&nbsp;每帧使用的位:&nbsp;4866048</p>
<p><br>一种在电视信号中被应用的很广的数字视频信号编码格式就是ITU-R的BT.601-5 提案。亮度元素被在13.5MHz下采样，而亮度值则在6.75MHz下采样，这样就形成了一个4:2;2的Y:Cb:Cr采样结果。采样数字信号的参数取决于视频码率(对于NTSC来说是30Hz,对于PAL/SECAM来说是25Hz)。NTSC的30Hz是对低空间分辨率的补偿，这样总的码率就是216Mbps.实际显示的激活部分的区域要比总量小，因为它去掉了在一帧边缘处的水平和垂直空白间隔。<br>每一个采样都有0-255的采样范围。0和255两个等级被留作同步，而且激活的亮度信号被限制到26(黑色）到235(白色)之间.</p>
<p>2.6 质量<br>为了指定，评价和比较视频通信系统，我们需要决定向观察者显示的视频图像的质量。衡量视频信号的质量是一件困难的事情，通常也是不准确的，因为有太多的因素会影响到衡量的结果了。视觉质量与生俱来就是主观的因素，它被很多因素影响着，这就使对于这个衡量结果的准确性变得更难了。比如说，一个视频信号的质量对于一个观察者来说主要取决于任务本身，比如说，被动地观看一部DVD影片，主动地参与一个视频会议，用符号评议进行通信交流，或是试图从一个视频场景中认出一个人。衡量视频信号的客观分类给定了一个准确的可重复的结果，但是没有哪种客观的测量方法可以完全地模拟人类视觉主观的感受。</p>
<p>2.6.1&nbsp; 主观质量测量<br>2.6.1.1 影响主观质量的因素<br>对于一个视频场景的感觉是由人类视觉系统对于不同元素复杂交互性决定的----眼睛和大脑.对于视频信号的感知是受空间保真度的影响的(不管有没有明显的失真，问题在于我们是否可以清楚地看到一个场景的各个部分)和时间保真度(运动是否自然平滑)。然而，一个观察者对于质量的看法经常会被观察环境，观察者的心情和观察者与场景的交互程序相关。一个执行特定任务的用户需要关注于视频场景的一部分。观察一个场景常与看一个电影时的对于&#8220;好&#8221;的概念是不同的。例如，一个观察者的对视频质量的看法在观察环境好的情况下会更好一些（而这一点不取决于视频信号本身的好坏）</p>
<p>其他的重要的影响因素包括视觉焦点（一个观察者通过一系列的观察点而不是同时观察所有的内容）和所谓的"最新效应"（我们对于一个视频序列的看法总是更多地受更新看到的内容的影响而不是老的内容)。所有的这些因素都让衡量一个视频的质量的好坏的任务变得极为困难。</p>
<p>2.6.1.2 ITU-R 500<br>很多的关于主观质量认下的测试过程都在ITU-R BT.500-11中被定义。一个常用的过程就是Double Stimulus Continuous Quality Scale(DSCQS)方法，评价者被展示了一系列的图片或两个视频序列A和B（一个接一个地），然后被要求给出A和B的质量评价值，方法是在五个分隔着的评价值（从"Excellent"到"Bad")画连续线来定。在一个典型的测试会话中，评价者被展示了一系列的序列，并被要求对它们进行评价。对于每对序列来说，一个是未受损的"参考&#8220;序列，另一个是同样的序列，它被在测试的系统或过程中修改了。</p>
<p>这两个序列的顺序，原始的和有损的，在测试地过程中被随机的给出，这样评价者就不知道哪个是原始的，哪个是改变过的序列。这样就防止了评价者带偏见地比交这两个测试序列。在结束的时候，评分被转化到一个规范化的范围内，最终的结果是用平均评价值来说的，用它来指明相应的帧的质量。</p>
<p>像DSCQS这样的测试被广泛地接受，并被用来评价主观的视频效果。然而，这样的测试受实际问题的影响。这样结果对于评价者来说差别会非常大。这个不同会被在重复测试的过程中被弥补过来。一个有经验的评价者(对视频压缩失真了解的比较多的）会比那些非有经验性的用户会给出一个更带偏见的评分。这就意味着一个很大的评价用户群是需要的，因为没有经验的用户很快会发现被改变的视频的一些特征。这些因素使得使用DSCQS方式的代价更大。</p>
<p>2.6.2 客观的质量测量<br>主观测量质量的方法的复杂性和消耗性让用算法自动测量质量要更加的吸引人。视频压缩的开发者和视频处理系统很大程序上依赖于所谓的客观质量测量方法。最广泛应用的方法是PSNR方法，但是这种方法的局限性使人们不得不找更加复杂的方法来逼近人类视觉性。</p>
<p>2.6.2.1 PSNR<br>PSNR是用来在对数级上描述质量，并且依赖于原始信号和改变后信号的均方差（MSE）:<br>PSNR(db) = 10log(10)(2^n-1)^2/MSE</p>
<p>PSNR可以很方便而快速地被计算出来，这样它就成为了一种很流行使用的方法，并用来测量压缩和解码视频图像的质量。</p>
<p>PSNR方法有几个局限性，PSNR需要一个原始的图像做为对比，但是这也许是无法在所有情况下都可以实现的,也难保所谓的原始图象没受过影响。PSNR不能准确地给出主观的视频质量值。对于给定的一个图象或一个图象序列来说，高的PSNR通常说明质量高，低PSNR说明质量低。然而，一个特定的PSNR值并不等于绝对的主观的质量。主观上感觉好的图象不一定PSNR值高。这种情况下，人类的观察敏感区中心让人感觉清晰度很好，但信嗓比不一定高。</p>
<p>2.6.2.2 其他的客观质量衡量方法<br>因为PSNR方法的局限性，最近有很多工作用来开发更加复杂的客观的测试过程，而且表示更准确的主观信息。很多不同的方法都被提出了。但是没有一个可以完全代替主观测试。所以还没有一个比较标准的，准确的，可用的方法。意识到这一点之后，ITU-T视频质量专家组（VQEG）就致力于提出一种客观的视频质量评价机制。每一步就是测试并比较隐藏的模型与测试模型。在2000年三月，VQEG宣布有10个这样的测试系统备选。不幸的是，没有一种被认为是适合的。VQED在2003年进行了第二次的评估。除非非常在自动质量评价中有一个非常大的突破，否则这个问题是很难被解决了。</p>
<p>2.7 结论<br>采样模拟信号会形成数字视频信号，它有准确，高质量和对于数字媒体的存储传递等各种优势，但是会占用比较在的空间。与生俱来的问题包括空间和时间分辨率，颜色表示和视频质量的测量问题。下一章会介绍视频压缩的一些其他的基本理论.</p>
<br><a id=viewpost1_TitleUrl href="http://blog.yesky.com/blog/langboy/archive/2006/10/27/1583142.html"><strong>H.264学习笔记二</strong></a><br>
<p>3.1 介绍<br>压缩(compress) 动词： 挤压到更小的空间中;即condense<br>压缩(conpress) 名词： 压缩的行为或是压缩的状态</p>
<p>压缩是把数据用更小的空间来存放的技术.视频压缩(视频编码)是把数字视频流序列用更少的数据位进行存放的方法."Raw"或叫没压缩过的视频需要大量的码(大约每秒信息216M),而且压缩对于数字视频的存储和传输来说都是需要的.</p>
<p>压缩包括一对互补的系统,一个编码器(encoder)和一个解压器(decoder).编码器把原数据在传输或存放之前转变为压缩格式(占用更少的数据位),而解压器把压缩的格式转会到原来的视频数据格式上.编码器/解码器对经常被叫做CODEC(enCOder/DECoder)</p>
<p>数据压缩是通过移除数据冗余来实现的，比如说，对于数据重构过程中无用的数据。很多种数据都有统计上的冗余性，它们就可以通过无损压缩进行有效的压缩，这样的标准比如说JPEG-LS，它可以达到3-4倍的压缩。有损压缩可以达到更高的压缩比。在有损压缩系统中，解压数据与源码流数据是不同的，高压缩率是通过视频质量的下降来达到的。有损视频压缩系统是建立在删除主观冗余的原理之上的，从图象或视频中删掉的部分不会很大程度上影响观察者对于视频质量的认识的。</p>
<p>大多数视频编码方法寻找空间和时间上的冗余来达到压缩的效果。在时间域中，连续几帧的视频通常有很强的相关性，特别是当时域采样率是非常高的时候尤其如止。在空间域中，通常像素采样点之间是相互关联的，比如说，相邻象素之间很相近。</p>
<p>H.264和MPEG4视频标准共用了一部分特征。这两种标准都假设了一种以块(block）为基础的运动补偿，变换，量化和熵编码。我们主要关注到这些主要的方法中，并从时间模型开始，接下来是图象变换，量化，预测式编码和熵编码。并以对于一个图象采样块进行编码和解码的过程进行描述。</p>
<p>3.2 视频编解码器<br>一个视频编码器器把一个源图像或视频序列转化为一种压缩模式，并在解码器把它构造为源序列的一个拷贝的或是一个近似.如果解压了的视频序列与原序列是相同的，那么编码过程是无损的，如果解压序列与源序列是不同的，那么这个过程是有损的。</p>
<p>CODEC用一种模型来表示原始视频流(一个被有效编码的表示方式，并可以用它来重建视频数据的近似结果或尽量取得高的码率。这两个目标(压缩效率和高质量)通常是相矛盾的，因为一个低的压缩码率通常在解压部分会降低图象的质量。码率和质量的平衡我们会在之后进行介绍</p>
<p>视频编码器是由三个主要的功能部件实现的：时域模型，空域模型和熵编码。时域模型的输入为一个未压缩的视频流序列。时域模型试图用邻近帧的相似性来消除了时域冗余,通常是构造通当前帧的预测。在MPEG4视频部分和H.264中，预测通常从一个或多个之前或之后的帧来进行的，并通过对于帧之间的差别进行补偿。时域模型的输出是一个剩余帧(通过从实际当前帧中减去预测值得到)，而一系列的模型参数，通常是一系列用来描述运动是如何补偿的运动向量。</p>
<p>剩余帧构成了时域模型的输入，它会利用邻近采样点的相似性来降低空域的冗余。在MPEG4视频部分和H.264中，这通常通过一些变换来对样点进行处理来实现。变换把采样点转到其他的域中，在这些域中用变换系数来表示。这些系数被量化来删除不明显的值，只留下很少的大系数来对剩余帧进行表示。空域模型的输出是一系列的量化变换的系数。</p>
<p>时域模型的参数(通常是运动向量)和空域模型的参数(系数)通常用熵编码来进行压缩。这就删除掉了统计上的冗余度(比如，用短二进制码表示当前的向量和系数)并制造出一个压缩流或文件来进行传输或存储。一个压缩的序列由编码的运动向量参数，编码的剩余系数和头信息表示。</p>
<p>视频解吗器从一个压缩流中构造一个视频帧。系数和运动向量由熵解码器进行解码，然后空域模型构建出一个版本的剩余帧。解码器利用运动向量参数与一个或多个解压帧来构成一个对当前帧的预测，然后帧就可以通过加入这个剩余帧来得到。</p>
<p>3.3 时域模型<br>时域模型的目标是要减少减少传输帧的冗余性。这个过程的输出是一个剩余帧，而且预测过程越准确，剩余帧中包含的能量就越小。剩余帧被编码并送到解压器用来构造预测帧，加上解码的剩余帧来构成当前帧。预测帧是通过一个或多个过去或未来的帧(都叫做参考帧)来创建的。预测的准确性通常可以由参考帧和当前帧之间的运动补偿来改进。</p>
<p>3.3.1 从前一视频帧进行预测<br>时间域的预测的最简单的方法是从当前帧的前一帧进行预测。用两帧之间的差来做为剩余帧。这个方法的明显的问题在于剩余帧中的能量太多了，这也就是说在时域压缩之后还有大量的数据可以被压缩。大部分的剩余能量是由于在二帧中的物体运动可能造成两帧的运动补偿形成的。</p>
<p>3.3.2 由于运动造成的改变<br>在视频帧之间的改变可能是由物体的运动造成的(刚性的物体运动，比如说一辆运动着的汽车，或可变形物体运动，比如说移动的手臂），摄象头的移动，被去覆盖的区域(比如说一个运动场景中由于物体的运动致成背景的去覆盖性)和光线的变化。除去去覆盖和光线变化，差别都是由于帧间的像素点的运动造成的。这样构造的像素点的邻接被称为光流(optical flow)。完整的域包括对于每个像素位置的光流向量，但是这些域都是被子采样过的，这样的话，只有每隔两个像素点的向量才被显示出来。</p>
<p>如果光流域是准确描述的，那么它应该可以构成一个对大多数像素点准确的预测，方法即为沿着光流向量移动参考帧中的每个像素点。然而，种种原因之下，这并不是一个实用的运动补偿的方法.对于光流的准确的计算对于计算来说是非常敏感的而且把每个像素点的光流传给解码器也是必要的，以使它能重构造预测帧(这样就得到了大量的传输数据，与我们小剩余值的目标是相矛盾的）。</p>
<p>3.3.3 基于块的运动估计和补偿<br>一个实用并被广泛使用的运动补偿方法是为了裣一个矩形区域的运动或叫当前帧的&#8220;块&#8221;。下列的步骤对当前帧的一个M &#215; N采样的块的处理过程：</p>
<p>1. 在参考帧中查找一帧(过去的或以后的，已被编码的或传输的)，来找到一个相匹配的M * N的区域。这是由在查找区域中比较M * N的块,并找到一个最接近这一块的区域。一个流行的匹配方式是用把两个块的能量作差，这样能量相差最小的两个区域被认为是最佳的匹配结果。这个查找匹配的过程被叫做运动估计。</p>
<p>2. 选定的区域成为对于当前M * N块的预测块，它被减掉当前的块来构成一个M*N的剩余块(运动补偿).</p>
<p>3. 剩余块被编码并传输，当前块和选定块的差值(运动向量)也被传输.</p>
<p>解码器使用接收到的运动向量来重建预测区域并解压剩余块，加上之前的预测块来重建一个原始块。</p>
<p>基于块的运动补偿这么流行是有很多原因的。它很直接，计算性上也很易处理，它与矩形视频帧很相适应，并且使用基于块的图形变换(比如DCT等)，而且它对于视频序列提供了一个有很效的时域模型。然而它也有一些缺点，比如说，实际物体中几乎没有平滑的边缘来进行矩形边界的匹配，物体通常在帧之间用很小的像素点位置移动（比如说可变形的物体，旋转和扭曲），而且很多种运动是难以用基于块的方法进行补偿的。尽管它有这些缺点，基于块的运动补偿是当前所有的视频标准使用的时域模型的基础.</p>
<p>3.3.4 对于一个宏块的运动补偿<br>宏块，对应于一个16*16的帧区域，是大多数编码标准(包括MPEG1,MPEG2,MPEG4,H.261,H.263和H.264)运动补偿预测方法的基本组成部分。对于源4:2:0的视频信号来说，一个对于源帧的16*16像素区域的是由256个亮度采样(用4个8*8的采样块排列)，64个Cb色度采样(用一个8*8的采样块排列),64个Cr色度采样(用一个8*8采样块排列)，这样就一共六个8*8的块。MPEG4或H.264的CODEC通过宏块来处理每一个视频帧.</p>
<p>运动估计<br>对于一个宏块的运动估计包括在参考帧中找一个与当前宏块相近的16*16的采样区域。参考帧是一个在之前被编码过的帧。参考帧的区域以当前宏块的位置为中心，宏块区域的查找16*16的相匹配区域做为最佳匹配结果。</p>
<p>运动补偿<br>在参考帧中选定的最佳匹配区域是从当前宏块中减掉的部分，它用来构成一个剩余帧，接着通过运动向量被编码和传输，它也描述了最佳对应区域。在编码器之内，剩余帧被编码和解码并被加到相应区域之中，来重构一个宏块，这个宏块被存为以后的运动补偿预测的参考帧。用一个解码的剩余帧来重构宏块来保证编码器和解码器在运动补偿的时候使用相同的参考帧。</p>
<p>在运动估计和补偿的过程中有很多不同方法。参考帧可以是之前的或之后的一帧，也可以是结合或是更多帧的搭配。。如果一个之后的帧用来进行参考的话，那么就要先对这一帧进行编码。在参考帧和当前帧之间有一个很大的改变的地方（比如说，一个场景的变化），也许不使用运动补偿进行编码宏块会更有效。这样编码器就选择帧内编码(在没有运动补偿的情况下进行编码.在移动场景中移动的物体很少符合16*16像素边缘而且这样也许使用可变的块大小进行运动估计和补偿会更高效。物体可能有很少的像素部分运动，这样使用在参考帧中插值法会是一种更加好的预测方法。</p>
<p>3.3.5 运动补偿块大小<br>视频序列中的连续两帧中图1是从图2中不通过运动补偿而进行减操作得到的一个剩余帧.剩余帧中的能量由于通过16*16的宏块做运动补偿而降低.每8*8块(而不是16*16)的块会更近一步降低剩余帧中的能量,4*4会更少.这个例子说明了小的运动补偿块可以得到更佳的运动补偿效果.然而,一个更小的运动补偿块会导致复杂度的升高(更多的搜索操作被执行了)，这样更多的运动向量就要被传输。发送每个运动向量需要一些位来做到，这个多余的负担会抵销剩余帧中能量的减少的优势。一个更有效的妥协的方法是采用调节图的块大小，比如说在相似的区域上选择一个大的块,而在高度细节化运动的部分选用更小的块。H.264使用了一种自适应的运动补偿块大小，在以后我们会提到。</p>
<p>3.3.6 子像素运动补偿<br>一些情况下，通过在参考帧中从插值采样位置来预测会得到更好的运动补偿预测。&#8220;子像素&#8221;运动估计和补偿包括寻找子采样的插值位置与整值采样位置，来寻找最佳匹配(比如说，最小化剩余帧的能量)并在这个位置使用整或子采样值来直行运动补偿预测。对于四分之一像素运动裣来说，第一步，运动估计会寻找对于整采样格的最佳匹配,接下来编码器在最佳匹配附近寻找半采样位置来看匹配是否可以被改进，如果需要的话，对半采样最佳匹配像素附近的四分之一采样位置进行寻找。最终的匹配（整，子或四分之一采样位置）由当前块或宏块相差得到。</p>
<p>用4*4的块大小得到的剩余帧可以使用半采样插值并有更低的剩余能量。这种方法可以由从四分之一采样格来得到更小的剩余帧能量得到扩展。总体上说，&#8220;更好的&#8221;插值可以达到更好的运动补偿性能（更小的剩余帧能量），代价则是复杂度会更高一些。这样得到的性能提升会因为插值的步骤的增多而抵销。半采样插值相比整采样有更好的性能，四分之一采样插值会给出更好的效果，八分之一更胜之，以此类推。</p>
<p>一个运动补偿过的参考帧被从当前帧中减去，剩余帧的能量如下（用总绝对误差来近似SAE）： <br>Sequence&nbsp;No motion compensation &nbsp;Integer-pel &nbsp;Half-pel &nbsp;Quarter-pel<br>'Violin',QCIF&nbsp;171945&nbsp;&nbsp;&nbsp;153475 &nbsp;&nbsp;128320 &nbsp;&nbsp;113744<br>'Grasses',QCIF&nbsp;248316&nbsp;&nbsp;&nbsp;245784 &nbsp;&nbsp;228952 &nbsp;&nbsp;215585<br>'Carphone',QCIF&nbsp;102418&nbsp;&nbsp;&nbsp;73952&nbsp;&nbsp;56492&nbsp;&nbsp;47780</p>
<p>一个低的SAE表示更好的运动补偿性能。在每种情况下，子像素运动补偿相对整像素补偿都有更好的性能表现，而四分之一补偿会更好。"Grasses"序列有更复杂的运动，这样就更难以实施运动补偿，悲痛"Violen"和"Carphone"就更容易进行补偿了。</p>
<p>在四分之一采样插值中寻找一个匹配的4*4的块是比在没有插值的16*16的块中更加复杂的。除了更大的复杂度之外，因为每个块的运动向量都要被编码并传输到接收端以更好的重建图象，这样就有了编码上的性能损失了。因为块大小减小了，传输的向量数增加了。需要更多的位来表示半采样或四分之一采样向量，因为向量的更细节部分也必须被像整采样那样进行编码。这样有另复杂运动的补偿模式下就有编码效率上的平衡度了，因为运动补偿越准确，就有更多的数据来表示运动域，但是在不那么准确的情况下，就不需要那么多位了。<br>3.3.7 基于区域的运动补偿<br>在一个自然的视频场景中移动的物体很少被对很整齐地对齐到块的边缘，它们很可能是不规则形状的，放置在任意位置上，而且在帧间改变他们的形状。这样就很难在参考帧中找到一个理想的匹配，因为它覆盖了一部分运动着的物体，一部分静态的物体。</p>
<p>在图像的任意区域应用运动补偿是可以达到更好的性能的。比如说，如果我们试图在椭圆形的物体中进行运动补偿的话，我们可以在参考帧中找到一个理想的匹配。然而使用基于区域的运动补偿会遇到很多的实际困难，包括识别区域边界，指出边界的轮廓，在运动补偿之后编码剩余帧，MPEG-4视频包括了一系列的工具来支持基于区域的补偿和编码。</p>
<br><br>
<div class=rightmenu>
<div><a id=viewpost1_TitleUrl href="http://blog.yesky.com/blog/langboy/archive/2006/10/27/1583144.html"><strong>H.264学习笔记三</strong></a></div>
<p>3.4 图像模型<br>一个自然的视频图像包括一格采样值.自然图像在它们原始的状态下通常很难于压缩,这是因为相邻图像采样值之间的很强的联系造成的.我们可以从一幅图像的自相关函数图中得到不同图像之间的相似程度.在中点处的最顶点表示图像未经移动时的图像.当空域移动拷贝被从原始图像的任一个方向移除的时候,这个函数值就会急骤下降,就这说明了一个图像采样值的邻域内是高度相关的.</p>
<p>一个运动补偿的剩余图象的自相关函数在当空域移动增加的时候快速衰减,表明了相邻的采样点是弱相关的.有效的运动补偿在剩余帧中减少了本地相关性,这样就让图象比原始状态下的图象更易于压缩.图像模型的作用就是把图像或剩余图像的相关性去除掉,并把它转变为一种可以被熵编码器有效编码的数据形式.实际图像模型一般有三个主要的组成部分：变换（去相关和简化数据），量化（减小转换数据的相关性）和重组（组合数据来把大值分组到一起）。</p>
<p>3.4.1 预测图像编码<br>运动补偿是预测编码的一个实例，在这种补偿下，编码器基于上一帧创造了对于当前帧的一个区域的预测并从当前域中减去这个预测来形成一个剩余帧。如果预测是成功的，那和在剩余帧中的能量是比原始帧中的能量少得多的，而且剩余帧可以用更少的位来表示。</p>
<p>与之相似的是,同一个图像采样或区域的预测可以由前面传输的同样图象或帧中组成.预测性编码被用作是早期的压缩算法的基础,也是H.264的一个很重要的组成部分.帧内编码(应用在变换域中,见后).空域预测有时被描述为"差分脉冲编码调制"(DPCM)--从通信系统中引入的一个差分的PCM编码方法.</p>
<p><br>&nbsp;B&nbsp;C<br>A&nbsp;X</p>
<p>图中假设一个像素X是被编码的像素点,如果在光栅顺序下处理这帧的话,那么点A,B和C(在当前和之前行的邻近像素)在编码和解码器中都是可得的(因为他们已经在X之前被解码).编码器在根据一些在之前编码的像素的组合来得到对于X的预测,从X中减掉这个预测,然后编码剩余帧频(做差之后的结果).解压器形成相同的预测,然后把解码的剩余帧加进去来重建像素值.如果编码过程是有损的(比如说剩余帧被量化了)那么解码的像素值A,B,C也许与原始的A,B,C是不同的(因为编码过程的损失),这样的话上述的过程可能在编码器和解码器上引起累积的不匹配.这种情况下,编码器应该解码剩余帧中的R(X),并重建像素.</p>
<p>比如说:<br>编码器预测: P(X) = (2A + B + C) / 4<br>剩余帧&nbsp; R(X) = X - P(X) 被编码并传输<br>解码器解码R(X)并组成同样的预测: P(X) = (2A + B + C) / 4<br>重建像素 X = R(X) + P(X)</p>
<p>编码器使用解码的像素值A,B,C来构成重建,比如说,P(X)=(2A+B+C)/4.这样的话,编码器和解码器使用同样的P(X),这样就可以避免错位的发生.</p>
<p>这种方法的压缩的效率依赖于对于P(X)预测的准确性.如果预测是准确的(P(X)与X的值是相近的),那么剩余帧的能量就非常小了.然而,并不是经常都能选择一个对复杂图像来说那么理想的预测器的.编码器就有必要指出对解码端选择预测器,这样就有一个预测和需要的多余位来表示信号和预测器的一个折衷考虑了.</p>
<p>3.4.2 变换编码<br>3.4.2.1 总述<br>图像中或视频CODEC中的变换阶段是把图像或运动补偿剩余值转到另一个域中(变换域中)。变换的选择依赖于以下几个分类<br>1. 在转换域中的数据是去相关性的(转换域中的数据的大多数能量都会聚集到很小的值中)<br>2. 转换应该是可逆的.<br>3. 转换的计算过程应该是易于处理的，</p>
<p>对图像和视频压缩以及很多的变换都建议使用以下两类方式：基于块的变换和基于图像的变换。基于块的变换的例子比如Karhunen-Loeve变换(KLT)，单值分解(SVD)和余弦变换（DCT）。每一种变换都是对于N*N的图像块或剩余样本来说的，这样图像就被用块的单元来处理。块变换有很低的内存需求而且很适于基于块的运动补偿剩余帧的压缩，但是受边界区域的影响比较严重。基于图像的变换对于整个图像或帧来进行操作（或一个图像的一大段进行操作）。最常用的图像变换是离散小波变换(DWT或直接说小波变换)。像DWT这样的变换对于表态图像的压缩来说已经被证明是很有效的了，但是它们对内存的消耗都比较大（因为整个图像或段都以单个单元来进行处理）而且不适用于基于块的运动补偿方法。DCT和DWT在MPEG4视频部分中都得到了应用（而且一个DCT的变种在H.264中被使用）。它们将在下面几节被讨论。</p>
<p>3.4.2.2<br>余弦变换在X中进行运算（X是一个N*N的采样块，通常是指在预测之后的图像采样或剩余帧值)来构造Y，一个N*M的系数块。DCT的操作(及它的反变换IDCT),可以用变换矩阵A来描述。一个N*N采样块的DCT变换由如下式子得到：Y=AXA(T),反DCT变换:Y=AXA(T),A(T)表示A的对称矩阵</p>
<p>X是一个采样的矩阵，Y是一个系统的矩阵，A是一个N*N的变换矩阵。A的元素是：</p>
<p>A(i,j) = C(i) * cos [(2j+1)*i*PI]/2N<br>C(i)=&nbsp;&nbsp; N^(-1/2)&nbsp;i=0<br>&nbsp;(2/N)^(-1/2)&nbsp;i&gt;0</p>
<p>一个二维DCT的输出是一组N*N的系数，它表示了图像在DCT域中的块数据，这些系数可以被想成是一组标准基的&#8221;权&#8220;值。任何图像块都可以由编合所有的N*N标准基来重组，通过这些基乘以相应的权因素值(系数）。</p>
<p>例2 图像块的DCT系数<br>一个选定的4*4的块，以及DCT系数。这种用DCT域表示块的方法的优点不是很明显的，因为并没有减少存储的空间，原来我们存16个像素值，我们现在成了需要存16个DCT系数。DCT的实用性当块被从系数的一个子集中构建出来的时候表现了出来：</p>
<p>把除去一些很大的值之外的所有的系数设为0，执行IDCT之后的结果如下图：在IDCT之前加入更多的系数可以形成渐近的更加准确的对原图的重建。这样，就可能从从一个子集的系数集中近似于原始的图像。删除系数中的小系数值（比如说通过量化）可以让图像数据在更少的系数表示位中表示出来，尽管这样做会影响图像的质量。</p>
<p><br>3.4.2.3 小波<br>流行的"小波变换"要(基于一系列系数与离散小波函数相等的滤波器来进行图像压缩的一种广泛使用的方法).一个应用于有N个采样结果的离散信号的离散小波变换的基本运行过程如下.一对滤波器被用来把信号分解为一个低频部分(L)和一个高频部分(H).每个波段由因子2被子采样化，这样这两个频率波都含有N/2个采样点。如果正确选择了滤波器的话，这个操作过程是可逆的。</p>
<p>这种方法可以被扩展应用到一个二维的信号上，比如说灰度图中。一个2D图的每一行都被经过低通和高通的滤波(Lx和Hx)，每个滤波器的输出被下采样用来制造中间图像L和H。L是原始图象的低通滤波，并通过在x方向进行下采样的结果.H是原图像的高通滤波并在x方向的下采样结果。接下来，这些新图的每一列都使用低和高通的滤波器(Ly和Hy)，并经过下采样来制造出四个子图象(LL,LH,HL,HH)。这四个子图象可以被组合为与原图的采样数相同的图象。LL是原图通过在水平和垂直方向经过低通，并用因素2进行子采样的结果。HL是通过在垂直方向经过高通滤波并包含了剩余垂直频率的结果。LH是通过在水平方向高通滤波并包含了剩余的水平频的结果，而HH是通过在水平和垂直两个方向进行高通滤波的结果。它们之间，四个图像包含了所有的原始图像的信息，但是LH,HL,HH的稀疏性使它们更加容易压缩。</p>
<p>在图像压缩程序中，二维的小波分解被继续应用到LL图中，来组成四个新的子图。得到的新的低通图象继续被得到子图象。很多高频的采样结果都是接近0的，它就可以通过把小值来移除来达到更优化的传输。在解码端，原图像通过上采样，滤波和加值被重建。</p>
<p>3.4.3 量化<br>量化器把一个在值域X的信号量化减为到值域Y中。使用更小的位来表示量化后的信号是可行的，因为转换后的值域比原来更小了。一个标量的量化器把输入的信号映射到一个量化的输出值域中，而一个向量的量化器把一组输入采样值映射到一组量化值中。</p>
<p>3.4.3.1 标量量化<br>标量量化的一个简单的例子就是把小数近似到最近的整数上，比如，从R到Z的映射。这个过程是有损的(不可逆的)因为它是无法从被近似后的结果来恢复出原来的小数的。</p>
<p>一个量化的更加通用的例子就是:<br>FQ = round (X/QP)<br>Y=FQ * QP</p>
<p>这里QP是量化的步长。量化输出级间隔单一的QP间断值。</p>
<p>在图像或视频的CODEC中，量化操作通常由两部分构成：编码端的前向量化FQ，和解码端的反量化(IQ).（事实上量化是不可逆的，这样用一个更准确的叫法的话：标量器和重标量器。在两个标量值之间的QP步长是一个重要的参数。如果步长很长的话，那么量化值的范围就很小，这样的话就可以在传输过程中被更有效地被表示(高压缩比地压缩).但是重量化值是原信号值的近似。如果步长很小的话，重量化值与原始信号更加匹配，但是量化值就落到一个更大的范围之内，就降低了压缩的效率。</p>
<p><br>量化可以被用来在像DCT或小波变换之后，除去了小系数之后降低图像数据的精确度。一个图像或视频的前向量化器设计为映射小系数值到0而保留一部分大系数值。前向量化器的输出通常是一个稀疏的量化系数的数组，大都为0。</p>
<p>3.4.3.2 向量量化<br>一个向量量化器把一系列的输入数据(比如一块图像采样)映射到一个单值(codeword)，而在解码端，每个单值（codeword)都映射到一个对于原始输入数据的近似。这组向量保存在编码和解码端，被用来当作一个编码表。在图像压缩中一个典型的向量量化程序如下：</p>
<p>1. 把原始图像分区(比如M &#215; N像素块)<br>2. 从编码表中选择一个与当前区域最相近的向量<br>3. 把选定的向量的序号传给解码器<br>4. 在解码端，用选定的向量来重建一个原始图像的拷贝。</p>
<p>量化是被用在空间域中(比如说用向量量化过的图像采样组)，但是它也可以被用在运动补偿或变换数据中.向量量化设计中的关键问题包含编码表的设计和在编码表中有效都查找最优化的向量的问题。</p>
<p>3.4.4 重排列和零编码<br>量化过的变换系数需要被仔细编码来进行存储和传输。在基于变换的图像或视频编码器上，量化器的输出是一个稀疏的数组，它包含了一些非0的系数和很多的0值系数。重排（把非0系数进行重组）和有效地表示0系数要在熵编码前进行操作。这些过程在DCT和小波变换中被提到了。</p>
<p>3.4.4.1 DCT<br>系数分布<br>一块图像或剩余采样的大的DCT系数通常都是在DC(0,0）系数&#8220;低频&#8221;部分。DCT系数的非0系数都聚在上顶部系数，而分布在水平和垂直方向是大约对称的。对于剩余区域来说，聚集在DC位置的系数是歪斜的，比如说，更多的非0系数在左手边出现。这是因为区域图片在垂直方向有很强的高频成分(因为在垂直方向的子采样)，这样因为垂直频率的原因得到了更大的DCT系数。</p>
<p>扫描<br>在量化之后，块的DCT系数被重排以把非0系数进行组合，以使对于剩余0值的表示方法更加有效。优化的重组方法(扫描方法)依赖于非0DCT系数的分布情况。对于经典的一帧来说，合适的扫描方式应该是gzag法，它是从左上角的DC系数开始的.从DC系数开始，每一个量化的系数被拷贝到一维数组里面。非0系数在重排数列的最前端被重组，而在之后是很长序列的0值。</p>
<p>gzag扫描扫描方式对于一个域块可能并不是理想的，因为系数是歪斜分布的，那么一个修改后的扫描顺序可会是有效的，比如说左边的系数在右边系数扫描之前被扫描。</p>
<p><br>运行级编码<br>重排过程的输出是一个通常在开始端包含一个或多个簇的非0系数，后面的是一串0值系数。这些0值被编码而实现更优化的表示方法，比如说，通过表示一串0里面的数量来缩减表示位数等等。</p>
<p>例如：<br>输入数组：16,0,0,-3,5,6,0,0,0,0,-7, . . .<br>输出值：&nbsp; (0,16),(2,-3),(0,5),(0,6),(4,-7). . .</p>
<p>DCT系数高频部分常被量化为0，这样一个重排的块通常以一串0结尾。一个特殊情况是需要指出一个块中的最后一个非0系数。在所谓的二维运行级编码被使用。每一个运行级对被用上面的方式进行编码，而一个单独的编码符号"last"，用来指出最后一个0值的位置。如果三维的运行级编码被使用的话，每个符号编码要编三个量化值：运行度，级数以及最后非0值。如上例就可以写为：<br>(0, 16, 0), (2,-3, 0), (0, 5, 0), (0, 6, 0), (4,-7, 1)</p>
<p>最后一个码中的1表示这是这个块中最后一个非0值。</p>
<p>3.4.4.2 小波<br>系数分布<br>很多在高子波中的系数（右下方的系数值）都是接近于0值的，可以被量化到0而不损失图像的质量。非0系数对应于图像的结构，比如说，在violin图中，弓就有很清晰的垂直结构。当低频中的系数是非0时，有很大的可能性在高频相应的系数也是0。这们设想一个非0的量化系数树，以在低频中根部开始。在第一层的一个单个LL的系数在其他的第一层有相应的系数值。第一层系数位置映射到四个相应的子段的同一位置的系数位置.</p>
<p>零树编码<br>在熵编码之前越好地编码非0小波系数就越好.达到这一点的一个有效的方法就是从最低层开始编码每个非0系数树.最低层的系数需要被编码,接着是它在高层的子系数,如此反复.编码过程在树达到0值系数的时候一直运行.之后的的全0值的层的子层值都为0.在解码端,重建过程从树根开始,非0系数被解码并重建,当遇到零树的时候,所有的剩余的子结点都被设为0.这嵌入零树(EZW)的小波系数编码方法.编码过程包含一种其他的可能性,0值系数可能跟着(a)一个零树(就像原来那样),或(b)一个非零的子系数阵.(b)不常发生,但是如果考虑到这些不常发生的情况的时候,重建图像的质量会被轻微地提高.</p>
</div>
<img src ="http://www.cnitblog.com/zouzheng/aggbug/38450.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2008-01-04 14:41 <a href="http://www.cnitblog.com/zouzheng/articles/38450.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>S3C2410平台上支持NAND boot的u-boot移植和共享</title><link>http://www.cnitblog.com/zouzheng/articles/38385.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Wed, 02 Jan 2008 07:26:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/38385.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/38385.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/38385.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/38385.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/38385.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 12pt">S3C2410平台上支持NAND boot的u-boot移植和共享<br>--luofuchong大侠</p>
小弟现有一个可用的nand flash启动的u-boot源代码愿意分享，具体下载地址如下： <br>　　<a href="http://www.hhcn.org/maindoc/nandboot-2410-luofuchong.rar">http://www.hhcn.org/maindoc/nandboot-2410-luofuchong.rar</a> 在此感谢华恒斑竹hn的帮助和提供空间^_^。<br>　　小弟不敢贪功，先注明一下这个源码的出处： 补丁来源于以下网站： <br>　　<a href="http://linux.insigma.com.cn/devbbs/dispbbs.asp?boardID=15&amp;ID=382&amp;page=1" target=_blank>http://linux.insigma.com.cn/devbbs/dispbbs.asp?boardID=15&amp;ID=382&amp;page=1</a><br>　　其实这个补丁早就下载了，但小弟不懂cvs的用法，怕麻烦一直没下载其对应版本的源码（在这里的显示版本虽然是1.1.4，但可是经过多人修改的，所以和官方的版本相差甚远）。 <br>　　后来我哥把它下载下来，于是就抽空把它编译了一下，串口居然有输出，兴致来了，花了几天搞了一下，现在基本可以用了。<br><br>这是cvs下载源码的方法： <br>cvs -d:pserver:anonymous@u-boot.cvs.sourceforge.net:/cvsroot/u-boot login <br>cvs -z3 -d:pserver:anonymous@u-boot.cvs.sourceforge.net:/cvsroot/u-boot co -D 20060523 -P u-boot <br>我经已经试过可以下载的了，不过最好晚上再下载成功率会高一点^_^ <br>登录的时候提示密码的时候直接按回车就行。<br><br>在些说一下这几天编译的经验： <br>1）打上补丁的过程中提示2、3个文件有些地方未能正常打补丁，但不影响编译。 <br>2）要用2.95.3的交叉编译器来编译，我试过用3.3.2的编译器来编译通过，但nand flash检测的那段代码没有运行，导致nand flash检测不出来，这可花了我不少的时间~_~ <br>3）附上的补丁是我修改过的（主要是一些提示信息和env地址的修改），打补丁的方法如下（假如你把补丁放到u-boot目录下）： <br><br>代码：<br>---------------------------------------------------------------------------------------------<br>patch -p1 &lt;u-boot-lfc.patch <br>---------------------------------------------------------------------------------------------<br>好了，下面介绍一下这个u-boot的用法： <br>U-Boot 1.1.4 (Oct 23 2006 - 22:04:37)<br><br>U-Boot code: 33F80000 -&gt; 33F9DC98 BSS: -&gt; 33FA2308 <br>RAM Configuration: <br>Bank #0: 30000000 64 MB <br>Nor Flash: 512 kB <br>Nand Flash: 64 MB <br><br>In: serial <br>Out: serial <br>Err: serial <br>Hit any key to stop autoboot: 0<br><br>sbc2410=&gt; printenv <br>bootargs=noinitrd root=/dev/mtdblock/3 console=ttySAC0 <br>bootdelay=3 <br>baudrate=115200 <br>ethaddr=08:00:3e:26:0a:5b <br>bootfile="zImage" <br>filesize=13469c <br>fileaddr=30008000 <br>netmask=255.255.255.0 <br>ipaddr=192.168.1.128 <br>serverip=192.168.1.15 <br>bootcmd=nand read 30008000 30000 1d0000;go 30008000 <br>stdin=serial <br>stdout=serial <br>stderr=serial <br>Environment size: 319/65532 bytes<br><br>sbc2410=&gt; nand <br>nand - NAND sub-system <br>info - show available NAND devices <br>nand device [dev] - show or set current device <br>nand read[.jffs2[s] addr off size <br>nand write[.jffs2] addr off size - read/write `size' bytes starting at offset `off' to/from memory address `addr' <br>nand erase [clean] [off size] - erase `size' bytes from offset `off' (entire device if not specified) <br>nand bad - show bad blocks <br>nand read.oob addr off size - read out-of-band data <br>nand write.oob addr off size - read out-of-band data<br><br>注：这是对nand flash操作的命令，我修改过源码好让它提示出来（默认好像没有提示）<br>按照提示应该都会它的用法了吧？不过在此还是举一个烧写内核的例子吧：<br>sbc2410=&gt; tftp <br>TFTP from server 192.168.1.15; our IP address is 192.168.1.128 <br>Filename 'zImage'. <br>Load address: 0x30008000 <br>Loading: ################################################################# <br>################################################################# <br>################################################################# <br>#################################################### <br>done <br>Bytes transferred = 1263260 (13469c hex) <br>注：可以看出，网络也是好的^_^ <br><br>sbc2410=&gt; nand erase 30000 1d0000 <br>NAND erase: device 0 offset 196608, size 1900544 ... OK<br><br>sbc2410=&gt; nand write 30008000 30000 1d0000 <br>NAND write: device 0 offset 196608, size 1900544 ... 1900544 bytes written: OK <br><br>OK，现在内核已经写入nand flash了，想开机引导它？<br><br>sbc2410=&gt; setenv bootcmd nand read 30008000 30000 1d0000\;go 30008000 <br>sbc2410=&gt; saveenv <br>Saving Environment to NAND... <br>Erasing Nand...Writing to Nand... done<br><br>这样就可以了。好了，现在按一下你的复位键试试： <br>U-Boot 1.1.4 (Oct 23 2006 - 21:28:24) <br><br>U-Boot code: 33F80000 -&gt; 33F9DC88 BSS: -&gt; 33FA22F8 <br>RAM Configuration: <br>Bank #0: 30000000 64 MB <br>Nor Flash: 512 kB <br>Nand Flash: 64 MB<br><br>In: serial <br>Out: serial <br>Err: serial <br>Hit any key to stop autoboot: 0<br><br>NAND read: device 0 offset 196608, size 1900544 ... 1900544 bytes read: OK <br>## Starting application at 0x30008000 ... <br>Uncompressing Linux................................................................................. done, booting the kernel. <br>Linux version 2.6.14 (root@luofuchong) (gcc version 3.4.1) #21 Fri Oct 20 17:20:39 CST 2006 <br>CPU: ARM920Tid(wb) [41129200] revision 0 (ARMv4T) <br>Machine: SMDK2410 <br>ATAG_INITRD is deprecated; please update your bootloader. <br>Memory policy: ECC disabled, Data cache writeback <br>CPU S3C2410A (id 0x32410002) <br>S3C2410: core 202.800 MHz, memory 101.400 MHz, peripheral 50.700 MHz <br>S3C2410 Clocks, (c) 2004 Simtec Electronics <br>CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on <br>USB Control, (c) 2006 sbc2410 <br>CPU0: D VIVT write-back cache <br>CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets <br>CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets <br>Built 1 zonelists <br>Kernel command line: noinitrd root=/dev/mtdblock/3 console=ttySAC0 <br>irq: clearing subpending status 00000002 <br>PID hash table entries: 512 (order: 9, 8192 bytes) <br>timer tcon=00500000, tcnt a509, tcfg 00000200,00000000, usec 00001e4c <br>Console: colour dummy device 80x30 <br>Dentry cache hash table entries: 16384 (order: 4, 65536 bytes) <br>Inode-cache hash table entries: 8192 (order: 3, 32768 bytes) <br>Memory: 64MB = 64MB total <br>Memory: 62208KB available (1924K code, 529K data, 108K init) <br>Mount-cache hash table entries: 512 <br>CPU: Testing write buffer coherency: ok <br>softlockup thread 0 started up. <br>NET: Registered protocol family 16 <br>S3C2410: Initialising architecture <br>SCSI subsystem initialized <br>usbcore: registered new driver usbfs <br>usbcore: registered new driver hub <br>S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics <br>DMA channel 0 at c4800000, irq 33 <br>DMA channel 1 at c4800040, irq 34 <br>DMA channel 2 at c4800080, irq 35 <br>DMA channel 3 at c48000c0, irq 36 <br>NetWinder Floating Point Emulator V0.97 (double precision) <br>devfs: 2004-01-31 Richard Gooch (rgooch@atnf.csiro.au) <br>devfs: devfs_debug: 0x0 <br>devfs: boot_options: 0x1 <br>yaffs Oct 18 2006 12:39:51 Installing. <br>Console: switching to colour frame buffer device 30x40 <br>fb0: s3c2410fb frame buffer device <br>fb1: Virtual frame buffer device, using 1024K of video memory <br>led driver initialized <br>s3c2410 buttons successfully loaded <br>s3c2410_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2410 <br>s3c2410_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2410 <br>s3c2410_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2410 <br>io scheduler noop registered <br>io scheduler anticipatory registered <br>io scheduler deadline registered <br>io scheduler cfq registered <br>RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize <br>usbcore: registered new driver ub <br>Cirrus Logic CS8900A driver for Linux (Modified for SMDK2410) <br>eth0: CS8900A rev E at 0xe0000300 irq=53, no eeprom , addr: 08: 0:3E:26:0A:5B <br>S3C24XX NAND Driver, (c) 2004 Simtec Electronics <br>s3c2410-nand: mapped registers at c4980000 <br>s3c2410-nand: timing: Tacls 10ns, Twrph0 30ns, Twrph1 10ns <br>NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit) <br>Scanning device for bad blocks <br>Bad eraseblock 1884 at 0x01d70000 <br>Creating 4 MTD partitions on "NAND 64MiB 3,3V 8-bit": <br>0x00000000-0x00020000 : "vivi" <br>0x00020000-0x00030000 : "param" <br>0x00030000-0x00200000 : "kernel" <br>0x00200000-0x04000000 : "root" <br>usbmon: debugfs is not available <br>s3c2410-ohci s3c2410-ohci: S3C24XX OHCI <br>s3c2410-ohci s3c2410-ohci: new USB bus registered, assigned bus number 1 <br>s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000 <br>hub 1-0:1.0: USB hub found <br>hub 1-0:1.0: 2 ports detected <br>Initializing USB Mass Storage driver... <br>usbcore: registered new driver usb-storage <br>USB Mass Storage support registered. <br>usbcore: registered new driver usbmouse <br>drivers/usb/input/usbmouse.c: v1.6:USB HID Boot Protocol mouse driver <br>mice: PS/2 mouse device common for all mice <br>s3c2410 TouchScreen successfully loaded <br>UDA1341 audio driver initialized <br>NET: Registered protocol family 2 <br>IP route cache hash table entries: 1024 (order: 0, 4096 bytes) <br>TCP established hash table entries: 4096 (order: 2, 16384 bytes) <br>TCP bind hash table entries: 4096 (order: 2, 16384 bytes) <br>TCP: Hash tables configured (established 4096 bind 4096) <br>TCP reno registered <br>TCP bic registered <br>NET: Registered protocol family 1 <br>Root-NFS: No NFS server available, giving up. <br>VFS: Unable to mount root fs via NFS, trying floppy. <br>yaffs: dev is 32505859 name is "mtdblock3" <br>yaffs: Attempting MTD mount on 31.3, "mtdblock3" <br>block 1757 is bad <br>VFS: Mounted root (yaffs filesystem). <br>Mounted devfs on /dev <br>Freeing init memory: 108K<br><br>init started: BusyBox v1.1.3 (2006.09.20-14:52+0000) multi-call binary <br>Starting pid 695, console /dev/tts/0: '/etc/init.d/rcS' <br>Please press Enter to activate this console. <br>注：这就是在我的板上的启动信息了^_^ <br><br>遗留的问题： <br>1：这个u-boot只提供jffs2文件系统的烧写功能（具体未用过，因为我只搞过yaffs文件系统~_~），没有对yaffs文件系统的烧写支持，我想这部分就留给各位去做吧^_^ <br>2：好像用同样的方法来启动2.4内核解压后内核不能启动，但2.6内核就可以，具体不知道原因，知道的朋友请告知并把修改好的补丁共享，发挥一下共享精神，谢谢！<br><br>原文地址 <a href="http://www.hhcn.org/s3c2410_u-boot.htm" target=_blank>http://www.hhcn.org/s3c2410_u-boot.htm</a> 
<img src ="http://www.cnitblog.com/zouzheng/aggbug/38385.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2008-01-02 15:26 <a href="http://www.cnitblog.com/zouzheng/articles/38385.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>QTE与触摸屏(转http://onebyte.21ic.org/）</title><link>http://www.cnitblog.com/zouzheng/articles/25337.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Thu, 05 Apr 2007 11:05:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/25337.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/25337.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/25337.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/25337.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/25337.html</trackback:ping><description><![CDATA[QTE触摸屏加载有两种方法：
<p>（<span style="font-family: AR PL ZenKai Uni,serif;">1</span>）<span style="font-family: AR PL ZenKai Uni,serif;">QTE</span>本身触摸屏加载；</p>
<p><span style="font-family: AR PL ZenKai Uni,serif;">	</span>主要注意三个内容：</p>
<ol type="i">
    <li>
    <p>编译<span style="font-family: AR PL ZenKai Uni,serif;">QTE</span>时，在其自定义配置文件（位于<span style="font-family: AR PL ZenKai Uni,serif;">QTDIR/src/tools/qconfig-XXX.h</span>，其<span style="font-family: AR PL ZenKai Uni,serif;">XXX</span>为自定义的名字，该特征字可以在<span style="font-family: AR PL ZenKai Uni,serif;">configure</span>时用<span style="font-family: AR PL ZenKai Uni,serif;">-qconfig
    XXX</span>指定）所应加的内容：</p>
    <p><span style="font-family: AR PL ZenKai Uni,serif;">#define QT_QWS_IPAQ</span></p>
    <p><span style="font-family: AR PL ZenKai Uni,serif;">#define QT_QWS_IPAQ_RAW</span></p>
    <p>去掉鼠标自动识别功能 ：<span style="font-family: AR PL ZenKai Uni,serif;">#define
    QT_NO_QWS_MOUSE_AUTO</span></p>
    <p>去掉不用的鼠标驱动，（在实际中，这一步可以不要，但对于缩减<span style="font-family: AR PL ZenKai Uni,serif;">QTE</span>的大小很有帮助），方法主要是在<span style="font-family: AR PL ZenKai Uni,serif;">configure</span>时设置配置参数为<span style="font-family: AR PL ZenKai Uni,serif;">-no-mouse-pc
    -no-mouse-bus -no-mouse-yopy -no-mouse-vr41xx </span>。</p>
    <p>以该编译好的<span style="font-family: AR PL ZenKai Uni,serif;">QTE</span>库为基础，编译应用程序；</p>
    </li>
    <li>
    <p>
    在目标机上，要将触摸屏驱动链接好。在<span style="font-family: AR PL ZenKai Uni,serif;">QTE3.0</span>的版本中，如果定义了上述的两个<span style="font-family: AR PL ZenKai Uni,serif;">IPAQ</span>相关的宏，其默认打开设备文件<span style="font-family: AR PL ZenKai Uni,serif;">/dev/h3600_tsraw</span>。如果只定义<span style="font-family: AR PL ZenKai Uni,serif;">QT_QWS_IPAQ</span>，则打开设备文件为<span style="font-family: AR PL ZenKai Uni,serif;">/dev/h3600_ts</span>。</p>
    </li>
    <li>
    <p> 在目标机上，设定环境变量：<span style="font-family: AR PL ZenKai Uni,serif;">QWS_MOUSE_PROTO=linuxtp:/dev/h3600_tsraw</span>。</p>
    </li>
</ol>
<p>（<span style="font-family: AR PL ZenKai Uni,serif;">2</span>）使用<span style="font-family: AR PL ZenKai Uni,serif;">tslib</span>方法；</p>
<ul>
    <li>
    <p>编译<span style="font-family: AR PL ZenKai Uni,serif;">TSLIB1.3</span>：</p>
    <ul>
        <li>
        <p>进行如下操作</p>
        </li>
    </ul>
    </li>
</ul>
<ul>
    <ul>
        <ul>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">#./autogen.sh
            #</span>生成<span style="font-family: AR PL ZenKai Uni,serif;">configure</span>文件</p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">CC=
            $ARM_TOOL_PATH/arm-linux-gcc</span></p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">CXX=
            $ARM_TOOL_PATH/arm-linux-g++ </span>
            </p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">./configure	--host=arm-linux
            --target=arm-linux --disable-inputapi --prefix=$PWD/build </span>
            </p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">make</span></p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">make install</span></p>
            </li>
        </ul>
        <li>
        <p>将<span style="font-family: AR PL ZenKai Uni,serif;">build</span>的整个目录拷贝到目标机，然后在目标机做如下设定，修改<span style="font-family: AR PL ZenKai Uni,serif;">/etc/profile</span>文件，在其中加入以下环境变量的设置</p>
        <ul>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">export
            V_ROOT=/xxx/xxx/build  #</span>目标机上<span style="font-family: AR PL ZenKai Uni,serif;">build</span>所在的路径</p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">export
            TSLIB_TSEVENTTYPE=H3600
            #</span>设定类型为<span style="font-family: AR PL ZenKai Uni,serif;">H3600</span>，其主要是对着<span style="font-family: AR PL ZenKai Uni,serif;">tslib</span>中的设备结构体定义，该定义要与触摸屏驱动中的一致</p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">export
            TSLIB_CONSOLEDEVICE=none
            #</span>设定控制台设备为<span style="font-family: AR PL ZenKai Uni,serif;">none</span>，否则默认为<span style="font-family: AR PL ZenKai Uni,serif;">/dev/tty</span>。在<span style="font-family: AR PL ZenKai Uni,serif;">tslib1.3</span>源码中，只要不是<span style="font-family: AR PL ZenKai Uni,serif;">none</span>，它就会打开<span style="font-family: AR PL ZenKai Uni,serif;">$(TSLIB_CONSOLEDEVICE)1</span>，默认的为<span style="font-family: AR PL ZenKai Uni,serif;">/dev/tty1</span>的设备，然后从中读取<span style="font-family: AR PL ZenKai Uni,serif;">console</span>的可用设置。这样可以避免出现&#8220;<span style="font-family: AR PL ZenKai Uni,serif;">open
            consoledevice: No such file or directory KDSETMODE: Bad file
            descriptor&#8221;</span>的错误</p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">export
            TSLIB_FBDEVICE=/dev/fb0  #</span>指定帧缓冲设备</p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">export
            TSLIB_TSDEVICE=/dev/touchscreen/0raw  #</span>指定触摸屏设备节点文件</p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">export
            TSLIB_CALIBFILE=$V_ROOT/etc/pointercal  #</span>指定触摸屏校准文件<span style="font-family: AR PL ZenKai Uni,serif;">pintercal</span>的存放位置</p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">export
            TSLIB_CONFFILE=$V_ROOT/etc/ts.conf  #</span>指定<span style="font-family: AR PL ZenKai Uni,serif;">TSLIB</span>配置文件的位置</p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">export
            TSLIB_PLUGINDIR=$V_ROOT/share/ts/plugins  #</span>指定触摸屏插件所在路径</p>
            </li>
        </ul>
        </li>
    </ul>
    <li>
    <p>编译<span style="font-family: AR PL ZenKai Uni,serif;">TSLIB1.4</span>（<span style="font-family: AR PL ZenKai Uni,serif;">TSLIB07072006</span>）</p>
    <ul>
        <li>
        <p>进行如下操作：</p>
        <ul>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">echo
            "ac_cv_func_malloc_0_nonnull=yes" &gt;
            tslib/arm-linux.autogen   #</span>为了防止出现<span style="font-family: AR PL ZenKai Uni,serif;">undefined
            reference to `rpl_malloc' </span>错误</p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">CONFIG_SITE=arm-linux.autogen
            ./configure CC=arm-linux-gcc CXX=arm-linux-g++
            --host=arm-s3c2410-linux-gnu --target=arm-s3c2410-linux-gnu
            --disable-input --disable-arctic2 --disable-mk712 --disable-collie
            --disable-corgi --disable-ucb1x00 --disable-linear-h2200
            --with-gnu-ld --prefix=$PWD/build</span></p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">make</span></p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">make install</span></p>
            </li>
        </ul>
        </li>
        <li>
        <p>将<span style="font-family: AR PL ZenKai Uni,serif;">build</span>的整个目录拷贝到目标机，然后在目标机做如下设定，修改<span style="font-family: AR PL ZenKai Uni,serif;">/etc/profile</span>文件，在其中加入以下环境变量的设置。其解释类上，不同于<span style="font-family: AR PL ZenKai Uni,serif;">TSLIB1.3</span>的是，<span style="font-family: AR PL ZenKai Uni,serif;">TLIB1.4</span>通过配置文件<span style="font-family: AR PL ZenKai Uni,serif;">ts.conf</span>中<span style="font-family: AR PL ZenKai Uni,serif;">module_raw
        h3600</span>语句来加载对应的设备结构体定义。已废除了<span style="font-family: AR PL ZenKai Uni,serif;">TSLIB_TSEVENTTYPE</span>宏。</p>
        <ul>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">export
            V_ROOT=/xxx/xxx/build  </span>
            </p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">export
            TSLIB_TSDEVICE=/dev/touchscreen/0raw</span></p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">export
            TSLIB_CALIBFILE=/etc/pointercal</span></p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">export
            TSLIB_CONFFILE=$V_ROOT/etc/ts.conf</span></p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">export
            TSLIB_PLUGINDIR=$V_ROOT/lib/ts</span></p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">export
            TSLIB_CONSOLEDEVICE=none</span></p>
            </li>
            <li>
            <p><span style="font-family: AR PL ZenKai Uni,serif;">export
            TSLIB_FBDEVICE=/dev/fb0</span></p>
            </li>
        </ul>
        </li>
        <li>
        <p>一个值得注意的问题是：<span style="font-family: AR PL ZenKai Uni,serif;">TSLIB1.4</span>在<span style="font-family: AR PL ZenKai Uni,serif;">ts_config</span>函数中通过<span style="font-family: AR PL ZenKai Uni,serif;">while((p=fgets(buf,BUFF_SIZE,f))!=NULL)</span>来加载<span style="font-family: AR PL ZenKai Uni,serif;">ts.conf</span>中的语句，而<span style="font-family: AR PL ZenKai Uni,serif;">buf</span>只有<span style="font-family: AR PL ZenKai Uni,serif;">512byte</span>。所以对于<span style="font-family: AR PL ZenKai Uni,serif;">ts.conf</span>没有用的定义语句，请将其删除，以防止误发生段错误。</p>
        </li>
    </ul>
    </li>
    <li>
    <p>以<span style="font-family: AR PL ZenKai Uni,serif;">TSLIB</span>库为基础，编译<span style="font-family: AR PL ZenKai Uni,serif;">QTE</span>。</p>
    <ul>
        <li>
        <p><span style="font-family: AR PL ZenKai Uni,serif;">QTE2.3.10</span>直接支持<span style="font-family: AR PL ZenKai Uni,serif;">-tslib</span>选项开关的应用。不用修改任何文件。可以通过网上所说的拷贝<span style="font-family: AR PL ZenKai Uni,serif;">tslib.h</span>头文件及库文件到<span style="font-family: AR PL ZenKai Uni,serif;">QTE</span>相关目录来进行编译（对于<span style="font-family: AR PL ZenKai Uni,serif;">tslib1.4</span>，还要拷贝<span style="font-family: AR PL ZenKai Uni,serif;">tslib_private.h</span>）。也可以在<span style="font-family: AR PL ZenKai Uni,serif;">./configure</span>进指定<span style="font-family: AR PL ZenKai Uni,serif;">-L&lt;path
        to tslib library&gt; -I&lt;path to tslib header&gt;</span>来防止出现找不到相应库文件
        的错误。（对于<span style="font-family: AR PL ZenKai Uni,serif;">tslib1.4</span>，应该还加上<span style="font-family: AR PL ZenKai Uni,serif;">-lts</span>选项）。</p>
        </li>
        <li>
        <p>对于其它版本的<span style="font-family: AR PL ZenKai Uni,serif;">QTE</span>，可以通过在<span style="font-family: AR PL ZenKai Uni,serif;">QTE</span>文件夹路径下执行<span style="font-family: AR PL ZenKai Uni,serif;">grep
        -lir 'tslib'
        *</span>来查看是否有对<span style="font-family: AR PL ZenKai Uni,serif;">tslib</span>的支持，如果没有则需要对源码进行相应的修改。（<span style="font-family: AR PL ZenKai Uni,serif;">onebyte</span>注：虽然网上说有补丁可下，但俺一直没找到相关的<span style="font-family: AR PL ZenKai Uni,serif;">patch</span>，但看看<span style="font-family: AR PL ZenKai Uni,serif;">QTE2.3.10</span>的源码后再做相应的修改还算比较方便：）</p>
        </li>
    </ul>
    </li>
</ul>
<p><br><br>
</p>
<p><span style="font-weight: bold;">［</span><span style="font-weight: bold; font-family: AR PL ZenKai Uni,serif;">onebyte</span><span style="font-weight: bold;">后记］</span>：</p>
<p><span style="font-family: AR PL ZenKai Uni,serif;">	</span>由于是一个人在做基于<span style="font-family: AR PL ZenKai Uni,serif;">embedded
linux</span>的软件开发，没有他人直接的交流，所以摸索<span style="font-family: AR PL ZenKai Uni,serif;">QTE</span>触摸屏支持的过程是相当辛苦的！网上关于这一块的说法不一，使得自己对<span style="font-family: AR PL ZenKai Uni,serif;">QTE</span>触摸屏支持的方法很长时间辨不清方向。但在这里还是要非常感谢网上的许多朋友，正是通过大家的讨论才将这块内容逐渐理通。</p>
<p><span style="font-family: AR PL ZenKai Uni,serif;">	</span>在这里特将这些方法记载下来，送给同我一样经历过困惑的朋友们：<span style="font-family: AR PL ZenKai Uni,serif;">P</span></p>
<p>［参考网站］</p>
<p><span style="font-family: AR PL ZenKai Uni,serif;">	</span>网上各论坛中关于<span style="font-family: AR PL ZenKai Uni,serif;">TSLIB</span>内容的帖子不少，这里只记一些主要的论坛网站，有兴趣的可以到这上面去看看：</p>
<p><span style="font-family: AR PL ZenKai Uni,serif;">[1]  </span><a  href="http://kiss.bitunion.org/forumdisplay.php?fid=113&amp;sid=WcnNGjWX">北京理工大学嵌入式<span style="font-family: AR PL ZenKai Uni,serif;">linux
BBS</span></a></p>
<p><span style="font-family: AR PL ZenKai Uni,serif;">[2] </span><a  href="http://www.hhcn.com/cgi-bin/leoboard.cgi">华恒嵌入论坛</a></p>
<p><span style="font-family: AR PL ZenKai Uni,serif;">[3] <a  href="http://www.qtcn.org/bbs/">Qt</a></span><a  href="http://www.qtcn.org/bbs/">中文论坛</a></p>
<p><span style="font-family: AR PL ZenKai Uni,serif;">[4] <a  href="http://www.qtforum.org/index.html">QT
Forum</a></span></p>
<p><span style="font-family: AR PL ZenKai Uni,serif;">[5] <a  href="http://www.linuxforum.net/">China
Linux Forum</a></span></p>
<p><br><span style="font-family: AR PL ZenKai Uni,serif;"></span></p>
<p><a  href="http://www.linuxforum.net/">onebyte注：前一阵子简略地分析了一下QT中触摸屏相关文件，现在把它共享出来。希望能对志同道合的朋友有所帮助：P<br><br>－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br>
</a></p>
<p style="margin-bottom: 0cm;">文件位于<span style="font-family: AR PL ZenKai Uni,serif;">QTDIR/src/embedded/</span>文件夹中。</p>
<p>（<span style="font-family: AR PL ZenKai Uni,serif;">1</span>）类结构示意图，如下图所示。</p>
<p><img  src="http://blog.21ic.com/uploadfile-/2006-12/1228521281.jpg" alt="类结构分析图" align="left" border="0"><br><span style="font-family: AR PL ZenKai Uni,serif;">	</span></p>
<p>（<span style="font-family: AR PL ZenKai Uni,serif;">2</span>）与触摸屏相关主要函数进行解释如下：</p>
<ul>
    <li>
    <p><span style="font-family: AR PL ZenKai Uni,serif;">QWSLinuxTPMouseHandlerPrivate</span>其构造函数</p>
    <p>在其中打开设备文件<span style="font-family: AR PL ZenKai Uni,serif;">/dev/h3600_tsraw</span>或<span style="font-family: AR PL ZenKai Uni,serif;">h3600_ts</span>或<span style="font-family: AR PL ZenKai Uni,serif;">ts</span>（视宏定义），并将其<span style="font-family: AR PL ZenKai Uni,serif;">readMouseData()</span>槽同<span style="font-family: AR PL ZenKai Uni,serif;">QSocketNotifier</span>的<span style="font-family: AR PL ZenKai Uni,serif;">activated</span>信号连接起来。</p>
    <p><span style="font-family: AR PL ZenKai Uni,serif;">QsocketNotifier</span>由所打开的设备文件号初始化。这样就可以将驱动中的事件同上层应用程序中的鼠标动作联系起来。</p>
    </li>
</ul>
<ul>
    <li>
    <p><span style="font-family: AR PL ZenKai Uni,serif;">QWSLinuxTPMouseHandlerPrivate::readMouseData()</span></p>
    <p>该函数读取设备文件<span style="font-family: AR PL ZenKai Uni,serif;">/dev/h3600_tsraw</span>或<span style="font-family: AR PL ZenKai Uni,serif;">h3600_ts</span>，视宏定义。并在其内部将触摸屏设备坐标（也就是电压值）通过其父类：<span style="font-family: AR PL ZenKai Uni,serif;">QWSCalibrateMouseHandler::transform()</span>函数转换为屏幕坐标。并取一定点的平均值。</p>
    </li>
    <li>
    <p><span style="font-family: AR PL ZenKai Uni,serif;">QWSCalibrateMouseHandler::transform()</span></p>
    <p>通过<span style="font-family: AR PL ZenKai Uni,serif;">a, b, c, d, e,
    f</span>转换参数将设备坐标转换为屏幕坐标。</p>
    </li>
    <li>
    <p><span style="font-family: AR PL ZenKai Uni,serif;">QWSCalibrateMouseHandler::Calibration()</span></p>
    <p>求取坐标转换系数及偏差（<span style="font-family: AR PL ZenKai Uni,serif;">a,
    b, c, d, e,
    f</span>，实际用的是二点校正法：左上及右下点。）。并调用<span style="font-family: AR PL ZenKai Uni,serif;">writeCalibration</span>将参数值输出到<span style="font-family: AR PL ZenKai Uni,serif;">/etc/pointcal</span>文件中。</p>
    </li>
    <li>
    <p><span style="font-family: AR PL ZenKai Uni,serif;">QWSCalibrateMouseHandler::readCalibration()</span></p>
    <p>从<span style="font-family: AR PL ZenKai Uni,serif;">/etc/pointcal</span>文件读取坐标转换系统及偏差。</p>
    </li>
</ul>
<p>（<span style="font-family: AR PL ZenKai Uni,serif;">3</span>）上述类都是通过<span style="font-family: AR PL ZenKai Uni,serif;">qmousedriverfatory</span>进行初始创建的。</p>
<br>
<p><br></p>
<p><span style="color: #ff0000;">［编译环境注：］</span><br>
</p>
<p style="font-weight: normal; color: #ff0000;">宿主机Linux操作系统为Fedro Core 5<br></p>
<p style="font-weight: normal; color: #ff0000;">交叉编译工具链版本：<span style="font-family: AR PL ZenKai Uni,serif;">arm-linux-g++
2.95.3</span>，</p>
<p style="font-weight: normal; color: #ff0000;">宿主机<span style="font-family: AR PL ZenKai Uni,serif;">编译工具链GCC
</span>版本为<span style="font-family: AR PL ZenKai Uni,serif;">4.1.0</span></p>
<p style="font-weight: normal; color: #ff0000;"><span style="font-family: AR PL ZenKai Uni,serif;">QT-X11版本为2.3.2</span></p>
<p style="font-weight: normal; color: #ff0000;"><span style="font-family: AR PL ZenKai Uni,serif;">QT/E版本为2.3.7</span></p>
<p><span style="font-family: AR PL ZenKai Uni,serif;"><span style="font-weight: normal; color: #ff0000;">QTOPIA版本为1.7.0</span></span></p>
<p><span style="font-family: AR PL ZenKai Uni,serif;"><span style="font-weight: normal; color: #ff0000;"></span><br></span></p>
<h3 class="cjk">（<span style="font-family: AR PL ShanHeiSun Uni,sans-serif;">1</span>）编译<span style="font-family: AR PL ShanHeiSun Uni,sans-serif;">QT-X11</span></h3>
<ul>
    <li>
    <p>解压<span style="font-family: AR PL ZenKai Uni,serif;">qt-x11-2.3.2.tar.gz</span>，并更改解压文件夹名为<span style="font-family: AR PL ZenKai Uni,serif;">qt-x11</span></p>
    </li>
    <li>
    <p><span style="font-family: AR PL ZenKai Uni,serif;">cd qt-x11</span></p>
    </li>
    <li>
    <p>更改<span style="font-family: AR PL ZenKai Uni,serif;">qt-x11</span>文件夹中<span style="font-family: AR PL ZenKai Uni,serif;">src/tools/qvaluestack.h</span>第<span style="font-family: AR PL ZenKai Uni,serif;">57</span>行源代码<span style="font-family: AR PL ZenKai Uni,serif;">remove(
    this-&gt;fromLast() );</span>为<span style="font-family: AR PL ZenKai Uni,serif;">this-&gt;remove(
    this-&gt;fromLast() );</span>否则，会出现<span style="font-family: AR PL ZenKai Uni,serif;">[<span style="color: #000000;">xml/qxml.o]</span></span><span style="font-size: 10pt; color: #000000;">错误</span></p>
    </li>
    <li>
    <p>建立<span style="font-family: AR PL ZenKai Uni,serif;">set-env</span>文件</p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export QTDIR=$PWD</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export PATH=$QTDIR/bin:$PATH</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export
    MANPATH=$QTDIR/doc/man:$MANPATH</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export
    LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">echo yes | ./configure
    -no-xft -no-opengl -no-sm</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">make</span></p>
    </li>
    <li>
    <p>在该文件夹下，执<span style="font-family: AR PL ZenKai Uni,serif;">"<span style="color: #800000;">source
    set-env</span>"</span>命令（<span style="font-family: AR PL ZenKai Uni,serif;">.</span>与<span style="font-family: AR PL ZenKai Uni,serif;">set-env</span>之间有空格）</p>
    </li>
</ul>
<br>
<h3 class="cjk">（<span style="font-family: AR PL ShanHeiSun Uni,sans-serif;">2</span>）编译目标机版本的<span style="font-family: AR PL ShanHeiSun Uni,sans-serif;">qte-2.3.7</span></h3>
<ul>
    <li>
    <p>为了编译<span style="font-family: AR PL ZenKai Uni,serif;">QTOPIA</span>，将<span style="font-family: AR PL ZenKai Uni,serif;">QTOPIA</span>文件夹下<span style="font-family: AR PL ZenKai Uni,serif;">./src/qt/qconfig-qpe.h</span>拷贝到<span style="font-family: AR PL ZenKai Uni,serif;">QTE</span>文件夹下
    <span style="font-family: AR PL ZenKai Uni,serif;">src/tools/</span></p>
    </li>
    <li>
    <p>然后建立<span style="font-family: AR PL ZenKai Uni,serif;">set-env</span>文件</p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">#!/bin/bash</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">#</span>编译<span style="font-family: AR PL ZenKai Uni,serif;">QTE</span>脚本</p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">#</span>此处<span style="font-family: AR PL ZenKai Uni,serif;">$PWD</span>指的是<span style="font-family: AR PL ZenKai Uni,serif;">QTE</span>所在的文件夹</p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export QTDIR=$PWD</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export QTEDIR=$QTDIR</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export PATH=$QTDIR/bin:$PATH</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export
    PATH=/usr/local/arm/2.95.3/bin:$PATH</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export
    LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">echo yes | ./configure
    -platform linux-x86-g++ -xplatform linux-arm-g++ -qconfig qpe
    -depths 16,24,32</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">make</span></p>
    </li>
    <li>
    <p>执行<span style="font-family: AR PL ZenKai Uni,serif;">"<span style="color: #800000;">source
    set-env</span>"</span></p>
    </li>
    <li>
    <p>注意，在此处<span style="font-family: AR PL ZenKai Uni,serif;">configure</span>时，一定要写明<span style="font-family: AR PL ZenKai Uni,serif;">platform</span>及<span style="font-family: AR PL ZenKai Uni,serif;">xplatform</span>，且<span style="font-family: AR PL ZenKai Uni,serif;">platform</span>要设为<span style="font-family: AR PL ZenKai Uni,serif;">linux-x86-g++</span>，否则当使用<span style="font-family: AR PL ZenKai Uni,serif;">linux-generic-g++</span>时，会找当前系统默认的<span style="font-family: AR PL ZenKai Uni,serif;">g++</span>，由于前面在<span style="font-family: AR PL ZenKai Uni,serif;">PATH</span>处设定新的<span style="font-family: AR PL ZenKai Uni,serif;">g++</span>路径，所以会出现错误。</p>
    </li>
</ul>
<ul>
    <li>
    <p>如果<span style="font-weight: bold;">需要移植到目标机上</span>，则将<span style="font-family: AR PL ZenKai Uni,serif;">$QTEDIR/lib/libqte.so.x.y.z</span>拷贝至目标机上<span style="font-family: AR PL ZenKai Uni,serif;">lib</span>文件夹下，并命名为<span style="font-family: AR PL ZenKai Uni,serif;">/lib/libqte.so.x</span>（根据前面的<span style="font-family: AR PL ZenKai Uni,serif;">libqte</span>编号而定）<span style="font-family: AR PL ZenKai Uni,serif;">;</span></p>
    <p>将<span style="font-family: AR PL ZenKai Uni,serif;">$QTEDIR/lib/fonts/fontdir</span>拷贝到目标机上<span style="font-family: AR PL ZenKai Uni,serif;">qt/e</span>的安装路径上（通过在目标机上设置<span style="font-family: AR PL ZenKai Uni,serif;">$QTDIR</span>来实现），如<span style="font-family: AR PL ZenKai Uni,serif;">/usr/local/qt-embedded/lib/fonts/fontdir</span></p>
    </li>
</ul>
<br>
<h3 class="cjk">（<span style="font-family: AR PL ShanHeiSun Uni,sans-serif;">3</span>）编译目标机版本的<span style="font-family: AR PL ShanHeiSun Uni,sans-serif;">qtopia-1.7.0</span></h3>
<ul>
    <li>
    <p>由于在编译<span style="font-family: AR PL ZenKai Uni,serif;">qtopia</span>时，需要用到<span style="font-family: AR PL ZenKai Uni,serif;">QTE</span>的<span style="font-family: AR PL ZenKai Uni,serif;">uic</span>命令来解释有关的资源，所以此处，需要将前面编译的<span style="font-family: AR PL ZenKai Uni,serif;">qt-x11</span>中<span style="font-family: AR PL ZenKai Uni,serif;">bin</span>目录下的<span style="font-family: AR PL ZenKai Uni,serif;">uic</span>命令拷贝至<span style="font-family: AR PL ZenKai Uni,serif;">QTEDIR/bin</span>下。</p>
    </li>
    <li>
    <p>建立<span style="font-family: AR PL ZenKai Uni,serif;">set-env</span>文件：</p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">#!/bin/bash</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">#</span>安装<span style="font-family: AR PL ZenKai Uni,serif;">QTOPIA</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export QPEDIR=$PWD</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">#</span>此处的<span style="font-family: AR PL ZenKai Uni,serif;">QTDIR</span>是前面编译的<span style="font-family: AR PL ZenKai Uni,serif;">QT/E</span>的路径</p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export
    QTDIR=/friendly-arm/arm-qtopia/qt</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export QTEDIR=$QTDIR</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">#</span>本机工具链的位置，根据个人情况设置</p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export
    PATH=/usr/local/arm/2.95.3/bin:$PATH</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export PATH=$QTDIR/bin:$PATH</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export
    PATH=$QPEDIR/bin:$PATH</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export
    LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">cd ./src</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">echo yes | ./configure
    -platform linux-arm-g++</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">make</span></p>
    </li>
    <li>
    <p>执行<span style="font-family: AR PL ZenKai Uni,serif;">"<span style="color: #800000;">source
    set-env</span>"</span></p>
    </li>
    <li>
    <p>如果<span style="font-weight: bold;">需要移植到目标机</span>上，将<span style="font-family: AR PL ZenKai Uni,serif;">QPEDIR</span>目录下的<span style="font-family: AR PL ZenKai Uni,serif;">bin,
    apps, etc, plugins, services, sounds, i18n, lib, pics,
    help</span>文件夹拷贝到目标机上的<span style="font-family: AR PL ZenKai Uni,serif;">QPEDIR</span>处（通过设置<span style="font-family: AR PL ZenKai Uni,serif;">QPEDIR</span>来实现）</p>
    </li>
    <li>
    <p>在目标机的<span style="font-family: AR PL ZenKai Uni,serif;">bin</span>目录下，建立<span style="font-family: AR PL ZenKai Uni,serif;">qtopia</span>脚本文件（如下）</p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">#!/bin/sh</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export set HOME=/root</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export set QTDIR=/opt/qt</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export set
    QPEDIR=/opt/qtopia</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export set
    QWS_KEYBOARD="USB:/dev/input/event1"</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export set
    QWS_MOUSE_PROTO="USB:/dev/input/mouse0"</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export set
    PATH=$QPEDIR/bin:$PATH</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">export set
    LD_LIBRARY_PATH=$QTDIR/lib:$QPEDIR/lib</span></p>
    <p style="color: #800000;"><span style="font-family: AR PL ZenKai Uni,serif;">$QPEDIR/bin/qpe &gt;
    /dev/null 2&gt;/dev/null</span></p>
    </li>
    <li>
    <p>在目标机启动后，就可以使用<span style="font-family: AR PL ZenKai Uni,serif;">qtopia</span>直接启动</p>
    </li>
</ul><img src ="http://www.cnitblog.com/zouzheng/aggbug/25337.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2007-04-05 19:05 <a href="http://www.cnitblog.com/zouzheng/articles/25337.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>gcc与gdb使用学习笔记</title><link>http://www.cnitblog.com/zouzheng/articles/25336.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Thu, 05 Apr 2007 11:00:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/25336.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/25336.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/25336.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/25336.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/25336.html</trackback:ping><description><![CDATA[今天学习了一下gcc与gdb的具体使用方法。并亲自用gdb调试了一下程序。gdb还是用不熟，只能以后慢慢加深体会了。（gdb刚开始用还真是不方便，也不知道如果做嵌入开发的话，有没有其它比较好的工具？如果有朋友知道，推荐一二，在此多谢啦！！）
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">1</span><span style="font-family: simsun;" lang="ZH-CN">、</span><span style="font-family: verdana;" lang="EN-US">GNU C</span><span style="font-family: simsun;" lang="ZH-CN">编译器（即</span><span style="font-family: verdana;" lang="EN-US">GCC</span><span style="font-family: simsun;" lang="ZH-CN">）</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">gcc -v </span><span style="font-family: simsun;" lang="ZH-CN">：</span><span style="font-family: verdana;" lang="EN-US">GCC</span><span style="font-family: simsun;" lang="ZH-CN">版本</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">-c</span><span style="font-family: simsun;" lang="ZH-CN">：仅把源代友编译为目标代码；</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">-s</span><span style="font-family: simsun;" lang="ZH-CN">：</span><span style="font-family: verdana;" lang="EN-US">GCC</span><span style="font-family: simsun;" lang="ZH-CN">在为</span><span style="font-family: verdana;" lang="EN-US">C</span><span style="font-family: simsun;" lang="ZH-CN">代码产生了汇编语言文件后，就停止编译。</span><span style="font-family: verdana;" lang="EN-US">GCC</span><span style="font-family: simsun;" lang="ZH-CN">产生的汇编语言文件的缺省扩展名为</span><span style="font-family: verdana;" lang="EN-US">.s</span><span style="font-family: simsun;" lang="ZH-CN">。</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">-E</span><span style="font-family: simsun;" lang="ZH-CN">：指示编译器仅对输入文件进行预处理。此时，预处理器的输出被送到标准输出（如显示器）而不是储存在文件里。</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">-O</span><span style="font-family: simsun;" lang="ZH-CN">：</span><span style="font-family: verdana;" lang="EN-US">GCC</span><span style="font-family: simsun;" lang="ZH-CN">对源码进行基本优化。</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">-O2</span><span style="font-family: simsun;" lang="ZH-CN">：</span><span style="font-family: verdana;" lang="EN-US">GCC</span><span style="font-family: simsun;" lang="ZH-CN">产生尽可能小和尽可能快的代码</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">-g</span><span style="font-family: simsun;" lang="ZH-CN">选项告诉</span><span style="font-family: verdana;" lang="EN-US">GCC</span><span style="font-family: simsun;" lang="ZH-CN">产生能被</span><span style="font-family: verdana;" lang="EN-US">GNU</span><span style="font-family: simsun;" lang="ZH-CN">调试器（如</span><span style="font-family: verdana;" lang="EN-US">gdb</span><span style="font-family: simsun;" lang="ZH-CN">）使用的调试信息，以便调试用户的程序。</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">-pg</span><span style="font-family: simsun;" lang="ZH-CN">选项告诉</span><span style="font-family: verdana;" lang="EN-US">GCC</span><span style="font-family: simsun;" lang="ZH-CN">在用户的程序里加入额外的代码，执行时，产生</span><span style="font-family: verdana;" lang="EN-US">gporf</span><span style="font-family: simsun;" lang="ZH-CN">用的剖析信息以显示程序的耗时情况。</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">gcc info page</span><span style="font-family: simsun;" lang="ZH-CN">：详细</span><span style="font-family: verdana;" lang="EN-US">GCC</span><span style="font-family: simsun;" lang="ZH-CN">编译器参数的说明，在</span><span style="font-family: verdana;" lang="EN-US">Emacs</span><span style="font-family: simsun;" lang="ZH-CN">内，按下</span><span style="font-family: verdana;" lang="EN-US">C</span><span style="font-family: simsun;" lang="ZH-CN">－</span><span style="font-family: verdana;" lang="EN-US">hi</span><span style="font-family: simsun;" lang="ZH-CN">，然后选&#8220;</span><span style="font-family: verdana;" lang="EN-US">gcc</span><span style="font-family: simsun;" lang="ZH-CN">&#8221;的选项。</span></p>
<p style="margin: 0in; font-size: 10pt; font-family: SimSun;">&nbsp;</p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">2</span><span style="font-family: simsun;" lang="ZH-CN">、使用</span><span style="font-family: verdana;" lang="EN-US">gdb</span><span style="font-family: simsun;" lang="ZH-CN">：</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">gdb filename</span><span style="font-family: simsun;" lang="ZH-CN">：能直接指定想要调试的程序。也可用</span><span style="font-family: verdana;" lang="EN-US">gdb</span><span style="font-family: simsun;" lang="ZH-CN">去检查一个因程序异常终止而产生的</span><span style="font-family: verdana;" lang="EN-US">core</span><span style="font-family: simsun;" lang="ZH-CN">文件，或者与一个正在运行的程序相连。</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: simsun;" lang="ZH-CN">（</span><span style="font-family: verdana;" lang="EN-US">1</span><span style="font-family: simsun;" lang="ZH-CN">）为使</span><span style="font-family: verdana;" lang="EN-US">gdb</span><span style="font-family: simsun;" lang="ZH-CN">正常工作，必须使程序在编译时包含调试信息。调试信息包含程序里的每个变量的类型、在可执行文件里的地址映射以及源代码的行号。</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: simsun;" lang="ZH-CN">（</span><span style="font-family: verdana;" lang="EN-US">2</span><span style="font-family: simsun;" lang="ZH-CN">）</span><span style="font-family: verdana;" lang="EN-US">gdb</span><span style="font-family: simsun;" lang="ZH-CN">命令一览：</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">file</span><span style="font-family: simsun;" lang="ZH-CN">：装入想要调试的可执行文件</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">kill</span><span style="font-family: simsun;" lang="ZH-CN">：终止正在调试的程序；</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">list</span><span style="font-family: simsun;" lang="ZH-CN">：列出产生执行文件的源代码的一部分</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">next</span><span style="font-family: simsun;" lang="ZH-CN">：执行一行源代码但不进入函数内部；</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">step</span><span style="font-family: simsun;" lang="ZH-CN">：执行一行源代码而且进入函数内部；</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">run</span><span style="font-family: simsun;" lang="ZH-CN">：执行当前被调试的程序；</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">quit</span><span style="font-family: simsun;" lang="ZH-CN">：终止</span><span style="font-family: verdana;" lang="EN-US">gdb</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">watch</span><span style="font-family: simsun;" lang="ZH-CN">：能监视一个变量的值</span><span style="font-family: verdana;" lang="EN-US"> </span><span style="font-family: simsun;" lang="ZH-CN">而不管它何时被改变；</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">print</span><span style="font-family: simsun;" lang="ZH-CN">：显示表达示的值；</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">break</span><span style="font-family: simsun;" lang="ZH-CN">：在代码里设置断点，这将使程序执行到这里时被挂起；</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">make</span><span style="font-family: simsun;" lang="ZH-CN">：不退出</span><span style="font-family: verdana;" lang="EN-US">gdb</span><span style="font-family: simsun;" lang="ZH-CN">就可以重新产生可执行文件</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: verdana;" lang="EN-US">shell</span><span style="font-family: simsun;" lang="ZH-CN">：不离开</span><span style="font-family: verdana;" lang="EN-US">gdb</span><span style="font-family: simsun;" lang="ZH-CN">就执行</span><span style="font-family: verdana;" lang="EN-US">UNIX shell</span><span style="font-family: simsun;" lang="ZH-CN">命令</span></p>
<p style="margin: 0in; font-size: 10pt;"><span style="font-family: simsun;" lang="ZH-CN">（</span><span style="font-family: verdana;" lang="EN-US">3</span><span style="font-family: simsun;" lang="ZH-CN">）可在</span><span style="font-family: verdana;" lang="EN-US">gdb</span><span style="font-family: simsun;" lang="ZH-CN">中按</span><span style="font-family: verdana;" lang="EN-US">Tab</span><span style="font-family: simsun;" lang="ZH-CN">键让</span><span style="font-family: verdana;" lang="EN-US">gdb</span><span style="font-family: simsun;" lang="ZH-CN">补齐一个命令。</span></p><img src ="http://www.cnitblog.com/zouzheng/aggbug/25336.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2007-04-05 19:00 <a href="http://www.cnitblog.com/zouzheng/articles/25336.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>GDB调试精粹及使用实例 （转）</title><link>http://www.cnitblog.com/zouzheng/articles/25308.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Thu, 05 Apr 2007 04:16:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/25308.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/25308.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/25308.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/25308.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/25308.html</trackback:ping><description><![CDATA[一：列文件清单 <br>1． List <br>(gdb) list line1,line2 <br><br>二：执行程序 <br>要想运行准备调试的程序，可使用run命令，在它后面可以跟随发给该程序的任何参数，包括标准输入和标准输出说明符(&lt;和&gt;)和外壳通配符（*、？、[、]）在内。 <br>如果你使用不带参数的run命令，gdb就再次使用你给予前一条run命令的参数，这是很有用的。 <br>利用set args 命令就可以修改发送给程序的参数，而使用show args 命令就可以查看其缺省参数的列表。 <br>（gdb）set args &#8211;b &#8211;x <br>(gdb) show args <br>backtrace命令为堆栈提供向后跟踪功能。 <br>Backtrace 命令产生一张列表，包含着从最近的过程开始的所以有效过程和调用这些过程的参数。 <br><br>三：显示数据 <br>利用print 命令可以检查各个变量的值。 <br>(gdb) print p (p为变量名) <br>whatis 命令可以显示某个变量的类型 <br>(gdb) whatis p <br>type = int * <br><br>print 是gdb的一个功能很强的命令，利用它可以显示被调试的语言中任何有效的表达式。表达式除了包含你程序中的变量外，还可以包含以下内容： <br>l 对程序中函数的调用 <br>(gdb) print find_entry(1,0) <br>l 数据结构和其他复杂对象 <br>(gdb) print *table_start <br>$8={e=reference=&#8217;\000&#8217;,location=0x0,next=0x0} <br>l 值的历史成分 <br>(gdb)print $1 ($1为历史记录变量,在以后可以直接引用 $1 的值) <br>l 人为数组 <br>人为数组提供了一种去显示存储器块（数组节或动态分配的存储区）内容的方法。早期的调试程序没有很好的方法将任意的指针换成一个数组。就像对待参数一样，让我们查看内存中在变量h后面的10个整数，一个动态数组的语法如下所示： <br>base@length <br>因此，要想显示在h后面的10个元素，可以使用h@10： <br>(gdb)print h@10 <br>$13=(-1,345,23,-234,0,0,0,98,345,10) <br><br>四：<a style="TEXT-DECORATION: underline" href="http://www.sogou.com/sogoupedia?query=断点" target=_blank><font color=#22229c>断点</font></a>(breakpoint) <br>break命令（可以简写为b）可以用来在调试的程序中设置断点，该命令有如下四种形式： <br>l break line-number 使程序恰好在执行给定行之前停止。 <br>l break function-name 使程序恰好在进入指定的函数之前停止。 <br>l break line-or-function if condition 如果condition（条件）是真，程序到达指定行或函数时停止。 <br>l break routine-name 在指定例程的入口处设置断点 <br><br>如果该程序是由很多原文件构成的，你可以在各个原文件中设置断点，而不是在当前的原文件中设置断点，其方法如下： <br>(gdb) break filename:line-number <br>(gdb) break filename:function-name <br><br>要想设置一个条件断点，可以利用break if命令，如下所示： <br>(gdb) break line-or-function if expr <br>例： <br>(gdb) break 46 if testsize==100 <br><br>从断点继续运行：countinue 命令 <br>五．断点的管理 <br><br>1． 显示当前gdb的断点信息： <br>(gdb) info break <br>他会以如下的形式显示所有的断点信息： <br>Num Type Disp Enb Address What <br>1 breakpoint keep y 0x000028bc in init_random at qsort2.c:155 <br>2 breakpoint keep y 0x0000291c in init_organ at qsort2.c:168 <br>(gdb) <br>2.删除指定的某个断点： <br>(gdb) delete breakpoint 1 <br>该命令将会删除编号为1的断点，如果不带编号参数，将删除所有的断点 <br>(gdb) delete breakpoint <br>3.禁止使用某个断点 <br>(gdb) disable breakpoint 1 <br>该命令将禁止断点 1,同时断点信息的 (Enb)域将变为 n <br>4．允许使用某个断点 <br>(gdb) enable breakpoint 1 <br>该命令将允许断点 1,同时断点信息的 (Enb)域将变为 y <br>5．清除原文件中某一代码行上的所有断点 <br>(gdb)clean number <br>注：number 为原文件的某个代码行的行号 <br>六．变量的检查和赋值 <br>l whatis:识别数组或变量的类型 <br>l ptype:比whatis的功能更强，他可以提供一个结构的定义 <br>l set variable:将值赋予变量 <br>l print 除了显示一个变量的值外，还可以用来赋值 <br><br>七．单步执行 <br>l next <br>不进入的单步执行 <br>l step <br>进入的单步执行 <br>如果已经进入了某函数，而想退出该函数返回到它的调用函数中，可使用命令finish <br>八．函数的调用 <br>l call name 调用和执行一个函数 <br>(gdb) call gen_and_sork( 1234,1,0 ) <br>(gdb) call printf(&#8220;abcd&#8221;) <br>$1=4 <br>l finish 结束执行当前函数，显示其返回值（如果有的话） <br><br>九．机器语言工具 <br>有一组专用的gdb变量可以用来检查和修改计算机的通用寄存器，gdb提供了目前每一台计算机中实际使用的4个寄存器的标准名字： <br>l $pc ： 程序计数器 <br>l $fp ： 帧指针（当前堆栈帧） <br>l $sp ： 栈指针 <br>l $ps ： 处理器状态 <br><br>十．信号 <br>gdb通常可以捕捉到发送给它的大多数信号，通过捕捉信号，它就可决定对于正在运行的进程要做些什么工作。例如，按CTRL-C将中断信号发送给gdb，通常就会终止gdb。但是你或许不想中断gdb，真正的目的是要中断gdb正在运行的程序，因此，gdb要抓住该信号并停止它正在运行的程序，这样就可以执行某些调试操作。 <br><br>Handle命令可控制信号的处理，他有两个参数，一个是信号名，另一个是接受到信号时该作什么。几种可能的参数是： <br>l nostop 接收到信号时，不要将它发送给程序，也不要停止程序。 <br>l stop 接受到信号时停止程序的执行，从而允许程序调试；显示一条表示已接受到信号的消息（禁止使用消息除外） <br>l print 接受到信号时显示一条消息 <br>l noprint 接受到信号时不要显示消息（而且隐含着不停止程序运行） <br>l pass 将信号发送给程序，从而允许你的程序去处理它、停止运行或采取别的动作。 <br>l nopass 停止程序运行，但不要将信号发送给程序。 <br>例如，假定你截获SIGPIPE信号，以防止正在调试的程序接受到该信号，而且只要该信号一到达，就要求该程序停止，并通知你。要完成这一任务，可利用如下命令： <br>(gdb) handle SIGPIPE stop print <br>请注意，UNIX的信号名总是采用大写字母！你可以用信号编号替代信号名 <br>如果你的程序要执行任何信号处理操作，就需要能够测试其信号处理程序，为此，就需要一种能将信号发送给程序的简便方法，这就是signal命令的任务。该 命令的参数是一个数字或者一个名字，如SIGINT。假定你的程序已将一个专用的SIGINT（键盘输入，或CTRL-C；信号2）信号处理程序设置成采 取某个清理动作，要想测试该信号处理程序，你可以设置一个断点并使用如下命令： <br>（gdb） signal 2 <br>continuing with signal SIGINT(2) <br>该程序继续执行，但是立即传输该信号，而且处理程序开始运行. <br><br>十一. 原文件的搜索 <br>search text:该命令可显示在当前文件中包含text串的下一行。 <br>Reverse-search text:该命令可以显示包含text 的前一行。 <br><br>十二.UNIX接口 <br>shell 命令可启动UNIX外壳，CTRL-D退出外壳，返回到 gdb. <br><br>十三.命令的历史 <br>为了允许使用历史命令，可使用 set history expansion on 命令 <br>(gdb) set history expansion on <br><br>小结：常用的gdb命令 <br>backtrace 显示程序中的当前位置和表示如何到达当前位置的栈跟踪（同义词：where） <br>breakpoint 在程序中设置一个断点 <br>cd 改变当前工作目录 <br>clear 删除刚才停止处的断点 <br>commands 命中断点时，列出将要执行的命令 <br>continue 从断点开始继续执行 <br>delete 删除一个断点或监测点；也可与其他命令一起使用 <br>display 程序停止时显示变量和表达时 <br>down 下移栈帧，使得另一个函数成为当前函数 <br>frame 选择下一条continue命令的帧 <br>info 显示与该程序有关的各种信息 <br>jump 在源程序中的另一点开始运行 <br>kill 异常终止在gdb 控制下运行的程序 <br>list 列出相应于正在执行的程序的原文件内容 <br>next 执行下一个源程序行，从而执行其整体中的一个函数 <br>print 显示变量或表达式的值 <br>pwd 显示当前工作目录 <br>pype 显示一个数据结构（如一个结构或C++类）的内容 <br>quit 退出gdb <br>reverse-search 在源文件中反向搜索正规表达式 <br>run 执行该程序 <br>search 在源文件中搜索正规表达式 <br>set variable 给变量赋值 <br>signal 将一个信号发送到正在运行的进程 <br>step 执行下一个源程序行，必要时进入下一个函数 <br>undisplay display命令的反命令，不要显示表达式 <br>until 结束当前循环 <br>up 上