More servicesWindows Live
HomeHotmailSpacesOneCare
 
MSN
Sign in
 
 
Spaces home  EE小站PhotosProfileFriendsBlog Tools Explore the Spaces community

Blog

    • View next 20 entriesView last 20 entries
    July 23

    最低成本的ARM调试解决方案——有关于Wiggler、H-Jtag、OpenOCD、GDB、Insight

     
    又是一个多月没有动这个Blog嘿嘿,我发现一个有趣的现象,我的Blog在每年的1月底到2月中旬,7月、8月是淡季,每天访问量基本都在100以下,其它时间都是旺季,尤其9月和3月,每天可以到200以上,最高甚至500。我想因该是因为学生们是EE小站访问的主力吧——9月和3月是开题的日子,这资料搜索做的,哈哈。现在是淡季,祝大家假期愉快,多陪陪父母。我现在就很后悔,大学的时候放假都在学校研究东西,就算回家,也背着全套的设备回去……现在工作了,根本没有时间回家看父母,唉。这段时间以来我一直在研究和调试相关的东西,最开始是想给MPC8313找一个便宜的调试方案,后来就找出来一大堆东西,但是就是没有合适8313用的。今天写的这个话题和学生们有很大关系,嘿嘿,怎样用最低的成本调试ARM,包括裸机调试和调试ARM Linux相关的东西。转载请注明来自EE小站,邮件cosine@126.com
     
    先给大家介绍个大概情况,现在国内都有什么著名的ARM开发工具和解决方案,价格从高低排:
     
    • BDI1000/2000/3000
    目前我知道的最牛X的调试工具,可以调试ARM、MIPS、PPC、ColdFire、XScale等多种处理器。无需更换硬件,只需要买不同的软件授权就可以调试不同的CPU。JTAG下载速度可以上兆,以太网接口。因为太贵了(BDI2000好像要人民币50000吧),我没怎么研究它到底配合什么软件来调试,不过GDB它是肯定支持的,它一直是我心目中的神话啊。
    • J-Link原版
    J-Link是IAR公司为ARM开发的调试工具,支持RDI协议的调试工具,如Keil、ADS、IAR等;支持GDB调试;什么SWD之类的用得很少,有没有都一样;但J-Link不支持ARM10以上的内核。JTAG下载的速度可以达到400~500K,正版价格大约5000人民币(全功能)吧,这么贵基本也不考虑了。
    • Multi-ICE原版
    ARM公司的原创调试工具,支持全系列ARM芯片,现在多少钱我也不知道了,反正在2000~3000人民币这个级别。我这里指的是国内做得比较好的那些,比如Realview之类的。仅仅支持ADS、SDT之类的裸奔代码调试,JTAG下载速度130K左右。虽然这几年Multi-ICE是国内ARM调试绝对的霸主,但现在ARM公司已经停止对ADS的维护了,Multi-ICE会开始走向没落。
    • Multi-ICE盗版
    国内有很多Multi-ICE的盗版,功能和Multi-ICE原版一样,并口的、USB的都有,价钱几百块人民币,淘宝上到处都有。但是和J-Link盗版相比,不推荐购买。
    • J-Link盗版
    最近这段时间,J-Link盗版渐渐开始多起来了,淘宝上也很多,功能和原版没有区别。价格大约在几百人民币左右,从性价比来看,推荐购买。我之后还会写一篇用J-Link调试ARM的文章,当你入门之后,绝对无法忍受今天介绍的这个低成本方案的JTAG下载速度,那时就买个J-Link来爽爽。
    • U-Link盗版
    U-Link是Keil公司做的用于ARM和某些增强型8051调试的工具,由于Keil公司做U-Link的时候没有加密,导致现在盗版满天飞,只需要100多块钱就可以买到一个。现在Keil已经被ARM收购,U-Link也是ARM一家的了。U-Link正版在盗版的排挤下,根本没有什么买的必要;U-Link仅仅支持Keil,而且JTAG下载速度仅有20~30K。
    • Wiggler电缆
    Wiggler是世界上最泛滥的一种调试工具,它非常简单,只需要一片74HC244,一个9013,几个电阻就可以。本来Wiggler是Macraigor(http://www.macraigor.com/)制作的,可以支持Macraigor的OCDRemote这个GDB Server,可以支持ARM、PPC、ColdFire、MIPS、XScale等多种CPU。后来因为它结构太简单,被人破解后搞得全世界都是,于是Macraigor怒了,现在用OCDRemote必须是Macraigor原厂的Wiggler了……尽管如此,后人又在Wiggler的硬件基础上开发了很多的调试工具,例如H-Jtag;另外也有其他的调试工具增加了对Wiggler的支持,例如OpenOCD。Wiggler电缆的成本特别低,当然它的性能也和成本一样低;用H-Jtag下载速度大约20~30KB/s,用Linux虚拟机下的OpenOCD下载速度大约2KB/s。不过对于囊中羞涩的学生们来说,是一个非常不错的入门工具。本文就针对Wiggler进行介绍。
    估计看这篇文章的人会有一些是从单片机起步,转到ARM上来的,我先梳理下各种CPU调试的知识。
     
    • 从MCS-51/96、PIC之类的单片机转入ARM
    这条路是学校教学比较传统的路子。条件好点的学校开单片机课的时候都有实验,用实验箱和仿真器做实验,那种仿真器就是一种最早的CPU/MCU仿真器,仿真器通过仿真头连接电路板,完全模拟CPU/MCU的功能;仿真器通过串口或者其他什么口连接计算机,计算机上有集编译器、调试器为一体的集成开发环境,可以监控和运行程序。这种仿真器的成本一般比较高,而且仿真不同的CPU/MCU需要不同的硬件,结构也很复杂,使用软件模拟的断点。解释下软件模拟的断点——就是用特殊的函数调用指令替换断点所在位置的指令,这些特殊的函数具有和仿真器的监控软件交互的功能。应该有很多的同学平时没有条件用上这么奢侈的设备,多半是用的是ISP,采用“点灯大法”——就是借助LED、串口之类的调试程序,每修改一次程序就重新下载一次,调试非常的艰苦。我刚开始玩单片机的时候AT的89S52还没有出来,我花一个月的生活费买了个烧写器,每次改程序都把芯片撬下来放到烧写器上,烧完再装回去继续点灯……
    走这条路,要明白的事情有:ARM的寄存器可不是51那寥寥可数的几个,是没有必要也不可能背下来的;ARM芯片一般都内置了JTAG调试逻辑,不需要CPU仿真器,需要的是一个JTAG协议转接器(虽然现在大家还叫这种东西为仿真器);集成开发环境在使用者看来和单片机的没有任何区别,这点请放心。
    • 从AVR、C8051F之类有JTAG的单片机转入ARM
    时代是不断进步的,AVR、C8051F具有JTAG口的单片机。JTAG(Joint Test Action Group)组织定了一个最初是用于测试生产出来的芯片是不是良品的测试接口和标准,在芯片的各个管脚上放上锁存器,然后串起来构成移位寄存器,可以监控芯片管脚的输入和输出;后来大家发现这东西用来搞芯片的在线调试不错,于是就出现了现在JTAG调试风行的局面。再说的明白些,也就是利用JTAG可以控制CPU内核,每个CPU都可以成为自己的“仿真器”,而不需要专用的设备。“人人都是食神。”——周星星语录。从理论上来说,世界上只需要一种仿真器,哦,确切的说应该叫做JTAG协议转换器,就可以调试所有的兼容JTAG标准的芯片;BDI2000这种超级贵的“仿真器”以及Wiggler这种什么都通吃的便宜货的存在是很合理的事情。
    走这条路,应该已经明白了JTAG是什么,所以不用多说了。
    • GDB是什么
    正像Windows和Linux的对比,集成开发环境比GDB在嵌入式开发领域,拥有更多的用户,但这并不意味的GDB不好。GDB(GNU Project Debugger)是开源软件组织GNU开发和维护的一种调试工具,它能调试目前所有的能跑Linux的CPU,当然ARM也是其中一员。对于初学者来说,不建议使用GDB,还是先从集成开发环境入手,例如ADS、SDT、Keil、IAR之类的。其实从编译器的层面来讲,集成开发环境和GDB所用的编译器GCC没有什么区别,但集成开发环境里面提供了源文件组织与浏览、工程文件管理、调试等多种功能,用起来很友好。GCC+GDB光学习写相当于工程文件的Makefile就要花很多的时间。但是,一旦你的学习进了一步到了Linux的Loader和内核,集成开发环境就无能为力了。前面已经提到了,本文覆盖了从刚开始的裸奔代码到涉足操作系统的GCC+GDB调试环境的建立方法。本文关于GDB的部分应该是国内挺难找到的HOWTO,转载请注明来自EE小站。关于GDB,可以参考下我之前的这篇文章http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!268.entry
    在开始之前请先确认你的电脑有并口,如果是笔记本就算了,买个PCMIA转并口的卡的钱够买个盗版U-Link了;要是肯下血本买盗版J-Link,那就看我以后写的文章。
     
    • 首先说代码裸奔怎么做
    你需要的东西有:
     
    ● 带并口的电脑一台
    ● 并口延长线一根
    ● Wiggler一个
    ● 随便什么ARM7或ARM9的开发板一个
     
    如果没有并口延长线,可以去电脑城买一根。如果没有Wiggler,你可以选择DIY,下面这张图是Wiggler的一种版本:
    如果不想DIY,上淘宝淘一个去。ARM开发板也可以在淘宝上淘淘,看你的经济能力了。
     
    你需要的软件有:
     
    ● ADS (ARM Developer Suite) V1.2
    ● H-Jtag
     
    ADS在一般学校的FTP上都有,H-JTAG请访问http://www.hjtag.com。在此再拜一下Twentyone大侠,可以为大家写出这么好的免费软件。
    H-Jtag和ADS的使用方法在H-Jtag的网站上的手册里写得很清楚了,我就不再啰嗦了,给出地址http://www.hjtag.com/download/USER%20MANUAL%20(CN).pdf
    • 说说GDB怎么做
    如果你对Linux下ARM的开发没有概念,先看我还是菜菜鸟的时候写的这篇文章http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!121.entry
     
    GDB使用GDB工具链,调试解决方案的结构是
     
    GDB前端<--->GDB<--->GDB服务程序<--->JTAG协议转换器(仿真器)<--->目标CPU(ARM CPU)
                                          |
                                      控制接口
     
    GDB有一个很大的缺点——文本界面,使用非常不方便。但幸运的是,有很多热心的开发者为GDB写了一些图形“外壳”——GDB前端,大大方便了GDB的使用。因为我们做的是交叉开发(即在x86结构的电脑上开发ARM等非x86结构的CPU程序),所以GDB无法直接调试编译出来的程序,这就需要一个服务程序。这个服务程序可以是一个可以控制目标CPU的程序(可能运行于计算机上;也可能运行于某些仿真器上,例如如BDI2000就是这样),也可以是一个运行于目标CPU上的服务程序,由它来装载被调试的程序。但是后者一般需要目标CPU上已经运行起了Linux内核;调试Bootloader和Linux内核本身,需要前一种服务程序。GDB和GDB服务程序之间的连接方式可以是以太网或者串口,而且GDB服务程序一般还有别的控制接口,例如Telnet接口,可以实现对目标CPU的控制,如初始化和程序文件下载等。比较复杂哦,一会儿说到软件的时候就会用上这些知识。
     
    你需要的东西和裸奔代码一样
     
    你需要的软件有:
     
    ● 一个可以运行的Linux
    虚拟机里的、真实的都可以,推荐使用Open Suse 10.3,下载地址http://software.opensuse.org/
    ● 本机GCC编译器
    Open Suse自己带的就可以
    ● 交叉GCC编译器
    可以去下载一个,随便给个地址把http://www.linux4sam.org/twiki/bin/view/Linux4SAM/SoftwareTools#Cross_Toolchain值得注意的是U-Boot 1.2.0之后需要使用支持软浮点的交叉编译器,如果没有,可以用Crosstool制作一个,可以看我之前的这篇文章http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!274.entry
    ● OpenOCD源码
    OpenOCD的主页是http://openocd.berlios.de/web/。OpenOCD是一个运行于PC上的程序,它可以控制包括Wiggler之内的很多JTAG硬件;我们可以将它理解为一种GDB服务程序。OpenOCD的源码只能通过SVN下载,地址是svn://svn.berlios.de/openocd/trunk
    ,在写这篇文章的时候OpenOCD已经是R818版本了,这个版本对Wiggler的支持有问题,我编译的是r520版本的,如果没有SVN Client,这个版本只能通过曲线的方式获得:先到下载http://www.yagarto.de/download/oldver/openocd-r520-20080322.exe这个由YAGARTO提供的OpenOCD For Cygwin的版本,安装它,在安装目录例如C:\Program Files\openocd-r520\source里找到源码压缩包。
    ● Insight源码
    Insight是一个GDB的图形前端,我感觉它比DDD更适合嵌入式系统程序的调试。
    ● 随便什么程序的源码,例如U-Boot
    U-Boot就不用介绍了,如果不知道可以Google下。
    U-Boot的下载地址是http://www.denx.de/wiki/UBoot/SourceCode
    下面开始编译,先是OpenOCD,假设源代码已经解压缩到了/home/lxz/build-openocd,先设定权限
    # cd /home/lxz/build-openocd
    # chmod 755  ./bootstrap
    # ./bootstrap
    等一会儿,输入
    # ./configure --prefix=/usr/local/arm/openocd --enable-parport
    这里--prefix指定的是安装的路径,--enable-parport使能并口,然后
    # make
    # sudo make install
    输入root密码,等一会儿,安装就完成了
     
    然后是insight,假设源码已经解压缩到了/home/lxz/insight-6.8,然后
    # cd /home/lxz/insight-6.8
    # ./configure --prefix=/usr/local/arm/arm-linux-insight --target=arm-linux
    这里--prefix指定的是安装的路径,--target指的是为ARM编译GDB,等一会儿,输入
    # make
    等一会儿,输入
    # sudo make install
    输入root密码,等一会儿,安装就完成了
     
    然后编译一个U-Boot用于测试,假设源码已经解压缩到了/home/lxz/at91rm9200/u-boot-1.2.0,假设已经修改完了Makefile中的交叉编译器的选项,假设我为AT91RM9200DK开发板编译,然后 
    # cd /home/lxz/at91rm9200/u-boot-1.2.0
    # make at91rm9200dk_config
    # make
    于是得到了/home/lxz/at91rm9200/u-boot-1.2.0/u-boot这个映像
     
    为了能让OpenOCD正常使用,我们还需要2个脚本,第一个是OpenOCD的配置脚本,这个脚本的作用是配置GDB服务程序、JTAG仿真器。写这个脚本可以看OpenOCD的文档http://openfacts.berlios.de/index-en.phtml?title=OpenOCD_configuration。我给出我的AT91RM9200DK开发板的配置文件at91rm9200.cfg,每一条配置信息的作用我就不解释了,请仔细阅读OpenOCD的文档。
     
    # Daemon configuration
    telnet_port 23
    gdb_port 2331
    daemon_startup reset
    # JTAG interface configuration
    interface parport
    jtag_speed 0
    reset_config trst_and_srst
    jtag_device 4 0x1 0xf 0xe
    # parport options
    parport_port 0x378
    parport_cable wiggler
    # Target configuration
    target arm920t little run_and_init 0 arm920t
    run_and_halt_time 0 1000
    target_script 0 reset at91rm9200_init.script
    working_area 0 0x00200000 0x1000 backup
     
    我还是提一下,上面这段配置信息中的target_script 0 reset at91rm9200_init.script这句就是指定第二个脚本的,而且让OpenOCD在当前目录下搜索这个脚本。也就是说,如果at91rm9200.cfg在/home/lxz/at91rm9200下,那么你在/home/lxz/at91rm9200下启动OpenOCD服务程序,OpenOCD就会在/home/lxz/at91rm9200下搜索at91rm9200_init.script这个脚本;如果在与at91rm9200.cfg所在路径不同的路径下启动OpenOCD服务程序,OpenOCD就无法找到at91rm9200_init.script,此时,target_script 0 reset at91rm9200_init.script这句就应该写成target_script 0 reset /home/lxz/at91rm9200/at91rm9200_init.script。
    第二个脚本的作用是初始化ARM CPU,因为U-Boot往往是在SDRAM里运行的,其连接位置也都在SDRAM里。用GDB或GDB前端下载程序的时候,必须保证SDRAM是可用的。AT91RM9200这个CPU上电的时候如果从片内Boot ROM启动(不推荐从外部启动,因为如果没有启动程序,AT91RM9200将运行于慢时钟,这样JTAG仿真器可能工作不正常),需要进一步配置PLL,PIO,SDRMC之类的外设之后,SDRAM才可以使用。第二个脚本就是一系列寄存器读写和延时命令的集合,如何编写请看OpenOCD的手册http://openfacts.berlios.de/index-en.phtml?title=OpenOCD_commands,给出我的at91rm9200_init.script。
     
    mww 0xfffffc28 0x00000000
    mww 0xfffffc2c 0x00000000
    mww 0xfffffc20 0x0000ff01
    sleep 20
    mww 0xfffffc28 0x20263e04
    sleep 20
    mww 0xfffffc2c 0x10483e0e
    sleep 20
    mww 0xfffffc30 0x00000000
    sleep 20
    mww 0xfffffc30 0x00000202
    sleep 20
    mww 0xfffff870 0xffff0000
    mww 0xfffff804 0xffff0000
    mww 0xffffff60 0x00000002
    mww 0xffffff64 0x00000000
    mww 0xffffff98 0x2188c159
    mww 0xffffff90 0x00000002
    mww 0x20000000 0x00000000
    mww 0xffffff90 0x00000004
    mww 0x20000000 0x00000000
    mww 0x20000000 0x00000000
    mww 0x20000000 0x00000000
    mww 0x20000000 0x00000000
    mww 0x20000000 0x00000000
    mww 0x20000000 0x00000000
    mww 0x20000000 0x00000000
    mww 0x20000000 0x00000000
    mww 0xffffff90 0x00000003
    mww 0x20000200 0x00000000
    mww 0xffffff94 0x000002e0
    mww 0x20000000 0x00000000
    mww 0xffffff90 0x00000000
    mww 0x20000000 0x00000000
    arm7_9 sw_bkpts enable
     
    这个脚本写起来很复杂,建议从一些样例代码上把寄存器的数值扒过来。另外,有些CPU,例如S3C2410,它上电的时候,SDRAM是默认可以用的,就不需要这个脚本了。还有一个值得注意的是,由于我们用的是Wiggler这种简单的JTAG协议转换器,初始化脚本里必须加上arm7_9 sw_bkpts enable这句。现在终于可以开始调试了,假设把OpenOCD安装在了/usr/local/arm/openocd,把Insight安装在了/usr/local/arm/arm-linux-insight,两个初始化脚本都放在了/home/lxz/at91rm9200;你已经正确连接了Wiggler,开发板已经上电。接下来还是用命令来说明
     
    # cd /home/lxz/at91rm9200
    # sudo /usr/local/arm/openocd/bin/openocd -f at91rm9200.cfg
    root's password:
    Open On-Chip Debugger 1.0 (2008-07-21-20:15) svn:
    $URL: http://svn.berlios.de/svnroot/repos/openocd/trunk/src/openocd.c $
    Info:    jtag.c:1329 jtag_examine_chain(): JTAG device found: 0x05b0203f (Manufacturer: 0x01f, Part: 0x5b02, Version: 0x0)
    Info:    target.c:240 target_init_handler(): executing reset script 'at91rm9200_init.script'
    Info:    options.c:50 configuration_output_handler(): software breakpoints enabled
     
    这就说明OpenOCD已经开始工作了。然后启动Insight
    # cd /home/lxz/at91rm9200/u-boot-1.2.0/
    # /usr/local/arm/arm-linux-insight/bin/arm-linux-insight
     
    出现下面的窗口
     
     
     
    然后选择菜单File>Target Settings...,在出现的窗口中进行如下设置,然后点OK。
     
     
     
    选择菜单File>Open,打开/home/lxz/at91rm9200/u-boot-1.2.0/u-boot这个映像;然后选择菜单Run>Download,将U-Boot程序下载到目标CPU。然后在程序运行的必经之路设定一个断点,如下图所示。
     
     
     
    选择菜单Control>Continure,程序就会从头开始执行,并停在断点处了。Insight还有很多不错的功能,并且很容易上手,大家研究下就好。补充一点,如果你对你的初始化脚本是否起作用没有信心,可以在启动Insight之后只选择菜单Run>Connect to target,然后选择菜单View>Memory查看各个寄存器和内存。最后给出一张我用Insight调试U-Boot的截图。
     
     
     
    在使用的过程中就会发现,用Wiggler下载的速度实在不怎么样,U-Boot的可执行映像至多只有200KB,所以还是可以忍受的。
    用同样的方法也可以调试其他Boot Loader,甚至是Linux内核;但是Linux内核的可执行映像一般有2MB之大,用Wiggler调试也是不现实的。我之前已经做了广告了,内核的调试要用J-Link来搞,敬请期待EE小站的后续文章。
    我对ARM CPU的在线Flash Download这件事情不是很感冒,所以H-JTAG和OpenOCD的这部分功能EE小站是不会涉及了,请见谅。今天就到这里。
     
    June 14

    再谈SDRAM的布线——有关Mentor WG、DxDesinger、Expedition、CES

     

    • 前言的前言
    这篇文章我写了很久很久,因为最近很忙很忙。现在我逐渐开始接触开关电源和可靠性设计的东西,好像离原来我定义的EE越来越远了。也许以后我要向模电或管理人员发展了……我还是纯朴地希望自己能一直保持做一个不断钻研的EE工程师。不说了,做人要厚道,转载请注明来自我是一只鱼同学的EE小站,邮件地址cosine@126.com
    • 前言
    最近一个多月都在研究Mentor WG,已经对DxDesigner + Expedition的画板流程有了比较清醒的认识,我对Mentor WG评价可以套用对目前国产汽车的评价——配置齐全、做工粗糙。虽然WG有很强的功能,但是BUG实在是数不胜数,而且有些BUG可能导致你的工程彻底报废,所以建议使用时辅以自动备份软件,减小工程崩溃带来的损失。
     
    今天要谈的话题都是基于WG的,因为PADS、Protel / DXP之类的软件没有这样的功能或功能不完整。不过,也可以使用其他软件进行PCB前仿、手动完成线长匹配等工作;工具只是人的技巧的辅助和延伸,要是没有高速PCB设计的知识,同样完不成高速数字PCB的设计。本文为我是一只鱼同学EE小站的原创文章,转载请注明出处;本文对初学者而言,技术难度较高,如果有不明白的地方,可以留言。另外继续废话几句,事实上SDRAM对布线的要求是很低的,DDR才是真正有挑战的东西,可惜我目前没有DDR的项目,也没有办法验证我对理论的理解,希望以后有机会和大家分享我的心得。下面正式开始:
    • 什么是高速数字PCB,怎么入手?
    高速数字PCB简单来说可以理解为关键部分如存储器总线的工作频率高于数十至一百MHz的PCB,更严格的定义应该用传输线来描述,当PCB上的信号的传输延迟大于上升时间的1/10时,这个信号的传输路径就应该视为传输线;即应当用与传统低速数字电路不同的方法对待。那么怎么入手?我是学机械出身的,电路原理和模电都是三脚猫知识;我个人认为High-Speed Digital System Design是本不错的书。首先看书,弄明白在频率高了以后会出现什么样的现象,有什么东西需要考虑之后,再继续后面的设计。不过我可以做个简单的概括,高频数字电路设计的大部分工作是解决传输线中信号反射问题和延迟问题。BTW,很久以前我还很菜的时候写了一篇文章http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!171.entry,这是关于PCB后仿的(这个词下面马上解释),大家有兴趣可以看看。
    • 高速PCB设计的流程
    元件布局——〉前仿真——〉布线——〉后仿真——〉出CAM文件
    其他不多说了,就解释下前仿真和后仿真。
    前仿真就是在器件IBIS模型、网络拓扑结构和器件分布的基础上做的对PCB可实现性仿真。举个例子解释前仿真的作用,如果器件、板子的机械结构都已经定下来了,CPU和SDRAM插座相隔10000mil,那么在布完这个板子之前,怎么知道这个板子能不能正常工作?关于如何使用WG进行前仿真,后面再说。
    后仿真就是在板子走线已经成型之后,对布线结果进行验证而作的仿真。后仿真会在前仿真基础上加上过孔模型、串扰、电磁兼容性等仿真内容。刚才提到的我的菜菜鸟文章http://xianzilu.spaces.live.com/blog/cns!4201FDC93932DDAF!171.entry,说的就是后仿真。
    • SDRAM对布线有什么要求?
    首先必须明白SDRAM是一种什么样的存储器,搞清其接口工作的逻辑时序。SDRAM是一种同步动态存储器,所有接口信号都是通过时钟同步和采样的。这就对SDRAM的布线提出了要求——保证采样的正确性。于是,应用高速数字电路的知识结合某种具体SDRAM器件和你的PCB进行分析,发现在正常工作频率(如100MHz)下,在PCB走线上的信号传输时间大于其上升时间1/10。于是,接下来考虑高速数字电路两大问题反射和延迟:反射造成SDRAM时钟线信号出现振铃,多次穿越门限造成误触发;数据线和时钟线的传输延迟不相同,造成时钟上升沿采样不到所需要的数据。接下来应用解决方法:时钟线串联电阻做阻抗匹配;布线时控制数据线和时钟线的长度差在一定范围内。当然,我这里说的是一个很简单的演绎过程,还有拓扑结构、最大布线长度等重要问题没有考虑,请大家仔细阅读我是一只鱼同学刚才推荐的课本。提示下,拓扑结构和最大布线长度的选择可以通过前仿真进行验证。
    • 进一步的问题,SDRAM布线用什么拓扑结构好?
    这个问题困扰了我很久很久,终于在学会前仿真后解决了,哈哈。其实大家已经很清楚SDRAM要尽量使用Y型分支结构(也叫T型分支),因为链式结构会产生两个问题:一、两片SDRAM的传输延迟不一样,影响CPU对数据输出进行采样;二、链式结构的节点处阻抗不连续,是一个反射点,而且反射点和源的距离太大,反射效果明显。但是,如果使用Y型分支结构,到底是先分支好呢还是后分支好呢?
     

     
    经过前仿真的验证,分支点靠近CPU的时候效果稍微好那么一点点。我想这是因为分支点本身是一个阻抗不连续点,也是会发生反射的。如果分支点靠近源端CPU,反射就会因为传输线的缩短而显得不太明显。我给分枝点靠近CPU的这种拓扑结构起个名字,叫短桩Y型分支结构。
    • 怎样用WG进行PCB前仿真?
    WG中PCB的前仿真的步骤:DxDesigner画原理图——〉Expedition布局——〉CES指定IBIS模型——〉CES指定网络的拓扑结构——〉ICX Pro前仿真。我们来看图说话。
    对于下面这样一个已经完成布局的PCB,从Expedition的工具栏中选择CES
     

     
    在CES的窗口中见的选项卡中,选择Parts
     
     
     
    例如对SDRAM的走线进行前仿真,就需要制定CPU、SDRAM以及其他连接在数据总线上的器件的IBIS模型。相应的模型可以在器件的官方网站上下载到。在Parts里选中要指定模型的器件。
     
     
     
    在弹出的窗口中按照步骤1、2、3(后续图片中的1、2、3、4亦表示步骤)选择IBIS模型文件
     
     
     
    选好后就OK,重复以上步骤直到把要进行仿真的信号所连接的所有器件的IBIS模型都选上。有的IBIS文件中含有多个器件的模型,选择你需要的
     
     
     
    在SDRAM信号设计的时候往往会使用电阻对信号进行阻抗匹配,这时候SDRAM布线的拓扑结构就会变成下面这样
     
     
     
    这个电阻也必须包含到前仿真中去。但是在实际设计中,往往有很多需要匹配的信号,所以一般是使用排阻的。但是默认情况下,CES是不认识排阻的,这需要设置。选择Setup菜单下的Settings…
     
     
     
    在弹出的窗口中选择Discrete Component Prefixes选项页,将你所用的排阻前缀输入(如RM),然后确认
     
     
     
    随后你就会发现CES把你的排阻认为是串行器件了。顺便提下,如上面这张图所示,CES会把这些已经定义前缀的器件识别为串行器件。识别为串行器件有好处也有坏处,好处是对于真正用于阻抗匹配等目的的器件,前后的网络会被归为一个网络进行识别(CES在原来的网络名后面加上“^^^”符号,将两个网络合并);坏处是很多功能性质的电阻,如运放中设定放大比例的电阻两端的网络也会被归为一个网络识别,这时候就需要把下面这张图中所示的钩号去掉。
     
     
     
    接下来,点击Parts边上的Nets选项卡,选择SDRAM的信号
     
     
     
    随后配置网络拓扑结构。对于SDRAM的控制线来说,它们不连接在SDRAM之外的其他上,因此其拓扑结构一般都是之前描述的这种:
     
     
     
    对于一般的地址线而言,往往需要连接除SDRAM芯片之外的其他器件,如NOR Flash,其拓扑结构可能是这样的
     
     
     
    我建议将NOR Flash连接在一个SDRAM的之后,因为如果再搞短桩Y型分支,那么将会有3组分支线,布线就很困难了。当然,连接在哪里要根据前仿真的结果来调整,我提供的这种连接对于某些器件应该会有问题。

    下面要把SDRAM的信号定义成上面这2种拓扑结构中的一种,在Nets列表里找到Topology这一列,点击下拉列表。对于SDRAM时钟信号SDCK这种串联阻抗匹配电阻的拓扑结构而言,选择Complex。
     
     
     
    随后点击工具栏上的Netline order按钮(这个按钮左边的几个按钮可以定义其他不同的拓扑结构,与上图列表中对应,依次是MST、Chained、T、Star、HTree、Custom,这些不同拓扑结构的含义可以Google下或者参看Mentor WG CES的手册)
     
     
     
    出来这样一个对话框
     
     
     
    之前已经提到SDRAM的地址和控制信号应当是短桩Y型分支,如果还有别的器件就连接在SDRAM之后。先说明下,因为定义了排阻为串行期间,所以CES自动的将CPU到排阻的连接识别出来并列在管脚对列表里了;管脚列表里蓝色背景的部分是已经在管脚对列表中存在的管脚。随后就需要定义Y型分支,点击Y型分支拓扑结构图标,再依次点击信号源管脚和两个负载管脚,如下图所示
     
     
     
    在管脚列表中就会出现如下显示
     
     
     
    这说明已经定义了一个Y型分支。定义之后的Y型分支可以删除和修改,具体细节请看CES手册。随后点击对话框下面的那个复选框,“Automatically create pin pairs from from-tos”,确定,CES的Nets列表中,刚才定义的Net下就出现如下图所示的内容
     
     
     
    那些L:VP_T_1_1_1181, L:D19-38之类的东西就是产生的拓扑结构描述。
    刚才已经提到SDRAM的地址线因为还需连接其他器件,拓扑结构的设置还需要有一步添加自定义管脚对。以地址线A2举例,同样选择其为Complex结构
     
     
     
    然后选择工具栏上的Netline order,在出现的对话框中将CPU和SDRAM之间的连接配置为Y型分支,如下图所示
     
     
     
    随后配置和NOR Flash芯片的连接,先点击“From pin / pin set”下面的文本框,然后依次点击SDRAM和NOR Flash的管脚,再点击右边的下箭头,如下图
     
     
     
    于是一个自定义的Pin Pair就出现了,同时管脚列表中对应的管脚背景色也会变蓝,显示这个管脚被指派过了。
     
     
     
    需要注意的是,NOR Flash连接在那个SDRAM器件的管脚上是没有要求的,但是为了走线方便,还是建议连接在理NOR Flash相应管脚较近的SDRAM器件上。
    接下来同样选中“Automatically create pin pairs from from-tos”复选框,确定,A2的拓扑结构就配置好了。
     
     
     
    这里还需要提一个概念——Virtual Pin(虚拟管脚),这是WG为了方便对拓扑结构的管理而设定的一种虚拟的控制点。还是用图来说明,对于SDRAM的连接拓扑结构
     
     
     
    WG把图中红圈标示的那个分支点分立出来,当作一个可以控制的元素Virtual Pin,这个元素可以移动、定位;一个Y型分支的拓扑结构就拆分成了各个元件到这个Virtual Pin连接的结构。刚才我们看到的“VP_T_1_1_1181”就是Virtual Pin,它在PCB设计的时候是这样显示的:
     
     
     
    Protel / DXP、PADS是没有这种功能的,PADS只能通过Matchlength Pin Pair来实现类似的功能,但对于SDRAM不太适用。不仅WG,强大Alergo也有这个功能。说了这么多,Virtual Pin的作用其实就一句话,用来做Y型分支的两个分支等长——因为没有Virtual Pin,去哪里设置等长规则,怎么检验等长的情况?
    接下来设定PCB层叠,不指定PCB的层叠,前仿真中的阻抗参数的计算是根本没有意义的。选择CES工具栏上的Stackup Editor
     
     
     
    出现下面的窗口,这个东西比较傻瓜式了,我就不做保姆式指导了。需要指定的东西有,PCB每一层的铜厚,相临两层之间的绝缘层厚度和介电常数,参考面(电源层、地层)是哪几层等。PCB的厚度和介电常数等参数需要向PCB厂家索取,参考面的位置可以Google下,看看大多数人用的层叠方法。
     
     
     
    有了以上的工作,前仿真就可以进行了,右键选择需要仿真的网络,例如SDCK,在弹出菜单中选择“Display Net in”——〉“ICX Pro Explorer”
     
     
     
    出现以下窗口
     
     
     
    这就是我们进行前仿的软件了。可以看到,在中间的黑色背景区域是器件管脚、传输路径以及其他器件(如阻抗匹配电阻)的连接拓扑结构——这也就是我们刚才设定的那些东西。图中绿色那些短棒就是传输路径,双击它可以修改长度;这个长度应由PCB布局决定。在CES中选择菜单“Data”——〉“Actuals”——〉“Upadate All”命令将PCB的数据导入CES之后
     
     
     
    在Nets的列表里可以看到Manhattan Length这一项的数值出现了
     
     
     
    这个数值的含义是布局完成之后目前PCB上这一网络所有飞线(用直线连接管脚的线)长度之和。一般来说把这个数值乘以1~2之间的一个数,就是最后的布线长度。你可以把这些数值输入到ICX Pro Explorer中去。对于含有拓扑结构的网络,应当把拓扑结构的每一段都输入到相应的传输线上去。你可以在PCB上试着移动Y型分支点即Virtual Pin的位置,然后更新Manhattan Length,看看是先分支的拓扑结构前仿的效果好,还是后分支的。
    ICX Pro Explorer也是一个比较傻瓜式的软件,用一用很快就会了,我就不介绍了,给大家看个仿真结果
     
     
     
    这是AT91SAM9263和K4S561632K-UC75组成的存储器系统,阻抗匹配电阻为22欧,SDRAM时钟在133MHz下的仿真波形。
    • WG中怎么设置SDRAM的线长匹配规则
    这是一个非常麻烦的部分,我研究了很久,转载请注明来自EE小站。在介绍规则设置之前,先介绍下SDRAM线长匹配的原则。
    一般来说,SDRAM的地址线是这样的拓扑结构
     
     
     
    SDRAM的控制线是这样的拓扑结构
     
     
     
    不同地址线之间,需要保证单路分支的长度匹配,即AB+BC或AB+BD相等;同时,需要保证同一地址线的两个分支相等,即BC=BD。不同控制线之间,需要保证单路分支的长度匹配,即ab+cd+de或ab+cd+df相等;同时,需要保证同一控制线的两个分支相等,即de=df。在控制线和地址线之间,同样需要保证单路分的支长度匹配,即AB+BC=ab+cd+de或AB+BC=ab+cd+df或AB+BD=ab+cd+de或AB+BD=ab+cd+df。

    而软件统计的结果,地址线的长度为AB+BC+BD+D’E;控制线的长度为ab+cd+de+df。统计的内容都不一样,怎么做匹配呢?有2种方法,使用公式、使用Pin pair。使用公式的好处是无论有没有阻抗匹配电阻,都可以很清晰的看到线长匹配的误差,这对手工布线非常有帮助,但是过程极其繁琐。使用Pin Pair的好处是很简单,不用输入很长的公式,但是对于有阻抗匹配电阻的信号,不能看到匹配误差,需要自己计算。

    先说公式方法
     
    记住,软件统计的是所有线段长度之和;我们需要控制的仅仅是所有地址线的AB+BC、所有控制线的ab+cd+de这些长度都相等(BC=BD、de=df这两个条件在设定Y型分支拓扑结构之后,布线器会自动地做到,于是将上面的那些表达式简化成等价的AB+BC和ab+cd+de这两个)。因为SDRAM的时钟是最重要的信号,选择时钟线的长度作为参考,时钟线的单路分支长度为ab[时钟]+cd[时钟]+de[时钟](Blog没有办法表示下标,用[]来修饰)。则对于其他信号,如地址线,理论上约束的内容应该是AB[地址]+BC[地址] = ab[时钟]+cd[时钟]+de[时钟]。软件统计的是所有线段长度之和,对于某一地址线,其长度应该是AB[地址]+BC[地址]+BD[地址]+D’E[地址]。因此,公式约束的内容就变为 AB[地址]+BC[地址] = ab[时钟]+cd[时钟]+de[时钟]+ BD[地址]+D’E[地址]。

    很复杂,来看个例子,对于一个含有匹配电阻的时钟信号,EBI0_SDCK,其拓扑结构如下所示
     
     
     
    其中VP_T_3_5_1336为Virtual Pin。它的单路分支长度按WG CES的语法,应写成\D1\-\C5\@\RM2\-\7\ + \RM2\-\2\@\VP_T_3_5_1336\-\VP_T_3_5_1336\ + \RM2\-\2\@\D19\-\38\,当然最后一项是\RM2\-\2\@\D20\-\38\也可以。
    确定了时钟的长度,接下来用它来约束其他地址线、控制线的长度。以EBI0_A3为例,其拓扑结构如下所示
     
     
     
    由于软件统计EBI0_A3的长度为上面4个Pin Pair线段长度之和,因此在EBI0_A3单段分支的基础上(这段长度和EBI0_SDCK的单段分支长度相等),需要加上\D19\-\24\@\D21\-\25\ + \D1\-\C9\@\D20\-\24\这段长度,当然第二项是\D1\-\C9\@\D19\-\24\也可以。所以限制EBI0_A3的长度为,\D1\-\C5\@\RM2\-\7\ + \RM2\-\2\@\VP_T_3_5_1336\-\VP_T_3_5_1336\ + \RM2\-\2\@\D19\-\38\ + \D19\-\24\@\D21\- \25\ + \D1\-\C9\@\D20\-\24\ +/-200th,当然倒数第二项是\D1\-\C9\@\D19\-\24\也可以,最后的+/-200th是控制的误差长度。然后把这个公式填到EBI0_A3后面的Formula中去。
     
     
     
    对于有阻抗匹配电阻的信号,如nEBI0_CAS
     
     
     
    由于软件统计nEBI0_CAS的长度为上面4个Pin Pair线段长度之和,因此在nEBI0_CAS^^^单段分支的基础上(这段长度和EBI0_SDCK的单段分支长度相等),需要加上\RM1\-\3\@\D20\-\17\或\RM1\-\3\@\D19\-\17\的长度。所以限制nEBI0_CAS的长度为,\D1\-\C5\@\RM2\-\7\ + \RM2\-\2\@\VP_T_3_5_1336\-\VP_T_3_5_1336\ + \RM2\-\2\@\D19\-\38\ + \RM1\-\3\@\D19\-\17\ +/-200th,当然倒数第二项是\RM1\-\3\@\D20\-\17\也可以,最后的+/-200th是控制的误差长度。
    按照上面的步骤把所有SDRAM信号线都操作一遍,是不是会崩溃?
     
    下面介绍用Pin Pair的方法
     
    给地址线、控制线建立这样的Pin Pair,例子如下:
    EBI0_SDCK^^^信号
     
     
     
    EBI0_A3信号
     
     
     
    这和之前的Pin Pair不同,这些Pin Pair是手工生成的,也就是说,在制定这些信号的拓扑结构的时候,不选择“Automatically create pin pairs from from-tos”复选框。然后,选中这一信号,通过菜单Edit>Pin Pair>Add Pin Pairs来手工添加,如下面两张图片所示。
     
     
     
     
     
    这样,只需要关心信号最开始是从哪个芯片的哪个管脚出来的,最后到哪个芯片的哪个管脚里去,有多少个单路分支,添加多少个Pin Pair,中间的阻抗匹配电阻、Virtual Pin全部可以忽略;最后再在Pin Pair的Match列用同一名字约束就可以了,如下所示
     
     
     
    控制信号也一样
     
     
     
    需要说明的是,上面这张图头三个Pin Pair是用来方便手工布线的。因为Pin Pair如果穿越了器件(对于信号路径穿越阻抗匹配电阻这种情况而言),Pin Pair的长度在CES里是显示不出来的——至少目前我还没有找到什么办法可以让它显示出来——这对手工布线来说非常不方便;但是自动布线却没有任何问题,Expedition可以正常的完成Tune(自动长度调整)操作。

    也许你有些疑惑,既然Pin Pair这么定义了,怎样才能看到自定义拓扑结构呢?把菜单中Filters>Levels>FromTos选项钩起来,就可以看见了,如下图所示。需要说明的是,Pin Pair仅仅是一种虚拟的连接关系,拓扑结构是用FromTos这种物理连接关系确定的。
     
     
     转载请注明来自EE小站,以方便后人查询。至于其他的布局、布线这些简单的东西就没有什么好说的了。就写到这里。
    April 16

    忙忙忙!

    最近很忙,时间都用来放松了,基本没有什么研究的兴趣。
    现在还在用ARM9设计东西,不过和过去相比设计考虑的东西多了很多,除了芯片功能,还必须考虑成本、供货、兼容产品、公司库存……另外我觉得自己开始钻牛角尖了,例如说考虑245缓冲在不上电或上电、掉电瞬间的方向;开始做一些变态的事情,比如用MOSFET搭门电路,哈哈。
    最近公司开始用WG来画板,唉,Mentor Graphic的产品,除了Modelsim能让我感觉好些,PADS和WG都让我感觉原来Altium designer是这么好用啊。WG的原理图编辑器DXDesigner基本上每一个功能都有BUG,实在数不胜数,甚至他们连Horizontal和Vertical这2个词的意思都分不清,菜单里水平镜像和垂直镜像的选项需要对调一下——我真怀疑这是印度人写的软件。DXDesigner画图大部分的时间我都在调整线和字体;动不动就莫名奇妙的崩溃,今天我就遇到了一条线可以选中却怎么也不能移动、删不掉的BUG;我搞工程这么多年了,刚开始的时候搞机械,AutoCAD、Solidworks、Pro/E,后来搞电子EWB、Protel99、Orcad、Quartus、DXP,平时用Visio,这么多能画图的软件,从来没有见过能有线条删不掉的情况……我奉劝想要使用Mentor产品的人一定要三思啊。
    现在觉得ARM没有什么意思了,呵呵,下一个我要挑战的东东是PowerPC。但是PowerPC的开发成本太高了,等手头的事情忙完了,我会寻找一条类似Wiggler+HJTAG的道路。
    我的http://cosine.oicp.net因为家里忘缴电费被掐电而非法关机半个月了吐舌,最近没有什么心情,过几天再把它恢复出来。
    就写这么多。
    March 15

    终于小窥了OpenGL的门径。

    大约半年前,我写了篇文章,介绍了如何在ARM Linux上使用OpenGL|ES软件包。但是运行的速度实在是太慢了。在ARM上流畅运行OpenGL一直是令我耿耿于怀的一个怨念。最近一段时间研究了下OpenGL,在别人代码的基础上(Mesa,TinyGL),写出了一个可以裸机运行的超精简OpenGL软件包,总共代码只有1600行。运行在具有2D图形加速功能的SOC处理器上,可以获得很不错的效果。但是这不是我最终的目的,我想要把这个软件包中的大多数功能改写成VHDL,实现硬件3D加速。当然,这个软件包的功能是为我从事的行业专门设计的,用于消费电子基本是不可能的。贴上一张图片,给大家看看。
     
     
    这个东西对我来说太有用了,更多的信息不能公开,抱歉了。如果你想进行这方面的研究,我可以给点资料提示,第一就是上面图片里这本书,俗称“OpenGL红宝书”;第二是随便什么讲计算机图形方面的书,只要涉及到画线、多边形填充算法,2维和3维投影变换,光源计算等,就可以。
    February 23

    在ARM Linux上使用Apache+PHP

    我相信这篇文章同样是国内很难搜到的一个HOWTO(呵呵,截至到我写出来之前),我的最初目的是在ARM上使用PHP,尝试了Busybox的httpd,以及boa都没有办法很方便的和PHP接口,因此我狠下心来,编译了Apache。在ARM上使用PHP,好处仅仅是脚本比cgi好写一些,付出的代价是速度和蜗牛一样慢,不要指望很多人同时访问可以响应得过来。
    另外说件事,BLOG上的文章多了,经常发现有人转载,但是有的人却不注出处……难道要我吧我的名字和邮件地址写到文章的每一个部分吗?也许国人就是这样缺乏某种精神,在我看到的转载我文章的BLOG中,基本都是网上各种ARM Linux文章的集合,不可否认他们搜集的很好,但是看了这么多文章,连一点心得体会都没有么,写点原创的东西就这么难么?不管怎样,我还是坚持EE小站的风格——原创性。下面开始正题,本文分为三大部分,apache、php和配置。
     
    • 编译apache

    下载apache 1.3.39(1.3.41有些bug,没有办法交叉编译)
    下载地址http://apache.mirror.phpchina.com/httpd/apache_1.3.39.tar.bz2

     
    交叉编译apache总体上需要两个步骤:
    1.编译本机代码
    2.利用本机代码进行交叉编译
     
    这是因为编译apache时,需要使用编译生成的工具制作后续编译使用的头文件,交叉编译的工具当然没有办法在PC上运行,因此,需要借用本机编译生成的工具。假设为本机编译的apache代码已经解压缩到/home/lxz/apache-1.3.39-i586,为ARM编译的apache代码已经解压缩到/home/lxz/apache-1.3.39,交叉编译器arm-linux-gcc已设缺省路径,具体步骤还是用命令来说明:
     
    # cd /home/lxz/apache-1.3.39-i586
    # ./configure
     
    因为仅仅是借用下本机代码,所以不用设置配置参数,然后编译
     
    # make
     
    等编译完成后,就可以配置交叉编译的apache了。apache的安装位置为/usr/local/apache
     
    # cd /home/lxz/apache-1.3.39
    # CC=arm-linux-gcc ./configure --prefix=/usr/local/apache
     
    会出来这样的提示,因为交叉编译的生成的testfunc这个工具不能在PC上执行,但可以不理会它
    ./helpers/TestCompile: line 294: /home/lxz/apache-1.3.39/src/helpers/testfunc: cannot execute binary file
    打开/home/lxz/apache-1.3.39/src/main/Makefile这个文件,找到这两段代码
    uri_delims.h: gen_uri_delims
     ./gen_uri_delims >uri_delims.h
    test_char.h: gen_test_char
     ./gen_test_char >test_char.h
    修改为
    uri_delims.h: gen_uri_delims
     /home/lxz/apache-1.3.39-i586/src/main/gen_uri_delims >uri_delims.h
    test_char.h: gen_test_char
     /home/lxz/apache-1.3.39-i586/src/main/gen_test_char >test_char.h
    这里借用了刚才编译生成的本机代码里的工具,然后
     
    # make
     
    这就编译好了,下面是安装。由于配置apache的时候“prefix”参数指定的安装位置是/usr/local/apache,在PC上,访问/usr/local是需要有root权限的,需要切换到root用户来进行安装。不建议将apache安装到一个随意的目录然后拷贝,因为这样会造成apache中的脚本调用位置的错误。当然,如果想要将apache安装到一个PC和ARM Linux都能访问的固定位置,如/home/lxz/apache也可以。
    如果你不明白上面这段话在说什么,那么请按照下面的步骤进行操作。请确认你的PC Linux上的/usr/local/apache这个目录不存在PC上使用的apache,否则下面的步骤会使你PC Linux上的apache不可用。
     
    # su root
     
    输入密码
     
    # cd /home/lxz/apache-1.3.39/
    # make install
    # exit
     
    别忘了用exit退出root用户模式,这样,apache的文件就被安装到PC上的/usr/local/apache了。接下来所要做的是将apache拷贝到ARM Linux根文件系统,假设ARM Linux根文件系统在PC上的位置为/home/lxz/root,其中已经有/usr/local这个目录
     
    # cp -r /usr/local/apache /home/lxz/root/usr/local
     
    如果是一路看着我的BLOG建立起根文件系统的,接下来还必须建立nobody用户和nogroup组,因为apache拒绝使用root用户运行。具体来说就是在ARM Linux根文件系统上建立/etc/passwd和/etc/group两个文件,怎么写这两个文件,可以google下。它们的内容可以如下:
     
    /etc/passwd
    root::0:0:root:/:/bin/ash
    nobody::65534:65533:nobody:/:/bin/ash
    /etc/group
    nobody::65533:
    nogroup::65534:nobody
    root::0:
    users::100:
    当然,如果你的ARM Linux根文件系统中有这两个文件,那么你需要检查一下是不是有nobody用户和nogroup组。接下来,可以制作文件系统映像并测试apache是否可以正常工作了,还是用命令来说明。
     
    # mkfs.cramfs /home/lxz/root /home/lxz/root.img
     
    我一直用cramfs,SUSE 10.2自己就带了mkfs.cramfs这个工具。烧写或者加载文件系统映像的步骤我就不说了,需要注意的是如果你使用了不可写的文件系统,如cramfs,需要把apache的日志路径挂载为临时文件目录,下面这几条命令在ARM Linux上执行。
     
    # mount -t tmpfs tmpfs /usr/local/apache/log
     
    然后就可以启动apache了
     
    # cd /usr/local/apache/bin
    # ./apachectl start
     
    假设ARM板的ip地址是192.168.5.118,在浏览器里输入http://192.168.5.118:8080访问ARM板(不修改默认配置,服务端口是8080)。apache的配置一会儿编译了php再说。
    • 编译php

    首先下载php-4.4.8,下载地址:http://cn2.php.net/get/php-4.4.8.tar.bz2/from/this/mirror

    交叉编译php同样需要两个步骤:
    1.编译本机代码
    2.利用本机代码进行交叉编译
     
    原因我就不重复了,假设为本机编译的php代码已经解压缩到/home/lxz/php-4.4.8-i586,为ARM编译的php代码已经解压缩到/home/lxz/php-4.4.8,交叉编译器arm-linux-gcc已设缺省路径,具体步骤还是用命令来说明:
     
    # cd /home/lxz/php-4.4.8-i586
    # ./configure
    # make
     
    在编译的同时,可以打开/home/lxz/php-4.4.8/configure这个文件,搜索“can not run test program while cross compiling”,会搜索到很多个这样的结果:
    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
    把它们都改为
    { echo "configure: error: can not run test program while cross compiling" 1>&2; }
    这样做的目的是直接无视交叉编译测试程序错误。另外,我使用的是arm-linux-gcc 3.4.1版,和代码不太兼容。找到/home/lxz/php-4.4.8/Zend/zend_strtod.c的第238行
    #if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \
        defined(IBM) != 1
    Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or
    IBM should be defined.
    #endif
    把这段改为
    #if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \
        defined(IBM) != 1
    //Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or
    //IBM should be defined.
    #endif
    在本机php编译完后,输入如下命令
     
    # cd /home/lxz/php-4.4.8
    # CC=arm-linux-gcc ./configure --prefix=/usr/local/php --host=i586-suse-linux --target=arm-linux
     
    别以为可以编译了,还有东西要修改,真汗啊……打开/home/lxz/php-4.4.8/Makefile,找到这段
    install-pear-packages: $(top_builddir)/sapi/cli/php
     @$(top_builddir)/sapi/cli/php $(PEAR_INSTALL_FLAGS) /home/lxz/php-4.4.8/pear/install-pear.php -d "$(peardir)" -b "$(bindir)" /home/lxz/php-4.4.8/pear/packages/*.tar
    用上我们刚才编译的本机php里的文件,把它改成
    install-pear-packages: /home/lxz/php-4.4.8-i586/sapi/cli/php
     @/home/lxz/php-4.4.8-i586/sapi/cli/php $(PEAR_INSTALL_FLAGS) /home/lxz/php-4.4.8/pear/install-pear.php -d "$(peardir)" -b "$(bindir)" /home/lxz/php-4.4.8/pear/packages/*.tar
    终于可以编译了
     
    # make
     
    随后和apache一样,需要切换用户,把php的文件安装到/usr/local/php
     
    # su
     
    输入密码
     
    # cd /home/lxz/php-4.4.8
    # make install
    # exit
     
    这样,php就编译完成了。
     
    • 配置Apache和PHP
    接下来就需要修改配置文件,让apache和php能够链接起来工作。这个配置过程和Windows下使用apache+php的过程类似,因为我不是把apache和php一起编译的,只是让apache认识“.php”这个扩展名,然后调用php。为了方便,直接给出apache的配置文件,配置文件的位置在ARM Linux文件系统的/usr/local/apache/conf/httpd.conf,其中红色字是在默认配置文件基础上修改或添加的内容。
    ServerType standalone
    ServerRoot "/usr/local/apache"
    PidFile /usr/local/apache/logs/httpd.pid
    ScoreBoardFile /usr/local/apache/logs/httpd.scoreboard
    Timeout 300
    KeepAlive On
    MaxKeepAliveRequests 100
    KeepAliveTimeout 15
    MinSpareServers 5
    MaxSpareServers 10
    StartServers 5
    MaxClients 150
    MaxRequestsPerChild 0
    Port 80
    User nobody
    Group nobody
    ServerAdmin cosine@126.com
    DocumentRoot "/home/webroot"
    <Directory />
        Options FollowSymLinks
        AllowOverride None
    </Directory>
    <Directory "/home/webroot">
        Options Indexes FollowSymLinks MultiViews
        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>

    <IfModule mod_userdir.c>
        UserDir public_html
    </IfModule>
    <IfModule mod_dir.c>
        DirectoryIndex index.html
        DirectoryIndex index.php
        DirectoryIndex index.php3
        DirectoryIndex index.phtml

    </IfModule>
    AccessFileName .htaccess
    <Files ~ "^\.ht">
        Order allow,deny
        Deny from all
        Satisfy All
    </Files>
    UseCanonicalName On
    <IfModule mod_mime.c>
        TypesConfig /usr/local/apache/conf/mime.types
    </IfModule>
    DefaultType text/plain
    <IfModule mod_mime_magic.c>
        MIMEMagicFile /usr/local/apache/conf/magic
    </IfModule>
    HostnameLookups Off
    ErrorLog /usr/local/apache/logs/error_log
    LogLevel warn
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common
    LogFormat "%{Referer}i -> %U" referer
    LogFormat "%{User-agent}i" agent
    CustomLog /usr/local/apache/logs/access_log common
    ServerSignature On
    <IfModule mod_alias.c>
        Alias /icons/ "/usr/local/apache/icons/"
        <Directory "/usr/local/apache/icons">
            Options Indexes MultiViews
            AllowOverride None
            Order allow,deny
            Allow from all
        </Directory>
        Alias /manual/ "/usr/local/apache/htdocs/manual/"
        <Directory "/usr/local/apache/htdocs/manual">
            Options Indexes FollowSymlinks MultiViews
            AllowOverride None
            Order allow,deny
            Allow from all
        </Directory>
        ScriptAlias /cgi-bin/ "/usr/local/apache/cgi-bin/"
        ScriptAlias /php4/ "/usr/local/php/bin/"
        # 注意 "/usr/local/php/bin/" 中最后一个"/"不可少
        <Directory "/usr/local/apache/cgi-bin">
            AllowOverride None
            Options None
            Order allow,deny
            Allow from all
        </Directory>
    </IfModule>
    <IfModule mod_autoindex.c>
        IndexOptions FancyIndexing
        AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip
        AddIconByType (TXT,/icons/text.gif) text/*
        AddIconByType (IMG,/icons/image2.gif) image/*
        AddIconByType (SND,/icons/sound2.gif) audio/*
        AddIconByType (VID,/icons/movie.gif) video/*
        AddIcon /icons/binary.gif .bin .exe
        AddIcon /icons/binhex.gif .hqx
        AddIcon /icons/tar.gif .tar
        AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv
        AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip
        AddIcon /icons/a.gif .ps .ai .eps
        AddIcon /icons/layout.gif .html .shtml .htm .pdf
        AddIcon /icons/text.gif .txt
        AddIcon /icons/c.gif .c
        AddIcon /icons/p.gif .pl .py
        AddIcon /icons/f.gif .for
        AddIcon /icons/dvi.gif .dvi
        AddIcon /icons/uuencoded.gif .uu
        AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
        AddIcon /icons/tex.gif .tex
        AddIcon /icons/bomb.gif core
        AddIcon /icons/back.gif ..
        AddIcon /icons/hand.right.gif README
        AddIcon /icons/folder.gif ^^DIRECTORY^^
        AddIcon /icons/blank.gif ^^BLANKICON^^
        DefaultIcon /icons/unknown.gif
        ReadmeName README.html
        HeaderName HEADER.html
        IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t
    </IfModule>
    <IfModule mod_mime.c>
        AddLanguage da .dk
        AddLanguage nl .nl
        AddLanguage en .en
        AddLanguage et .ee
        AddLanguage fr .fr
        AddLanguage de .de
        AddLanguage el .el
        AddLanguage he .he
        AddCharset ISO-8859-8 .iso8859-8
        AddLanguage it .it
        AddLanguage ja .ja
        AddCharset ISO-2022-JP .jis
        AddLanguage kr .kr
        AddCharset ISO-2022-KR .iso-kr
        AddLanguage nn .nn
        AddLanguage no .no
        AddLanguage pl .po
        AddCharset ISO-8859-2 .iso-pl
        AddLanguage pt .pt
        AddLanguage pt-br .pt-br
        AddLanguage ltz .lu
        AddLanguage ca .ca
        AddLanguage es .es
        AddLanguage sv .sv
        AddLanguage cs .cz .cs
        AddLanguage ru .ru
        AddLanguage zh-TW .zh-tw
        AddCharset Big5         .Big5    .big5
        AddCharset WINDOWS-1251 .cp-1251
        AddCharset CP866        .cp866
        AddCharset ISO-8859-5   .iso-ru
        AddCharset KOI8-R       .koi8-r
        AddCharset UCS-2        .ucs2
        AddCharset UCS-4        .ucs4
        AddCharset UTF-8        .utf8
        <IfModule mod_negotiation.c>
            LanguagePriority en da nl et fr de el it ja kr no pl pt pt-br ru ltz ca es sv tw
        </IfModule>
        AddType application/x-tar .tgz
        AddType application/x-httpd-php .php3
        AddType application/x-httpd-php .php
        AddType application/x-httpd-php .phtml

        AddEncoding x-compress .Z
        AddEncoding x-gzip .gz .tgz
    </IfModule>
    Action application/x-httpd-php "/php4/php"
    <IfModule mod_setenvif.c>
        BrowserMatch "Mozilla/2" nokeepalive
        BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
        BrowserMatch "RealPlayer 4\.0" force-response-1.0
        BrowserMatch "Java/1\.0" force-response-1.0
        BrowserMatch "JDK/1\.0" force-response-1.0
    </IfModule>
    php也有配置文件,但是修改起来比较简单,只需要把/home/lxz/php-4.4.8/php.ini-dist复制到ARM Linux文件系统的/usr/local/php/lib,并改名为php.ini,找到
    register_globals = Off
    修改为
    register_globals = On
    保存就可以了。
    如果你觉得上面的一切都很麻烦,可以在EE小站资料页面下载我制作好的压缩包,地址http://cosine.oicp.net/project/at91rm9200/armv4-apache-php.tar.bz2,解压缩到ARM Linux根文件系统的/。这个压缩包包含apache 1.3.39和php 4.4.8,默认的网页服务器根目录为/home/webroot,默认监听端口为80。
    另外,我在资料站上开了个wiki来测试ARM Linux上Apache+PHP的组合,地址http://cosine.oicp.net/dokuwiki/。测试的时间不会很长,但我会保证这个链接在2008年4月1号前有效。
    February 03

    半个猪年总结

    07年7月十多号来到北京,转眼半年了。今天公司放假了,写半个猪年的总结。
    首先介绍下我干活的公司,中国本土数控行业第二,当然和Fanuc、Siemens没法比,呵呵;我们以中低端产品为主打。刚才说的是销量,我觉得技术水平我们绝对国内第一;我拆解过主要竞争对手的产品,发现他们用的CPU已经停产了,但那可是他们的高端主打产品……我们公司研发的力量还是很雄厚的,这也头儿们的领导风格决定的。头儿们都是做技术出身,行为做事都很低调,在中国现在的拜金气氛下,这样不浮躁的头真的不多。但是中国市场是复杂的,技术好不能保证最好的销量,但是可以保证企业的长久生存。哈哈,扯远了,我这样的小兵,还是专心做好自己的事情先。
    反正这半年混的还凑合,不过把自己热爱的事业作为职业,业余时间也没有什么追求了,关心技术内容的人一定发现技术文章次了些,哈哈。其实我也不能多写了,现在签了卖身契,开源就等于自杀——如果要我付保密违约金,那干脆就杀了我吧。怪不得国内有些Linux大牛的文章都太监了,估计也是不想和钱过不去吧……现在有空我就游戏,我的QQ牌升级已经从来北京的时候的300分小房车变成现在600多分的小坦克了,最近打腻了,开始捡起研究生时候练的WOW小牧师,也许我该开个类别介绍我的游戏经验了。也许我有些宅,但是在北京这种地方,我也就能在看丹桥的冠京隆市场撑回款爷,出门玩,那就是大把大把的RMB啊。现在住的是公司的房子,要想买房,以我和GF的工资加起来,除去花销,一年也就能买四环外半个厕所。
    不知不觉在北方已经生活了6年半了,我觉得自己从口音、思维习惯到饮食口味已经都没有福州人的风格了,唯一剩下的是一张福州人脸,到哪儿人都一下认出我是南方人……我现在特别羡慕有口音的人,那说话多有味道啊。哦,其实我也有口音,说福州话有东北口音尴尬
    好了,废话说完放一些图片,先是我们公司前台,刚搬新楼,装修不错,关键是前台MM好漂亮,真是我情窦初开以来遇到的最漂亮的MM,每天我都要多看几眼,哈哈。更加幸运的是,这张照片里MM走光了。
     
     
     
    第一张图是我的猪窝办公桌,呵呵,我的口号是,做硬件的就得要有做硬件的样子。接下来的是我在学校的桌子,相比之下现在的我还是整洁许多的。
     
     
     
     
     
    我们公司的产品,这台是目前已经上市的产品里第二高端的,4轴系统;第一高端的是8轴的,我还没有见过实物。业内人士一定知道我在哪里工作了,刚才还有一点忘了说了,我觉得我们公司产品的外形是国内最酷的,这是唯一和Fanuc、Siemens不相上下的地方,哈哈。这台是我们用来调试的,面板有些旧。
     
     
     
    园区夜景,拍的时候没有发现那根电线,真烦人……手持相机,无三脚架,快门时间2秒,能拍出这样的效果我是不是很牛X?估计是焊接0603练出来的,哈哈。