2009年12月10日星期四

[转帖]AD6编译原理图时出现[ERROR]“Duplicate Net Names Element……”

 
 
 
 


刚开始看到"Duplicate Net Names Element[0]:N000-1(inferred)"的错误提示觉得很奇怪,因为根本没有N000-1这个Net,搞了很久才找到解决办法。这个错误一般是出现在一个项目里有多原理图时,原理图里面应用了Port就会出现这个问题。

原图:

修改后(关键要给总线也添加网络标号):


因为Port和总线只是图形上的表示(为了好看而已),如果觉得不方便可以直接不用Port,用个Text表示就可以了,懒人办法~~呵呵:


2009年11月24日星期二

2009年11月5日星期四

无题

对于爱情,我尽力保持其来自于本心,而不为其他所扰动;对于爱情,我尽力保持其真诚,而不为其他所侵蚀;对于爱情,我尽力避免对方受到伤害,而宁愿自己舔舐伤口;对于爱情,我一直充满了希望;
 
尽管,有时候有些话无法说出口;尽管,有时候乌云阻隔了方向;尽管,有时候船儿驶出了中央;我的心从未改变。
 
 

2009年10月16日星期五

LVDS-LCD驱动芯片选型

最近选用了一块台湾晶彩10.4寸的液晶屏,接口是18BIT的LVDS接口,故评估了几家的LVDS-LCD驱动器芯片 。

生产该类芯片的主要厂家有TI和NS,产品系列都比较全,而且两家的有些产品彼此兼容,两家对该类产品的叫法不同,TI叫做FlatLink (LVDS for LCD) ,而NS则叫做SerDes - Displays and Imaging Interface,又细分为FPD-Link/Open LDI LVDS 和FPD-Link II - Embedded Clock LVDS。而最常用的是TI的sn65lvds84a ,sn65lvds86a ,与此兼容的是NS的 FPD-Link/Open LDI LVDS系列的DS90C363B,DS90CF364A等。

另外,TI的资料较少,基本上只有DATASHEET,而NS的资料则较多。

另外还有一韩国厂家DOSTEK生产的DTC34LM85A系列较便宜,几十片的价格只有8元,相对于以上两家的千片价格动辄两三个美金的价格可谓相当便宜,不过恐怕质量够呛。

白光LED驱动器选型

最近要找一驱动液晶LED背光的驱动器,评估了几家的产品,最后选择了天�科技股份有限公司(http://www.fitipower.com/) 的FP6738。

生产该驱动器的主要有TI,LINEAR及台湾的一些小公司;TI和LINEAR 产品系列比较全,而且资料文档参考设计等比较全,供货好,产品质量也有保证,主要缺点是价格高,且基本上都是QFN封装的,手工焊接较难。而台湾公司产的很多是SOP-8封装的,容易焊接调试,主要缺点是产品系列不全,资料很少,供货不好。

评估的台湾公司:
白光LED驱动器 台湾天钰科技股份 http://www.fitipower.com/product.htm?cid=13&sc_id=18 资料相对要全,DATASHEET上有计算方法
白光LED驱动器 BITEK公司 www.bitek.com/ 资料不全,且控制复杂
白光LED驱动器 台湾E-CMOS www.ecmos.com.tw/ 主页上资料无法下载

2009年9月16日星期三

【转】关于verilog综合

转自:
http://hi.baidu.com/%B0%AE%B5%C4%BF%D5%BC%E4%B0%AE%B5%C4%CE%DD/blog/item/90993c03c27965074afb512e.html

一:基本
Verilog中的变量有线网类型和寄存器类型。线网型变量综合成wire,而寄存器可能综合成WIRE,锁存器和触发器。

二:verilog语句结构到门级的映射
1、连续性赋值:assign
连续性赋值语句逻辑结构上就是将等式右边的驱动左边的结点。因些连续性赋值的目标结点总是综合成由组合逻辑驱动的结点。Assign语句中的延时综合时都将忽视。

2、过程性赋值:
过程性赋值只出现在always语句中。

阻塞赋值和非阻塞赋值就该赋值本身是没有区别的,只是对后面的语句有不同的影响。

建议设计组合逻辑电路时用阻塞赋值,设计时序电路时用非阻塞赋值。

过程性赋值的赋值对象有可能综合成wire,latch,和flip-flop,取决于具体状况。如,时钟控制下的非阻塞赋值综合成flip-flop。

过程性赋值语句中的任何延时在综合时都将忽略。

建议同一个变量单一地使用阻塞或者非阻塞赋值。

3、逻辑操作符:
逻辑操作符对应于硬件中已有的逻辑门

4、算术操作符:
Verilog中将reg视为有符号数,而integer视为有符号数。因此,进行有符号操作时使用integer,使用无符号操作时使用reg。

5、进位:
通常会将进行运算操作的结果比原操作数扩展一位,用来存放进位或者借位。如:
Wire [3:0] A,B;
Wire [4:0] C;
Assign C=A+B;
C的最高位用来存放进位。

6、关系运算符:
关系运算符:<,>,<=,>=
和算术操作符一样,可以进行有符号和无符号运算,取决于数据类型是reg ,net还是integer。

7、相等运算符:==,!=
注意:===和!==是不可综合的。
可以进行有符号或无符号操作,取决于数据类型

8、移位运算符:
左移,右移,右边操作数可以是常数或者是变量,二者综合出来的结果不同。

9、部分选择:
部分选择索引必须是常量。

10、BIT选择:
BIT选择中的索引可以用变量,这样将综合成多路(复用)器。
11、敏感表:
Always过程中,所有被读取的数据,即等号右边的变量都要应放在敏感表中,不然,综合时不能正确地映射到所用的门。

12、IF:
如果变量没有在IF语句的每个分支中进行赋值,将会产生latch。如果IF语句中产生了latch,则IF的条件中最好不要用到算术操作。Case语句类似。Case的条款可以是变量。

如果一个变量在同一个IF条件分支中先赎值然后读取,则不会产生latch。如果先读取,后赎值,则会产生latch。

13、循环:
只有for-loop语句是可以综合的。

14、设计时序电路时,建议变量在always语句中赋值,而在该always语句外使用,使综合时能准确地匹配。建议不要使用局部变量。

15、不能在多个always块中对同一个变量赎值

16、函数
函数代表一个组合逻辑,所有内部定义的变量都是临时的,这些变量综合后为wire。

17、任务:
任务可能是组合逻辑或者时序逻辑,取决于何种情况下调用任务。

18、Z:
Z会综合成一个三态门,必须在条件语句中赋值

19、参数化设计:
优点:参数可重载,不需要多次定义模块

四:模块优化
1、资源共享:
当进程涉及到共用ALU时,要考虑资源分配问题。可以共享的操作符主要有:关系操作符、加减乘除操作符。通常乘和加不共用ALU,乘除通常在其内部共用。

2、共用表达式:
如:C=A+B;
D=G+(A+B);
两者虽然有共用的A+B,但是有些综合工具不能识别.可以将第二句改为:D=G+C;这样只需两个加法器.

3、转移代码:
如循环语句中没有发生变化的语句移出循环.

4、避免latch:
两种方法:1、在每一个IF分支中对变量赋值。2、在每一个IF语句中都对变量赋初值。

5:模块:
综合生成的存储器如ROM或RAM不是一种好方法。最好用库自带的存储器模块。

五、验证:
1、敏感表:
在always语句中,如果敏感表不含时钟,最好将所有的被读取的信号都放在敏感表中。

2、异步复位:
建议不要在异步时对变量读取,即异步复位时,对信号赎以常数值。

verilog综合时序仿真出现X状态解决一例

软件版本:ISE webpack 11.1 + Synplify Pro 9.6.1 + Modelsim SE 6.5
CPLD:xilinx XC9500系列
 
 
模块代码:
module rs485_fiber(clk, rs485_rx,fiber_rx, fiber_sd, 
                    rs485_tx, rs485_en, fiber_tx, led_tx, led_rx);
                    
    output rs485_tx, rs485_en, fiber_tx, led_tx, led_rx; 
    input  clk, rs485_rx, fiber_rx, fiber_sd;
    
    reg [2:0] delay;
    
    initial begin
        delay = 3'b000;
    end
    
   assign rs485_tx = ~fiber_rx;
   assign fiber_tx = ~rs485_rx;
   assign led_tx = rs485_rx;
   assign led_rx = rs485_tx & fiber_sd; 
   assign rs485_en = (~delay[2]) | (~delay[1]) | (~delay[0]);
 
   always @ (posedge clk )         //always @ (posedge clk or posedge fiber_rx)
        
       if (fiber_rx == 1)  
           delay <= 0;                           
       else
           if (delay == 7)
               delay <= 7;
           else
               delay <= delay + 1;            
endmodule
 
顶层测试代码:
module RS485_fiber_t;
// Inputs
reg clk;
reg rs485_rx;
reg fiber_rx;
reg fiber_sd;
// Outputs
wire rs485_tx;
wire rs485_en;
wire fiber_tx;
wire led_tx;
wire led_rx;
// Instantiate the Unit Under Test (UUT)
rs485_fiber uut (
.clk(clk), 
.rs485_rx(rs485_rx), 
.fiber_rx(fiber_rx), 
.fiber_sd(fiber_sd), 
.rs485_tx(rs485_tx), 
.rs485_en(rs485_en), 
.fiber_tx(fiber_tx), 
.led_tx(led_tx), 
.led_rx(led_rx)
);
 
always #15 clk <= ~clk; //15ns反转一次
always #5000 fiber_rx <= ~fiber_rx;  //5us反转一次
 
initial begin
// Initialize Inputs
clk = 0;
rs485_rx = 1;  
fiber_rx = 0;  
fiber_sd = 1;  
// Wait 100 ns for global reset to finish
#100;
        
// Add stimulus here
end
      
endmodule
 
 
synplify综合RTL图:
 
 
modelsim 前仿真没有问题,后仿真结果有问题:
 
 
 
修改模块代码,always @ (posedge clk )   为always @ (posedge clk or posedge fiber_rx)   则综合RTL图为:
modelsim 前仿真没有问题,后仿真结果也没有问题:
 
 
原因分析:
 
从代码1可以看出,综合的RTL图中有多个控制端的多路数据选择器,如果多个控制端同时动作(由于延时等),可能会冲突,导致逻辑短路,从而形成X状态。
 
而代码2综合生成的RTL图中多个控制端的多路数据选择器被简化为单个控制端的两路选择器,则不会有该问题。

2009年9月14日星期一

ISE11.1 + Modelsim SE 6.5 CPLD开发环境搭建

最近搞CPLD,使用的是XILINX的XC9572,搭建环境的过程网上和书本上介绍的都不是很系统,过程还是相当麻烦的,现总结一下。
 
步骤:
1,下载ISE Webpack 11.1免费版
去XILINX的官方主页下载,(首先要注册下)有两种下载方式(1)使用网络安装版;下载一个80多M的安装文件,该程序会根据你的设置下载相应的文件安装,优点是不需下载所有安装文件,只下载需要安装的;但是安装过程中如果网络断线,机器重启就要从头开始;(2)现在全部安装文件,大约2.7G,下载说明中说浏览器会下载一个下载插件,该插件会保证下载文件的完整性,及断点下载,但是俺的FIREFOX一直没提示安装插件,那个插件GOOGLE了半天也没找到,最后使用FLASHGET就下载下来了。
 
2,下载Modelsim SE
网上找个PJ版就可以,CSDN上有个6.5版本可以。需要注意的是ISE 11.1的POST FIT仿真和编译XILINX库只支持Modelsim SE 6.2版本以上的。
 
3,安装
先安装Modelsim SE,再安装ISE 11.1,会自动找到Modelsim的安装目录,设置好。如果没有设置好,在ISE 11.1的菜单 设置中设置一下即可。
 
4,编译XILINX库
理论上在新建的工程中全部编译即可,但是实践发现有些库不会编译,后仿真时会提示找不到库。网上有很多方法编译库,最方便的方法还是在 ISE安装目录\ISE\bin\nt 中执行compxlibgui.exe 程序,按照提示,注意要选中所有库(包括FPGA),否则编译库不全面。编译完成即可。
 
需要注意的是:编译完成后,会自动更新ISE安装目录\ISE\bin\nt \unwrapped \modelsim.ini文件,添加进加载库的路径。新建工程仿真时,ISE会复制该文件到你的工程目录,从而从ISE中调用Modelsim仿真时,会读取工程目录下的配置。所以,如果你是先建的工程仿真出错后又编译的库,则需要执行菜单命令clean下你的工程,重新编译综合仿真,从而仿真时又复制一遍配置文件,否则仿真时会找不到库。
 
5,新建工程 添加测试文件
使用Verilog文件,加入你的模型,编译综合成功后;添加测试文件,要选择Verilog texture文件(必须注意啊!!),该测试文件会自动保护一个测试框架,在里面添加测试语句即可。
 
一定要注意:测试文件一定要选择Verilog texture文件,我一开始选择的Verilog源文件,结果,仿真都正常,前仿真没有问题,而后仿真有个波形就是出不来,最后发现是文件类型不对!!
 
6,仿真
在仿真界面下,右击设定仿真时间、精度等等参数,双击即可自动打开Modelsim仿真,在命令窗口输入run 30us即可仿真。
 
 
 
其他:
安装ISE Webpack 11.1 好像不会自动安装Modelsim XE软件版本,但是会有一个ISIM可以进行仿真。

2009年9月11日星期五

ISE MODELSIM小记(1)

ISE版本:ISE WEBPACK 11.1
MODELSIM SE 6.5

从ISE中调用MODELSIM SE 6.5,执行的配置文件是该工程目录下的modelsim.ini文件,该文件是建立该工程时从I:\XILINX\ISE11.1-WEBPACK\ISE\bin\nt\unwrapped\modelsim.ini复制过来的,而不是modelsim安装目录中的。

要编译XINLINX的库,则执行I:\XILINX\ISE11.1-WEBPACK\ISE\bin\nt目录下compxlibgui.ex程序,按提示进行即可;要进行布线后的仿真必须选中全部的,如果不选FPGA,默认好像不编译simprims_ver库等,都选择全部即可。在ISE工程中编译时也是不会全部编译。

[转帖]Modelsim se完全编译xilnx库的方法

转自:http://hi.baidu.com/yoman/blog/item/7ea0b38b8ce32e7e9e2fb4bc.html


什么是之前的老办法呢?

Modlesim 仿真库的建立:
将Modelsim根目录下的modelsim.ini的属性由只读改为可写。
新建一个文件夹,比如library(为叙述方便,把它放在modelsim的根目录下)。D:/modelsim/library.
启动Modelsim,选择[File]/[chang Directory],选择D:/modelsim/library.

选择[File]/[New]/[library]命令,弹出[Creat a New library],在[lihrary Name]中输入"simprims_ver",同时下一栏也自动输入"simprims_ver",单击OK。

在主窗口中选择[compile]/[Compile]命令,弹出[compile Source Files],在[Library]的下拉列表中选择"simprims_ver"在[查找范围]中选中[Xilinx/veriog/src /simprims]目录下的全部文件,单击complie进行编译。(这时可能会花你一些时间,耐心等待编译完毕)用同样的方法将unisims和 Xilinxcorelib三个仿真库进行编译。

这时在D:/modelsim/library 下就有以上三个仿真库。

总结步骤为a:建立库的放置路径b:对库进行编译c:对库进行映射。最后重新启动Modelsim可以在列表中看到建立的三个库。

那么这个办法明显是比较麻烦的。其实我们可以这样做;

1.
首先将modelsim.ini文件只读模式去掉,存档前面打对勾。
2.
在您安装ise的目录下,进入到bin\nt目录下,例如e:\ise6\bin\nt,确认有compxlib这个程序
3.
在cmd中运行compxlib -s mti_se -f all -l all -o e:\modeltech_6.0\xilinx_libs就可以了,e:\modeltech_6.0是我安装modelsim的目录,您可以作相应的更改。参数也可以按照您的要求作相应的更改。

这样就可以了。

需要注意的是,千万记住ise和modelsim的安装目录都不要出现空格,最好是直接安装在根目录下。

具体单独用modelsim进行behavioral model的方法是,打开modelsim,把你的代码和仿真代码文件加入,别忘了加入glbl.v文件。在哪里?自己找吧。然后编译,work库这些设置好后,命令行(modelsim里的)输入

vsim -L Xilinxcorelib_ver -L unisims_ver -L simprims_ver -lib work $yourtestname glbl

就可以了

2009年9月10日星期四

安装Modelsim SE 6.5 (Post installation 时停止)

今天安装Modelsim SE 6.5 ,总是在Post installation script 进行到50%时,停止。最好,停掉诺顿杀毒、360、天网防火墙后,安装成功!!

2009年7月1日星期三

最近很乏

不知怎么回事,自从西安出差回来就感觉很累很累,晚上睡觉也很好,但还是感觉身体很累。真奇怪!

2009年6月8日星期一

想你

想你
  是一种痛
  隐隐的
  不常来,却挥不去
  初时不觉
  不觉中已渗入血液
  撕心裂肺
  想你
  是一种痛
  刻骨铭心的痛
  不常来,却深刻
  曾以为
  随时时间的流失
  会如那昙花般的消逝
  但是
  总会在一个不经意的时刻
  清风般的掠过心头
  如刀割般的清楚
  想你
  从不知疲惫
  却
  极累

2009年5月19日星期二

很好听的一首歌

<embed src="http://player.youku.com/player.php/sid/XNTU1OTE4ODA=/v.swf" quality="high" width="480" height="400" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash"></embed>
 
 
那些青春的日子,永难忘记;我知道青春和激情不会离我远去。

2009年5月18日星期一

祝福

忽闻俺五年级时暗恋的一美女将要结婚了,祝福之!

2009年5月11日星期一

arm9 fpga cpld开发板到手

最近购买了三块开发板,今天都试了一下,感觉还可以。微控电子的底板卖得太贵了,1000元,根本没有啥东西,自己做成本也没有那么多,不过可能主要是技术支持的费用,只购买核心板是没有技术支持的。FPGA CPLD开发板都是使用的并口下载线,要是再买个usb的下载线就爽了。
 
 
 
 

MDK9263核心板+扩展底板+彩屏液晶

1(1500)

微控电子http://www.mcuzone.com

当前底板没有批量板,购买手工焊接底板即可

FPGA开发板 红色飓风II-Altera

1(980)

FPGA开发板网http://www.fpgadev.com/shop_view.asp?id=28

 

CPLD开发板CA329

1(360)

联华众科http://www.lianhua-zhongke.com.cn/CA329-Brief.htm

2009年5月10日星期日

安装并口卡驱动

电脑上没有并口,为了使用并口下载线,买了一moschip的9805并口卡,可是安装光盘中的驱动出错,提示好像是"INF安装段无效",网上下了N个驱动,安装了N次还是无效。
 
最后,卸载了原来的驱动,在官方网站上下载了最新驱动,安装成功。留个记号!

2009年5月9日星期六

将ubuntu linux 8.04转移到新硬盘

因为硬盘不够了,最近刚花了660大洋购进一西数的1TB绿盘,今天装上了。原来硬盘上装的是windows xp和ubuntu linux 8.04,现在想把linux弄到新硬盘上,花了不少功夫,试验加google,终于成功了,赶快记下来,最近记性不好,有点少年痴呆。
 
1,挂上新硬盘,都是SATA接口的,确保新硬盘在原来硬盘的后面,如果位置不对,有可能启动失败(一个是bios启动不对,再一个是在grub和linux中分区号可能会改变,只有一个硬盘无论装在哪里都是sda,再加上一块就有可能变成了sdb)。
 
2,对新硬盘进行分区,我是使用的patition magic for dos 8.0,建立一个主分区 ext3格式,一个home分区和一个swap分区,其他的为NTFS分区。
 
3,使用ghost 8.3,把原来的主分区复制到新的主分区上。
 
4,修改grub for dos的menu.lst文件(我是使用grub for dos引导的linux),使其可以引导启动(这时交换分区还是使用的原来的,而根分区是加载的新的,但是因为在fstab中的根分区是原来的,所以会冲突,表现为查看磁盘分区的参数该两个分区会混乱),启动后更改fstab文件,更改根分区和交换分区的UUID,各分区UUID可以通过sudo blkid或ls -l /dev/disk/by-uuid或vol-id /dev/sda1等命令得到。(需要注意的是使用pq8.0分区后,新的linux分区除根分区有的没有uuid,那么除了swap分区,其它的分区在linux下通过自带的分区工具重新格式化一下即可,而swap分区则需要使用mkswap /dev/sdb6命令重新激活一下即可,如果当前swap分区已经挂载则需要先卸载)
 
又把home单独放到了一个分区上,方法参照上一篇日志。
 
幸亏手头上有个申请的ubuntu linux 7.10的光盘,在当前系统下不能操作的就是用光盘live cd启动。

转帖:调整硬盘空间并将home单独分区

转自:http://liupingjing.blog.ubuntu.org.cn/?p=634

 

一年前刚安装linux的时候因为对文件系统和分区只是了解太少,在分区的时候直接将60G的空间划给了/目录,随着系统里安装的软件和配置文件的增多,不爽的地方就来了。

  1. 首先是备份,以前/分区小的时候(小于9G)都是直接用clonezilla备份整个/分区,后来因为需要安装了VBOX,VBOX的虚拟硬盘有 10个G,都在家目录下面,再后来因为要搭建nios2linux交叉开发环境,又在家目录中用了5G空间,这样一来如果再备份的话可能备份文件就大于 10G了,真的不敢想象,因为home不是单独的分区,想把它隔离出来只用clonezilla备份其他目录也不可能,恼火的很;
  2. home不是单独分区的第二点坏处就是论坛里说的:一旦需要重装系统,配置文件就都不在了,如果home是独立分区的话,重装完将它挂载到/home目录就可以了,系统和以前的一模一样。

基于这两点原因(还有一个主要原因是很多天没有捣鼓系统了,有点儿心痒),下午决定调整原来的根分区大小,然后将腾出来的空间单独划为home,在论坛上看了些帖子,折腾了几个小时,总算没出什么岔子,步骤记录如下:

  1. 调整分区
    需要在卸载要操作的分区的状态下进行,因为要调整/分区,所以不能进入现在的linux中,一般有下面两种方式:
    • LiveCD:可以用光驱或硬盘启动的方式启动LiveCD,在LiveCD中完成分区大小的调整;
    • 其他Linux:启动硬盘其他分区或移动设备(移动硬盘或U盘)中的linux。

    我的电脑没有光驱,U盘里的prayaya-linux没有下载gparted(用于调整分区的软件),所以只能用硬盘启动LiveCD的方式来进行,这里不再多说。
    进入Linux后,以管理员权限启动gparted(没有的话就装一下,LiveCD默认就装了的),软件启动后,将/分区调小,在空出来的硬盘空间上建立新的分区(假设为sda11),文件系统最好和原来/的文件系统一致。

  2. 复制文件
    首先在liveCD或其他Linux中将原来的根分区(假设为/dev/sda8)和新分区(假设为/dev/sda11)挂载,挂载用以下命令,其中的8和11根据自己的实际情况而定:
    sudo mount /dev/sda8 /media/sda8
    sudo mount /dev/sda11 /media/sda11

    挂载后就可以复制文件了,但要注意,/home下的文件是有权限属性的,所以复制的时候这些属性也要保留,可以用下面的命令来复制:
    sudo cp -ax /media/sda8/home/* /media/sda11
    复制完毕后将原来的home目录改名(先不要删除,万一重启后有问题可以再复制一次),然后新建/home目录作为新分区的挂载点,命令如下:
    sudo mv /media/sda8/home/ /media/sda8/home_old
    sudo mkdir /media/sda8/home
  3. 修改/etc/fstab文件
    以管理员权限用编辑器(vi,emacs,gedit等均可)打开/etc/fstab文件,一般fstab文件里的分区都是以UUID标记的,所以要先查看一下调整分区后原来分区的UUID有没有变化,有变动的话要改动fstab文件中的相关项使其和现在保持一致,查看分区UUID的命令如下:
    sudo blkid
    修改了UUID后还没有完,现在的系统中已经没有/home了(虽然有home目录,但没有任何数据,因为系统启动时没有将分区/dev/sda11挂载到/home),所以需要在fstab文件中依葫芦花瓢地加上一行,内容如下:
    UUID=XXXXXXXXXX(新分区的UUID) /home ext3 defaults 0 2
    将fstab文件保存后关闭。

重启系统,一切已经OK了,好像还不是太难。

2009年4月19日星期日

液压系统仿真软件DSHplus-3.6与matlab simulink联合仿真

昨天回实验室,师弟们使用DSHplus-3.6与matlab simulink联合仿真出现问题,主要是DSHplus-3.6导出模型失败,帮忙给解决了下。
 
由于本人不是搞仿真的,对matlab也只是了解一下,所以难免有错误,不对的地方请指正。
 
软件版本:DSHplus-3.6测试版 matlab 6.5  vc++ 6.0
 
1,设置matlab:
在matlab中输入命令mex -setup ,会提示是否让matlab自己搜索编译器,选择y,然后选择编译器等等,选择 VC++ 6.0(当然首先要安装该软件)。这一步需要注意的是如果matlab是7.0的版本,好像需要把vc++ 6.0安装到C盘根目录的vs98目录下,共享文件夹COMMON也要安装到C盘根目录下,会有提示的;
注意:这一步只有执行一次即可,以后再不用执行,除非你重新安装了编译器、换了编译器或者更换了用户。
 
2,建立模型,设置DSHplus-3.6,导出模型:
DSHplus-3.6的仿真方式使用嵌入到simulink中仿真,即把在DSHplus-3.6建立的仿真模型导出成matlab可以识别的动态链接库,matlab调用这些动态链接库来仿真。导出前需要先编译模型(不知道是不是必须的,也不知道是干啥),在 "选项"中选择使用"VC++ 6.0"。
然后选择"导出",选择"matlab s-function",选择"embeded"和"cosimulation"。单击"start",会让你选择导出文件目录和文件名,例如文件夹为d:\de,文件名输入de.cpp,点击确认,看下面的信息栏,首先会编译de.cpp,这个应该是模型的核心部分,主要跟DSHplus相关,它会使用DSHplus的头文件和库;需要注意的是DSHplus自带borland c++ 5.3,这一步默认是使用borland c++编译链接的(选项里面有设置,头文件路径,编译选项,库路径等等,但是都不需要设置,默认的就好),而且可能也只能使用它编译链接,因为各编译器的库不能兼容,而DSHplus自带的库明显是borland c++ 5.3编译的,vc++无法链接。
编译的这一步一般都会没有错误。下一步是编译跟matlab的接口程序(s-fuction)部分,也就是de_dll.c文件,DSHplus会直接调用matlab的mex命令来编译,估计可能是使用 mex de_dll.c de.lib命令编译,但是因为编译模型核心部分时,没有生成de.dll的引入库de.lib,故这一步会失败,到底为啥没有生成引入库,搞不明白,一方面第一步编译模型核心部分de.dll时,是使用的borland c++,这是肯定的,不能更改,所以也就不能生成VC++使用的引入库,即使能生成,也不能直接在VC++中使用,难道是DSHplus-3.6设计的失误?
 
3,生成引入库:
DSHplus-3.6不能直接编译生成de_dll.dll,那我们只能手工生成了,在matlab下执行mex de_dll.c出现:
>> mex de_dll.c
Microsoft (R) Incremental Linker Version 6.00.8168 
Copyright (C) Microsoft Corp 1992-1998. All rights reserved. 
 
de_dll.obj  
   Creating library _lib4186.x and object _lib4186.exp 
de_dll.obj : error LNK2001: unresolved external symbol _getModuleData 
de_dll.obj : error LNK2001: unresolved external symbol _unmapModule 
de_dll.obj : error LNK2001: unresolved external symbol _mapModule 
de_dll.obj : error LNK2001: unresolved external symbol _setModuleData 
de_dll.dll : fatal error LNK1120: 4 unresolved externals 
 
  D:\MATLAB6P5\BIN\WIN32\MEX.PL: Error: Link of 'de_dll.dll' failed. 
 
??? Error using ==> mex
Unable to complete successfully
很明显,是不能链接。
执行D:\Program Files\Microsoft Visual Studio\VC98\Bin>dumpbin /exports de.dll>de.def  (VC++的目录根据安装自己更改)
de.def文件内容:
Microsoft (R) COFF Binary File Dumper Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
Dump of file de.dll
File Type: DLL
  Section contains the following exports for de.dll
           0 characteristics
           0 time date stamp Thu Jan 01 08:00:00 1970
        0.00 version
           1 ordinal base
           5 number of functions
           5 number of names
    ordinal hint RVA      name
          2    0 00001CB5 _getModuleData
          3    1 000019C6 _mapModule
          4    2 00001D7D _setModuleData
          1    3 00001E47 _setOutputCallback
          5    4 00001BDE _unmapModule
  Summary
        1000 .edata
        1000 .idata
        2000 .reloc
       18000 CODE
        7000 DATA
        1000 TLS
很明显,不能链接的函数在de.dll中,所以要生成de.dll的引入库!
生成方法:
a, 执行D:\Program Files\MinGW\bin>pexports de.dll>de.def  (pexports程序在MinGW的发行包中)
生成de.def文件内容:
LIBRARY de.dll
EXPORTS
_getModuleData
_mapModule
_setModuleData
_setOutputCallback
_unmapModule
 
b,对照dumpbin /exports de.dll>de.def  生成的de.def中函数列表的ordinal项,在每个函数后加上@x,中间有一空格,x为相应函数的ordinal项。
c,去掉每个函数前面的下划线;(在使用lib.exe生成引入库时,会自动加上下划线),de.def成为如下形式:
 
LIBRARY de.dll
EXPORTS
setOutputCallback @1
getModuleData @2
mapModule @3
setModuleData @4
unmapModule @5
d,生成引入库。D:\Program Files\Microsoft Visual Studio\VC98\Bin>lib.exe /def:de.def
就生成了引入库。
 
4,生成接口dll:
在matlab下执行 mex de_dll.c de.lib    一般就OK了(需要事先把dshplus的inlcude头文件目录加入到系统环境变量的inlclude中)。
 
5,在matlab下打开de.cdl,仿真即可
 
 
注意:从上面看,可能全部使用borland c++ 5.3编译器,会自动生成引入库和自动调用mex 生成dll成功,这就需要安装borland c++ 5.3,matlab中使用mex -setup设置borland c++ 5.3为默认编译器等等。
 
附录:
 
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
因为模型核心dll的导出函数是统一的,所以如果工程不改名的话(例如从dshplus导出时都选择de.cpp),则可以一直使用这个de.lib链接,如果想改名则改动de.def的第一行的de.dll到其他名字,重新生成lib即可。
 

【转帖】VC中无LIB时的DLL隐式链接,制作与VC++相符合的LIB函数符号输入库

 
 
请大家注意!这种方法只能应用于输出为C格式的__stdcall调用方式!
  1. 使用VC++的工具DUMPBIN将DLL中的导出函数表导出到一定义(.DEF)文件
  EXAMPLE:
   DUMPBIN VideoDeCoder.dll /EXPROTS /OUT:VideoDeCoder.def
  2. 将导出的.DEF文件整理为一符合.DEF个数的函数导出文件
  EXAMPLE:
   VideoDeCoder.DEF 文件内容如下
  
   Dump of file VideoDeCoder.dll
  
   File Type: DLL
  
   Section contains the following exports for VideoDeCoder.dll
  
   0 characteristics
   3D49E48F time date stamp Fri Aug 02 09:46:55 2002
   0.00 version
   1 ordinal base
   11 number of functions
   11 number of names
  
   ordinal hint RVA name
  
   1 0 00010F60 _TM_ClearDecoderBuff@4
   2 1 00010E80 _TM_CloseDecoder@4
   3 2 00010F00 _TM_DecodePicture@4
   4 3 00010ED0 _TM_DecodePictureHeader@4
   5 4 00010FD0 _TM_GetFileEnd@4
   6 5 00011030 _TM_GetUValue@4
   7 6 00011060 _TM_GetVValue@4
   8 7 00011000 _TM_GetYValue@4
   9 8 00010E10 _TM_OpenDecoder@8
   10 9 00010F30 _TM_ReturnType@4
   11 A 00010F90 _TM_SetFileEnd@8
  
   Summary
  
   2000 .data
   1000 .rdata
   1000 .reloc
   15000 .text
   按照以下方法整理:
   1>添加LIB说明
   LIBRARY "VideoDeCoder" ;"xx"为DLL名称
   DESCRIPTION "VideoDeCoder library"
   2>去掉导出函数说明端以外的内容,在LIB说明下添加 "EXPROTS" 说明导出函数
   LIBRARY "VideoDeCoder"
   DESCRIPTION "VideoDeCoder library"
   EXPORTS
   ordinal hint RVA name
  
   1 0 00010F60 _TM_ClearDecoderBuff@4
   2 1 00010E80 _TM_CloseDecoder@4
   3 2 00010F00 _TM_DecodePicture@
   4 3 00010ED0 _TM_DecodePictureH
   5 4 00010FD0 _TM_GetFileEnd@4
   6 5 00011030 _TM_GetUValue@4
   7 6 00011060 _TM_GetVValue@4
   8 7 00011000 _TM_GetYValue@4
   9 8 00010E10 _TM_OpenDecoder@8
   10 9 00010F30 _TM_ReturnType@4
   11 A 00010F90 _TM_SetFileEnd@8
   3>将所有的函数放至行首,去掉 "hint" 和 "RVA" 数据,留下函数的序号 "ordinal" ,在序号前加上 "@" 符号
   形成 "_导出函数名@参数字节和 @序号" 此种格式(__stdcall 方式调用导出的函数符号是 "函数名称@参数字节和").
   最后形成.DEF文件如下:
   LIBRARY "VideoDeCoder"
   DESCRIPTION "VideoDeCoder library"
   EXPORTS
  
   TM_ClearDecoderBuff@4 @1
   TM_CloseDecoder@4 @2
   TM_DecodePicture@4 @3
   TM_DecodePictureHeader@4 @4
   TM_GetFileEnd@4 @5
   TM_GetUValue@4 @6
   TM_GetVValue@4 @7
   TM_GetYValue@4 @8
   TM_OpenDecoder@8 @9
   TM_ReturnType@4 @10
   TM_SetFileEnd@8 @11
  3. 使用VC++的LIB工具,带/DEF:(.def文件名) /MACHINE:IX86(80X86机器),就输出符合VC++格式的的LIB文件了.
  EXAMPLE:
   LIB /DEF:VideoDeCoder.def /MACHINE:IX86
  4. 接时带上LIB文件链接;注意的是当有些动态库DUMPBIN的只有函数名,无"@nn"的参数格式,如C++Builder写的DLL,输出就只有函数名符号,链接时就会报错:
  error LNK2002:unresolved external symbol "functionname@nn"
  提示程序中引入的函数符号无法识别,这时只要将DEF文件中相应的函数名称改为functionname@nn方式,重新建立
  LIB,重新链接即可.
  这样就制作成功了符合VC调用方式的LIB了!
  参考:MSDN2000
  要值得一说的是!BORLAND C++BUILDER有一个很好的工具IMPDEF可以直接将DLL中的函数输出到.DEF文件中,只要做一点点修改就可以成为符合VC的DEF文件!
  IMPDEF xxx.def xxx.dll
  这种方法只能应用于输出为C格式的__stdcall调用方式经过我的论证有些错误!我利用Borland C++和VC++做论证,发现:
  而在C++BUILDER中!
  __cdecl的函数输出前会带一"_"
  __stdcall无特征,只输出函数名
  __fastcall函数输出前带一"@"
  都无"@nn"后缀格式!
  在VC中!
  __cdecl无特征,只输出函数名
  __stdcall的函数输出前会带一"_"后缀带"@nn"
  __fastcall函数输出前带一"@"后缀带"@nn
  只要将BC的DEF文件中函数申明格式转换为VC识别的格式就可以利用LIB工具生成LIB;要使用C分格输出(extern "C")才是必须的!而且别忘了在DEF文件中的函数申明不要带"_"啊!:)不然会出现error LNK2001的链接错误!

2009年4月12日星期日

偶记

终于,小静也结婚了,像这位能从初中一下谈恋爱到结婚的,还是第一次见到,很幸福。但中午不知是啥原因,不想吃饭,面对着山珍海味竟然吃不下,真是郁闷,大家都不想喝酒,也就没有喝,两点多就各自散了。在李村玩了一会儿直接在超市买菜去了光光家做饭吃,有,虾米丝瓜,炒香菇,辣椒豆腐皮,炒茄子,肉炒胡萝卜,肉炒芹菜。俺做了其中两样,不过比较失败,主要是因为他们吓指导的,呵呵。光光已经下定决心考博了,我暂时还没有打算,不过等空闲下来应该去海大上上自习了,憧憬中!在青岛又要少了一把酒话科技的知己实在是有些不舍,然人生漂泊,有聚有散,常事而已。临回来拿了3本路遥的《平凡的世界》,记得上次看是在初中二年级了,时间久远,只记得有郝红梅这个人,还有就是主人公烧砖窑这几段,花了晚上和一上午的时间,基本上有浏览了一遍,又共鸣了一番。想自己可能并不适合看这类书,看了总要伤心流泪,总要融入到情节里面去。
 
无意间看到漫山的桃花开了,满眼的粉红,煞是好看。不禁想起 东邪西毒 里面的"他是因为那个女人才喜欢桃花的"这句话来,不禁哑然失笑,笑那位盲武士也笑自己,不过是微笑。
 
中午睡了一觉,没想到一直到3点,本来是想出去玩的,在院子里的长凳上坐了一个小时,看庭前花开花落,迎春花正开得艳,而玉兰已是落红,樱花也开了,满山的桃红,蚂蚁也出洞了,各样蝴蝶翩翩起舞。不想又过了一年,我还要独自赶路,有时候感觉看到了前面的灯光,咫尺却又天涯。"Wars come and go, but soldiers remain."。想是自己本不喜欢不停地行走的,原来漫步,爬山,游泳,都喜欢不停的运动,一直处在行动之中,从不长时间停下来观赏周围的风景,现在发现自己更喜欢独自坐在一个地方,观察周围的事物,思考自己的所为与思想,只有处在宁静的状态之中才能到达心灵的深处,才能荡尽内心的垃圾,但这样会孤独。可能另一种方式是邀一知己(也许生命的另一半更好),相坐而不言语,观风景而达禅定。
 
现在感觉到了,人与人之间,特别是男人与女人之间,很像是刺猬,离得近了可以彼此取暖而太近却又会刺伤对方。原来我是宁可别人伤害我,也不愿伤害别人,现在好像是首先不想自己被伤害,也许是受过的伤害太多吧,有很多东西都是有原因的,也是很难控制的。凡是自由应该以不伤害别人为准。
 
想我这种人,想找到人生一伴侣实在是小概率事件,不用说样子有点有伤市容,没钱没才没脑子,偏偏又是个理想主义者,感觉可遇而不可求,非得半年、几年才能产生感情,靠原始点的感觉定夺吧,理性又不允许,介绍对象对俺基本上就是一不靠谱的事。思想超前又中庸,性格外向又腼腆,内心自卑又骄傲,心灵君子又"禽兽",智商中上又阿甘,思维自由又保守,胸有大志又无所作为,喜欢有才的又喜欢漂亮的.....
 
时间到,暂停胡扯。

2009年4月2日星期四

代码

花了不到两个月时间写了大约2万多行代码,虽然因为时间要求紧,代码有很多地方很臃肿,但是已经很不错了。第一次写这么大的代码,进展还算是很顺利。喘下气

2009年3月27日星期五

zt ANSI C中取得结构体字段偏移值的惯用法

http://dev.21tx.com/2005/01/18/14190.html

 

假设在ANSI C程序中定义了一个名为MyStruct的结构类型,其中有一个名为MyField的字段,如何取得它在结构体中的偏移?

typedef struct MyStruct_tag
{
  // some fields
  ...

  long MyField;

  // other fields
  ...
} MyStruct;


    最容易想到的方法应该与如下代码差不多:

size_t GetOffset()
{
  MyStruct s;

  return (size_t)( (char*)(&s.MyField) - (char*)(&s) );
}

    这段代码确实能完成任务,但为了取得偏移值,函数不得不定义了一个MyStruct结构体实例,可这有必要吗?仔细想想,结构体的内存布局是在什么时候由谁决定的?没错,是编译器在编译期确定的,它一旦被确定就不会改变了,而依赖于结构体内存布局的字段偏移也就随之确定并不再改变。既然在编译阶段编译器就洞悉了内幕,那么我们完全有理由要求它在编译期为程序提供这些信息。如何做呢?请看下面的代码:

#define MY_OFFSET (size_t)&(((MyStruct*)0)->MyField)

    上面定义的MY_OFFSET宏就是我们要的MyField的偏移。一定有人问,这样强制转换后的结构指针怎么可以用来访问结构体字段?呵呵,其实这个表达式根本没有也不打算访问MyField字段。ANSI C标准允许任何值为0的常量被强制转换成任何一种类型的指针,并且转换结果是一个NULL指针,因此((MyStruct*)0)的结果就是一个类型为 MyStruct*的NULL指针。如果利用这个NULL指针来访问MyStruct的成员当然是非法的,但& (((MyStruct*)0)->MyField)的意图并非想存取MyField字段内容,而仅仅是计算当结构体实例的首址为 ((MyStruct*)0)时MyField字段的地址。聪明的编译器根本就不生成访问MyField的代码,而仅仅是根据MyStruct的内存布局和结构体实例首址在编译期计算这个(常量)地址,这样就完全避免了通过NULL指针访问内存的问题。又因为首址的值为0,所以这个地址的值就是字段相对于结构体基址的偏移。

    如上做法避免了一定要实例化一个MyStruct对象,并且求值是在编译期进行,没有运行期负担。实际上这种利用编译器掌握的整个程序的信息以在编译期计算某些值的方法与现在C++编程中很流行的(静态)元编程技术类似,只不过C++程序员可以利用模板技术在编译期完成非常复杂的计算,而缺乏模板支持的ANSI C在这方面的能力则要弱许多。

    或许因为求结构体字段偏移很常用,ANSI C在标准头文件stddef.h中就专门定义了一个形如offsetof(s,m)的宏来求任意一个结构类型中某个字段的偏移,而且绝大多数C开发系统的实现都采用了上述的方法,例如:

// VC7.1
#ifdef  _WIN64
#define offsetof(s,m)   (size_t)( (ptrdiff_t)&(((s *)0)->m) )
#else
#define offsetof(s,m)   (size_t)&(((s *)0)->m)

2009年3月24日星期二

[转] 有些事,一转身就是一辈子

有些人一直没机会见,等有机会见了,却又犹豫了,相见不如不见。

有些事一直没机会做,等有机会了,却不想再做了。

有些话埋藏在心中好久,没机会说,等有机会说的时候,却说不出口了。

有些爱一直没机会爱,等有机会了,已经不爱了。


有些人很多机会相见的,却总找借口推脱,想见的时候已经没机会了。

有些话有很多机会说的,却想着以后再说,要说的时候,已经没机会了。

有些事有很多机会做的,却一天一天推迟,想做的时候却发现没机会了。

有些爱给了你很多机会,却不在意没在乎,想重视的时候已经没机会爱了


人生有时候,总是很讽刺。

一转身可能就是一世。说好永远的,不知怎么就散了。

最后自己想来想去竟然也搞不清当初是什么原因分开彼此的。

然后,你忽然醒悟,感情原来是这么脆弱的。

经得起风雨,却经不起平凡;风雨同船,天晴便各自散了。


也许只是赌气,也许只是因为小小的事。

幻想着和好的甜蜜,或重逢时的拥抱,那个时候会是边流泪边捶打对方,还傻笑着。

该是多美的画面。

没想到的是,一别竟是一辈子了。

于是,各有各的生活,各自爱着别的人。

曾经相爱,现在已互不相干。

即使在同一个小小的城市,也不曾再相逢。

某一天某一刻,走在同一条街,也看不见对方。

先是感叹,后来是无奈。

也许你很幸福,因为找到另一个适合自己的人。

也许你不幸福,因为可能你这一生就只有那个人真正用心在你身上。

很久很久,没有对方的消息,也不再想起这个人,也是不想再想起这些事

2009年3月19日星期四

keil MDK3.23a + WinARM-2006060无法链接

原来用着keil MDK3.23a + WinARM-2006060 配合的挺好的,不过随着文件和子目录的增多,最近问题多多,首先是选项里的优化等级设置的不能保存,后来是经常链接出错,有时候说找不到文件,而文件名是给的却字母的文件名;有时候是非得跟默认的启动文件链接。感觉应该是keil传递给gcc的链接参数有问题,最后只能采取了一方法,还是不错的,就是使用makefile链接(傻瓜都能想出来的方法,呵呵)。然后一个批处理解决问题。
 
俺的makefile的内容:
#
#  $Id: Makefile 1.1 2009-03-12 22:03:17Z yushiyou $
#  $Revision: 1.1 $
#  $Author: jcw $
#  $Date: 
#  
#  只是链接所有文件的makefile
#  不使用默认的启动文件,使用标准库和数学库,不进行垃圾清理,生成map文件
export CC=D:\WinARM\bin\arm-elf-gcc
export AR=D:\WinARM\bin\arm-elf-ar
export OBJCOPY=D:\WinARM\bin\arm-elf-objcopy
export OBJDUMP=D:\WinARM\bin\arm-elf-objdump
ELF: 
$(CC) -T .\LPC2294-ERAM.ld -Wl,-Map=".\lst\psmu-c30-m.map"  -o .\obj\psmu-c30-m.elf .\obj\*.o -nostartfiles -lm
 
俺的批处理的内容:
REM 链接文件的批处理
D:\WinARM\utils\bin\make ELF
pause

C语言中的对齐

Win32平台下的微软C编译器(cl.exe for 80x86)在默认情况下采用如下的对齐规则: 任何基本数据类型T的对齐模数就是T的大小,即sizeof(T)。比如对于double类型(8字节),就要求该类型数据的地址总是8的倍数,而 char类型数据(1字节)则可以从任何一个地址开始。Linux下的GCC奉行的是另外一套规则(在资料中查得,并未验证,如错误请指正):任何2字节大小(包括单字节吗?)的数据类型(比如short)的对齐模数是2,而其它所有超过2字节的数据类型(比如long,double)都以4为对齐模数。
 
ANSI C规定一种结构类型的大小是它所有字段的大小以及字段之间或字段尾部的填充区大小之和。填充区就是为了使结构体字段满足内存对齐要求而额外分配给结构体的空间。那么结构体本身有什么对齐要求吗?有的,ANSI C标准规定结构体类型的对齐要求不能比它所有字段中要求最严格的那个宽松,可以更严格(但此非强制要求,VC7.1就仅仅是让它们一样严格)。
 
__attribute__((packed))意思是按最小对齐,也就是单字节。__attribute__((aligned(n)))是指按n字节对齐,这里的对齐不仅指起始位置n字节对齐,也指的结束的位置也是n字节对齐。对于结构来说,例如:
struct E{
        char a;
        int b;
        unsigned short c;
        long d;
        unsigned long long e;
        char f;
}__attribute__((aligned(8)));
结构内部的成员按照自己的对齐方式,而该结构的起始和结束位置都要8字节对齐,所以a占4字节,b占4字节,c占4字节,d占4字节,e占8字节,f占8字节(为了结束位置对齐),总共占32字节。
struct E{
        char a;
        int b;
        unsigned short c;
        long d;
        unsigned long long e;
        char f;
}__attribute__((aligned(4)));
a占4字节,b占4字节,c占4字节,d占4字节,e占8字节,f占4字节,共28字节。
 
但是:
struct E{
        char a;
        int b;
        unsigned short c;
        long d;
        unsigned long long e;
        char f;
}__attribute__((aligned(1)));
也是占用28字节,怎样解释?可能,"ANSI C标准规定结构体类型的对齐要求不能比它所有字段中要求最严格的那个宽松",这个条件的优先级更高。它屏蔽了__attribute__((aligned(1)))这个条件。(注意该处编译器是GCC,处理器认为是arm,"Linux下的GCC奉行的是另外一套规则(在资料中查得,并未验证,如错误请指正):任何2字节大小(包括单字节吗?)的数据类型(比如short)的对齐模数是2,而其它所有超过2字节的数据类型(比如long,double)都以4为对齐模数")。
 
而例如#pragma pack(1) ,则应该是对所有数据类型的对齐吧!

利用XMPP协议进行远程控制

原来转过一篇《gtalk机器人实验成功》(http://yushiyou.blogspot.com/2008/09/zt-gtalk.html。刚发现了一个使用于嵌入式系统的XMPP客户端 iksemel(https://www.ohloh.net/p/iksemel ):

iksemel is an XML (eXtensible Markup Language) parser library designed for Jabber applications.

Some features:

Highly portable, builds on all POSIX environments and Windows (via mingw). Suitable for embedded systems. Code is small and highly modular, you can trim unneeded parts. Memory usage is low, parser is quite fast. Provides SAX, DOM and XMPP parsers. TLS (via gnutls) and SASL support for XMPP security. Only UTF8 encoding is built-in supported. Fully documented with examples. Latest source code is currently hosted at this subversion repo:

http://svn.pardus.org.tr/projeler/iksemel/

兼容POSIX接口,那么应该也支持ECOS,RTEMS啊!那就好了,使用块ARM7和COTEX-3内核的ARM即可,跑个ecos还是绰绰有余的!实在不行就用个ATMEL的ARM9,不过50多元,北京君正的也行啊,国产的才30多元,软件支持的也很好,linux,wince的都提供完整的平台软件,功耗很小,可以长期开着,还可以淘宝上买个路由器,刷下机,跑个linux。的gtalk的客户端和机器人,解析远程命令并进行相应的操作,开个灯、开个空调、开个热水器啥的,很是不错!

移植Microchip Graphics Library(PIC GUI)到ARM7 + RA8835(SED1335)上刷屏慢的解决方法

上次移植的Microchip Graphics Library(PIC GUI) 在LPC2214上运行很慢,即使主频提高到48Mhz还是很慢,大概刷一屏要1秒。感觉关键问题,一个是RA8835的读写速度太慢,大约在1MHZ;再一个,底层只实现了画点函数,这样如果填充一个矩形,就必须每个点都要画,而其实一次写可以画8个点,还有每次画点都要先设置光标,读回数据,修改,设置光标,写数据,浪费了大量时间;
 
一种加速的方法是,在片内内存设置一屏数据的缓冲区,写屏时对缓冲区操作,速度快,操作完成后,根据裁剪域,把裁剪域数据一次写入液晶控制器;
 
再一种方法也是在片内内存设置一屏数据的缓冲区,每次操作先对缓冲区操作,然后把得到的字节写入控制器,这样画点时对液晶控制器的读写简化为设置光标,写数据;uc/gui的SED1335驱动(UCGUI332a_LCDDriver的LCDSLin.c文件 )就是采用了这种方法,再加上画水平直线,画垂直直线等的优化函数;
 
经仔细分析,发现第一种方法没法实现,因为在GOLDraw() 函数返回时,没有有效的裁剪域存在;只能使用第二种方法。

2009年3月13日星期五

zt非诚勿扰征婚启事英译版

 
  Here's his announcement looking for a bride.
  你要想找一帅哥就别来了,你要想找一钱包就别见了,硕士学历以上的免谈,上海女人免谈,女企业家免谈(小商小贩除外),省得咱们互相都会失望。刘德华和阿汤哥那种财貌双全的郎君是不会来征你的婚的,当然我也没有做诺丁山的梦。您要真是一仙女我也接不住,没期待您长得更画报封面一样看一眼就魂飞魄散。外表时尚,内心保守,身心都健康的一般人就行,要是多少还有点儿婉约那就更靠谱了。心眼儿别太多岁数别太小,允许时常有不切实际的想入非非,但三句话就能给轰回现实还不气脑顶多有点儿难为情地咧嘴一笑就该干吗干吗去了。我喜欢会叠衣服的女人,每次洗完烫平叠得都像刚从商店里买回来的一样。说得够具体了吧。
  If you are looking for a handsome guy or a wallet,don't reply;If you hold a Master's degree or higher, not possible;girls born in Shanghai, not possible;female entrepreneurs(except small business hawker), not possible, so that we don't waste each other's hope. The Andy Liu or Tom criuse kind, ,who are both wealthy and good-looking, would not make an announcement looking for you. Surely, I don't expect a Notting Hill story either. Even if you're indeed an angle, I won't be able to handle you――I don't expect that you looks like that girl on the magazine cover, just one look crushing people's souls.An averge person, with outside stylishness and inside conservativeness,with fit body and mind,will just do, even better if you're beautifully shy. You need not to play too many tricks or be too young, from time to time, you're allowed to have unrealistic dreams, but a few words is enough to get you back into reality without getting you angry――a little embarassed grin at most,and then do what you ought to do. I like a woman who knows how to fold clothes in a way that whenever you finish washing, ironing and folding them, they will look just like when you bought them from stores. It cannot be more specific than this, can it?
  自我介绍一下,我,岁数已经不小了,日子小康,抽烟不喝酒,留学生身份出去的,在国外生活过十几年,没正经上过学,蹉跎中练就一身生存技能,现在学无所成海外归来,实话实说应该定性为一只没有公司没有股票没有学位的"三无劣海龟"。性格OPEN,人品五五开,不算老实人,但天生胆小,杀人不犯法我也杀不了人,伤天害理了自己良心也备受摧残,命中注定想学坏都当不了大坏蛋。总体而言基本上还是属于对人类对社会有益无害的一类。
  Let me introduce myself for you. I'm a man whose age is no longer small, living a moderately well-off life, who doesn't drink but smoke. I went abroad as a student and spent more than a decade living abroad, but never attended a real education. In wasting time, I learned all sorts of ways to make a living. Now I returned with no achivement at all. To tell you the truth, I should be judged as a "Fake Turtle" without the three―No company, no stocks and no degree. My personality is open;My character is neither good nor bad. I'm not exactly an honest man, but I am without much courage since I was born. Even it is not illegal to kill, I wouldn't kill anyone. My conscience will be tortured by the guilt if I do anything cruel to others.I am meant not to be a villain, even if I try to be one. In general and basically, I'm still one of those who are beneficial and harmless to the mankind and our society.
  有意者电联,非诚勿扰
  Contact me by phone, if you're the one.

2009年2月27日星期五

function list for notepad++

这里有unicode 版的下载:

http://randronov.blogspot.com/2008/11/function-list-for-notepad-5x-unicode.html

其实notepad++ 5.2 的zip包中有ansi的下载的。

2009年2月24日星期二

离思

曾经沧海难为水,除却巫山不是云。
取次花丛懒回顾,半缘修道半缘君。
上星期天,大程结婚请客。这是自打毕业以来的第一次聚会,班里同学共12人,实到10人。4月份还有两个人结婚,时间过得真快。好怀念上学的岁月。

2009年2月16日星期一

做项目

感觉自己要做项目的话必须一气呵成,中间不能有任何停顿,因为自己对某一方面的兴趣不会保持太长;
另外还要制定切实可行的计划,并在实行过程中贯彻执行;

2009年2月2日星期一

转帖:使用__attribute__处理对齐问题

 
GNU C扩展的__attribute__ 机制被用来设置函数、变量、类型的属性,其用得较多的是处理字节对齐的问题。

__attribute__ 的语法为:
[code]__attribute__ ((语法列表))[/code]

参数aligned(number) [number为最小对齐的字节数]是用得较多的一个。
另一个是参数packed 表示"使用最小对齐"方式,即对变量是字节对齐,对于域是位对齐。

这个例子稍长了点,不过非常简单:
[root@Kendo develop]# cat align.c
[code]#include <stdio.h>

struct A{
        char a;
        int b;
        unsigned short c;
        long d;
        unsigned long long e;
        char f;
};

struct B{
        char a;
        int b;
        unsigned short c;
        long d;
        unsigned long long e;
        char f;
}__attribute__((aligned));

struct C{
        char a;
        int b;
        unsigned short c;
        long d;
        unsigned long long e;
        char f;
}__attribute__((aligned(1)));


struct D{
        char a;
        int b;
        unsigned short c;
        long d;
        unsigned long long e;
        char f;
}__attribute__((aligned(4)));

struct E{
        char a;
        int b;
        unsigned short c;
        long d;
        unsigned long long e;
        char f;
}__attribute__((aligned(8)));

struct F{
        char a;
        int b;
        unsigned short c;
        long d;
        unsigned long long e;
        char f;
}__attribute__((packed));

int main(int argc, char **argv)
{
        printf("A = %d, B = %d, C = %d, D = %d, E = %d, F = %d\n",
                sizeof(struct A), sizeof(struct B), sizeof(struct C), sizeof(struct D), sizeof(struct E), sizeof(struct F));
        return 0;
}[/code]

在一个32位机上运行结果如下:

[code][root@Kendo develop]# gcc -o align align.c
[root@Kendo develop]# ./align            
A = 28, B = 32, C = 28, D = 28, E = 32, F = 20[/code]

我们看到,最后一个struct F,1 + 4 + 2 + 4 + 8 + 1 = 20,因为使用了__attribute__((packed)); 来表示以最小方式对齐,所以结果刚好为20。

而第一个struct A,因为什么也没有跟,采用默认处理方式:4(1) + 4 + 4(2) + 4 +  8 + 4(1) = 28,括号中是其成员本来的大小。与此相似的是struct D。

接下来看struct E,采用8个字节的方式来对齐:8(1+4+2 ,即a, b, c)+ 8(4, d) + 8 + 8(1, f) = 32。

而在struct C中,试图使用__attribute__((aligned(1))) 来使用1个字节方式的对齐,不过并未如愿,仍然采用了默认4个字节的对齐方式。

在struct B中,aligned没有参数,表示"让编译器根据目标机制采用最大最有益的方式对齐"――当然,最有益应该是运行效率最高吧,呵呵。其结果是与struct E相同。

在对结构的大小并不关注的时候,采用默认对齐方式或者编译器认为最有益的方式是最常见的,然后,对于一些对结构空间大小要求严格,例如定义一个数据包报头的时候,明白结构的对齐方式,就非常有用了。

转帖:c语言中的内存对齐

http://blog.csdn.net/ztz0223/archive/2007/05/10/1602970.aspx

 

先看一个具体的问题:


内存对齐的问题。

struct倘若如此声明:
struct something {
...
...
}

如果在结构体后面加上__attribute__((packed));记得带上后面的";"那么就是严格的各个成员的大小之和。
或者可以在程序开头的地方加上#pragma pack(N),其中N为对齐的字节数,若为1则和__attribute__((packed))是一个意思了.当然了,若#pragma pack(N)放在结构体的定义后面定义那么对结构体是无效的啦.

我们看一个程序:
#include<stdio.h>
//#pragma pack(1)
struct node{
       //int i;
       char aa[5];
       int i;
       struct node *front;
       struct node *next;
       };//__attribute__((packed));
//#pragma pack(1)

int main(void)
{
    int a;
    a=sizeof(char);
    printf("a=%d",a);
    a =sizeof(struct node );
    printf("a=%d",a);
    getchar();
    }
其中__attribute__((packed))和#pragma pack(1)是我尝试对齐用的.采用不对齐的形式就可以看出struct node *front和struct node *next都是占用的4个字节,这个是与结构体的大小,形式没有关系了.

下面引用人家的一篇文章说明具体的结构分配.

许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐,而这个k则被称为该数据类型的对齐模数(alignment modulus)。当一种类型S的对齐模数与另一种类型T的对齐模数的比值是大于1的整数,我们就称类型S的对齐要求比T强(严格),而称T比S弱(宽松)。这种强制的要求一来简化了处理器与内存之间传输系统的设计,二来可以提升读取数据的速度。比如这么一种处理器,它每次读写内存的时候都从某个8倍数的地址开始,一次读出或写入8个字节的数据,假如软件能保证double类型的数据都从8倍数地址开始,那么读或写一个double类型数据就只需要一次内存操作。否则,我们就可能需要两次内存操作才能完成这个动作,因为数据或许恰好横跨在两个符合对齐要求的8字节内存块上。某些处理器在数据不满足对齐要求的情况下可能会出错,但是Intel的IA32架构的处理器则不管数据是否对齐都能正确工作。不过Intel奉劝大家,如果想提升性能,那么所有的程序数据都应该尽可能地对齐。Win32平台下的微软C编译器(cl.exe for 80x86)在默认情况下采用如下的对齐规则: 任何基本数据类型T的对齐模数就是T的大小,即sizeof(T)。比如对于double类型(8字节),就要求该类型数据的地址总是8的倍数,而 char类型数据(1字节)则可以从任何一个地址开始。Linux下的GCC奉行的是另外一套规则(在资料中查得,并未验证,如错误请指正):任何2字节大小(包括单字节吗?)的数据类型(比如short)的对齐模数是2,而其它所有超过2字节的数据类型(比如long,double)都以4为对齐模数。
  
  现在回到我们关心的struct上来。ANSI C规定一种结构类型的大小是它所有字段的大小以及字段之间或字段尾部的填充区大小之和。嗯?填充区?对,这就是为了使结构体字段满足内存对齐要求而额外分配给结构体的空间。那么结构体本身有什么对齐要求吗?有的,ANSI C标准规定结构体类型的对齐要求不能比它所有字段中要求最严格的那个宽松,可以更严格(但此非强制要求,VC7.1就仅仅是让它们一样严格)。我们来看一个例子(以下所有试验的环境是Intel Celeron 2.4G + WIN2000 PRO + vc7.1,内存对齐编译选项是"默认",即不指定/Zp与/pack选项):
  
  typedef struct ms1
  {
  char a;
  int b;
  } MS1;
  
  假设MS1按如下方式内存布局(本文所有示意图中的内存地址从左至右递增):
  _____________________________
  |    |          |
  |  a  |    b     |
  |    |          |
  +---------------------------+
  Bytes:  1       4
  
  因为MS1中有最强对齐要求的是b字段(int),所以根据编译器的对齐规则以及ANSI C标准,MS1对象的首地址一定是4(int类型的对齐模数)的倍数。那么上述内存布局中的b字段能满足int类型的对齐要求吗?嗯,当然不能。如果你是编译器,你会如何巧妙安排来满足CPU的癖好呢?呵呵,经过1毫秒的艰苦思考,你一定得出了如下的方案:
  
  _______________________________________
  |    |\\\\\\\\\\\|         |
  |  a  |\\padding\\|    b     |
  |    |\\\\\\\\\\\|         |
  +-------------------------------------+
  Bytes:  1     3       4
  
  这个方案在a与b之间多分配了3个填充(padding)字节,这样当整个struct对象首地址满足4字节的对齐要求时,b字段也一定能满足int型的4字节对齐规定。那么sizeof(MS1)显然就应该是8,而b字段相对于结构体首地址的偏移就是4。非常好理解,对吗?现在我们把MS1中的字段交换一下顺序:
  
  typedef struct ms2
  {
  int a;
  char b;
  } MS2;
  
  或许你认为MS2比MS1的情况要简单,它的布局应该就是
  
  _______________________
  |       |    |
  |   a    |  b  |
  |       |    |
  +---------------------+
  Bytes:   4      1
  
  因为MS2对象同样要满足4字节对齐规定,而此时a的地址与结构体的首地址相等,所以它一定也是4字节对齐。嗯,分析得有道理,可是却不全面。让我们来考虑一下定义一个MS2类型的数组会出现什么问题。C标准保证,任何类型(包括自定义结构类型)的数组所占空间的大小一定等于一个单独的该类型数据的大小乘以数组元素的个数。换句话说,数组各元素之间不会有空隙。按照上面的方案,一个MS2数组array的布局就是:
  
  |<-  array[1]   ->|<-  array[2]   ->|<- array[3] .....
  
  __________________________________________________________
  |       |    |       |   |
  |   a    |  b  |   a    |  b |.............
  |       |    |       |   |
  +----------------------------------------------------------
  Bytes: 4     1     4      1
  
  当数组首地址是4字节对齐时,array[1].a也是4字节对齐,可是array[2].a呢?array[3].a ....呢?可见这种方案在定义结构体数组时无法让数组中所有元素的字段都满足对齐规定,必须修改成如下形式:
  
  ___________________________________
  |       |    |\\\\\\\\\\\|
  |   a    |  b  |\\padding\\|
  |       |    |\\\\\\\\\\\|
  +---------------------------------+
  Bytes:   4      1     3
  
  现在无论是定义一个单独的MS2变量还是MS2数组,均能保证所有元素的所有字段都满足对齐规定。那么sizeof(MS2)仍然是8,而a的偏移为0,b的偏移是4。
  
  好的,现在你已经掌握了结构体内存布局的基本准则,尝试分析一个稍微复杂点的类型吧。
  
  typedef struct ms3
  {
  char a;
  short b;
  double c;
  } MS3;
  
  我想你一定能得出如下正确的布局图:
  
  padding
  |
  _____v_________________________________
  |  |\|   |\\\\\\\\\|        |
  | a |\| b |\padding\|    c    |
  |  |\|   |\\\\\\\\\|        |
  +-------------------------------------+
  Bytes: 1 1  2    4      8
  
  sizeof(short)等于2,b字段应从偶数地址开始,所以a的后面填充一个字节,而sizeof(double)等于8,c字段要从8倍数地址开始,前面的a、b字段加上填充字节已经有4 bytes,所以b后面再填充4个字节就可以保证c字段的对齐要求了。sizeof(MS3)等于16,b的偏移是2,c的偏移是8。接着看看结构体中字段还是结构类型的情况:
  
  typedef struct ms4
  {
  char a;
  MS3 b;
  } MS4;
  
  MS3中内存要求最严格的字段是c,那么MS3类型数据的对齐模数就与double的一致(为8),a字段后面应填充7个字节,因此MS4的布局应该是:
  _______________________________________
  |    |\\\\\\\\\\\|         |
  |  a  |\\padding\\|    b     |
  |    |\\\\\\\\\\\|         |
  +-------------------------------------+
  Bytes:  1     7       16
  
  显然,sizeof(MS4)等于24,b的偏移等于8。
  
  在实际开发中,我们可以通过指定/Zp编译选项来更改编译器的对齐规则。比如指定/Zpn(VC7.1中n可以是1、2、4、8、16)就是告诉编译器最大对齐模数是n。在这种情况下,所有小于等于n字节的基本数据类型的对齐规则与默认的一样,但是大于n个字节的数据类型的对齐模数被限制为n。事实上,VC7.1的默认对齐选项就相当于/Zp8。仔细看看MSDN对这个选项的描述,会发现它郑重告诫了程序员不要在MIPS和Alpha平台上用 /Zp1和/Zp2选项,也不要在16位平台上指定/Zp4和/Zp8(想想为什么?)。改变编译器的对齐选项,对照程序运行结果重新分析上面4种结构体的内存布局将是一个很好的复习。
  
  到了这里,我们可以回答本文提出的最后一个问题了。结构体的内存布局依赖于CPU、操作系统的规定. 

转帖:单字节大小枚举及按位对齐

http://linux0818.bokee.com/viewdiary.179592916.html

 

在linux下定义一个枚举,我们用gcc编译时,得到的大小默认为4个字节,但如何让这个枚举大小为1个字节呢?下面我们看看一个例子test.c:

#include <stdio.h>
enum he {
    AGE = 0x01,
    NAME = 0x02
};

enum she {
    AGE1 = 0x03,
    NAME2 = 0x04
};

struct bear {
    char x;
    char y;
    enum he he;
    enum she she;
    int z;
};

 

int main(int argc, char **argv)
{
    int size = 0;
    struct bear bear;
    size = sizeof(struct bear);
    printf("size is:%d\n", size);
    return 0;
}

用gcc test.c时,得出来的结构体的大小为16个字节,两个char型为2个字节,由于第二个char型后面为4个字节的enum型,所以按默认的4个字节对齐,前两个char型为4个字节。再加上两个enum,一个int型,所以总共16个字节。

 

然而在"#include <stdio.h>"下行加上#pragma  pack(1) 编译运行后得到得结构体的大小为14个字节。因为这是按1个字节对齐,两个char型为两个字节,加两个enum,一个int共14个字节。

 

上面说的是按位对齐,而要把enum变为单个字节,则只需在上面的代码编译时,再加上-fshort-enums参数就行了:

gcc test.c -fshort-enums

运行后得到此结构体的大小只有8个字节了。上面的两个enum型就成就单字节的枚举了。

 

下面对-fshort-enums在gcc手册中的解释:

-fshort-enums
    Allocate to an "enum" type only as many bytes as it needs for the declared range of possible values. Specifically, the "enum" type will be equivalent to the smallest integer type which has enough room.

    Warning: the -fshort-enums switch causes GCC to generate code that is not binary compatible with
code generated without that switch.  Use it to conform to a non-default application binary interface.

2009年2月1日星期日

放假归来

在家待了7天,终于回来了。在家基本上是吃了睡,睡了吃,顺便走亲戚,同学聚会。但是心情不好,长大了,事情也就多了,不能再无忧无虑了,向往另一种生活,但是有一些真的无法摆脱。想要改变世界,改变别人,发现连自己也改变不了。
 
新的一年 新的开始,送走了失落的2008,迎来了充满期待的2009。希望我的2009不再平凡!

2009年1月21日星期三

The Software Development Process

The Software Development Process
 
We have now gone through the various phases in the process of writing a software. These phases can be summarised as follows:
1. What (Analysis)
2. How (Design)
3. Do It (Implementation)
4. Test (Testing and Debugging)
5. Use (Operation or Deployment)
6. Maintain (Refinement)

2009年1月16日星期五

转帖:使用结构体中成员变量指针的教训

 
今天碰到的问题,跟这篇文章差不多,也是有关结构体和字节对齐的事儿。
__packed struct _tag_A
{
    char        a;
    char        b;
    char        c;
    int         d;
};
void Set1(struct _tag_A *p)
{
    p->d = 0x12345678;
}
void Set2(int *p)
{
    *p = 0x12345678;
}
int main(void)
{
    struct _tag_A s;
    int i;
    while(1)
    {
        //第一种方法
        Set1(&s);
        //第二种方法
        Set2((int*)&(s.d));
        //第三种方法
        Set2(&i);
        s.d = i;
    }
}
上面的代码,用了三种方法,修改结构体_tag_A的成员d。这段代码在VC下面没有测试过,但是在ADS下面,编译和执行都不会报错,但是只有其中的两个执行结果是对的,另外一个是错的,你觉得是那两个呢?
这是我今天刚刚碰到的。问题倒不是什么大问题,却会象陷阱一样潜伏着,成为软件的隐患。
问题发现后,再仔细想想,其实也不难理解。第一、三种方法没有什么问题,第二种方法中,Set2函数的形参是int*,编译器对这个内存的处理默认是4字节对齐的,也就是说丢失了有关结构体的"字节对齐"的信息,而第一种和第三种都保留了这些信息,所以执行的时候也就没有什么问题了。 

2009年1月12日星期一

使用TOR突破GFW

连FreeRTOS.org都被GFW了!!相当的郁闷啊!FireFOX的gladder插件今天也不好用了,使用了tor,很爽很强大!可到这里下载http://tor.zuo.la/download.html.zh-cn ,它的官方网站也被GFW了。安装指南,google里搜"http://tor.zuo.la/download.html.zh-cn "。

有点烦,决定闭关2个月

至2009.3.12日期间,不再上google reader, qq(为避免被腾讯收回,可上一次), msn, 校友录等等;
除问问题外,不再上daxia, 21ic, linux fans, csdn等;
不再下载任何内容,仅仅消化已下载的内容;
不再主动参加任何活动;
手机不定期关机,有事请邮箱,非诚勿扰;
 
只发表blog,上gtalk, 邮箱,上ecos freertos 官方网站,linux仅上http://www.linuxforum.net/ 和oldlinux。
 
于士友 2009.1.12

2009年1月10日星期六

某人的生日

今天是某人的阴历生日,跟我的阳历生日一样,我还没有忘记。

2009年1月9日星期五

看了 非诚勿扰

昨天晚上看了 非诚勿扰,很不错的一部片子,今天又看了一遍。想了很多,又都忘了。怎样把握住真爱,怎样得到真爱,怎样不为外物所迷惑,怎样把持住自我......
 
很奇怪,昨天晚上竟然做了一个梦,梦见跟高中的哥们,他们的女朋友,还有一个女孩,但不知道是谁,也在那个北海道的悬崖上玩耍,很美很美的一个梦........醒来只能记得起些许。
 
我所缺乏的只是那个真正理解我的那个人,我也在等待被她所拯救......,也许她就在不远处

2009年1月8日星期四

喜欢和爱的区别

http://news.xinhuanet.com/school/2006-06/09/content_4670611.htm

    人世间有种情感叫"喜欢",另一种叫"爱"

    爱是他在的时候,眼睛里只有他一人;他不在的时候,一切都带有他的影子。

    喜欢是在深夜看书时突然想起他,想象他现在做什么,心里漾起一阵轻飘飘的温暖,却从不主动给他打电话。几分钟后,注意力又重新被书中的情节吸引!

    爱是在寂寞的夜里,思念如潮水般涌来,手里捧着书却怎么也看不进去,心里惦记着他此时是否还在加班,吃没吃晚饭,是不是如自己想着他一般想着自己

    喜欢是和他讨论问题争的面红耳赤,各不相让,在他面前像个刺猬一样从不认输,但在心里却早已暗暗佩服他的见地他的才华。

    爱是希望他和自己步调一致,和自己心灵相通,他无心说的一句玩笑话也能让自己顷刻情绪低落甚至眼泪汪汪。在他面前,自己是从不设防的。

    喜欢是出门在外给他发个短信,告诉他这边的天气很好,然后把手机关掉,独自在异地疯玩一个星期,晒成一个黑人后突然出现在他面前吓他一跳。

    爱是无论到哪都希望有他陪伴。可以站在海边给他打手机,让他听听海浪的声音;也可以因为在异乡的街道上看到一个酷似他的背影而愣在原地久久不动。

    喜欢是他出差前简单的道一声"一路平安",看着他离去的背影,心中有一点不舍,却什么也不说,只是默默等待他归来的消息. 

    爱是他临出差前千叮咛万嘱咐,往他的背包里塞满衣服和食物,在车站要等到火车开走才肯离开。并且在他走后的日子里天天心神不定,一遍遍的祈祷他能够平安归来。

    喜欢是在受伤的时候,不想让他看到自己脆弱的一面,在他面前把眼泪悄悄抹掉,转过头依然是一副快乐坚强的模样。 

    爱是在受委屈的时候,爬在他的胸前痛哭,没有伪装没有顾虑,把所有的烦恼统统告诉他,并渴望从他的怀抱中得到安慰。

    喜欢是看到他和另一个女孩牵手走过,心里有一点点疼,但很快会冲着朝阳重新扬起笑脸。 

    爱是输不起的游戏,付出全部只后,留下的可能仅仅是刻在心底的一道伤痕

    喜欢一个人是想要他是自己的,所以,可以喜欢很多人,想要很多人都是自己的。 

    爱是明明离不开他,却要不得不放弃他,因为他要的幸福,也许我给不了。不敢霸占他,希望看他找到幸福,即使那份幸福不是跟我分享的。

    喜欢是,希望寂寞的时候,无聊的时候,伤感的时候,找个人说说话。 

    爱是,在任何时候都想跟他分享,快乐的时候甚至希望把所有快乐都给了他。

    喜欢是,在很久很久没联络的时候,接到他的电话,然后笑着听他说话。 

    爱是,在几天没有联络的时候,着急得的打电话给他,然后忍住眼泪笑一笑。

    喜欢,只有在一起的时候,才惦记着对方。 

    爱,是哪怕是在一起,每一秒钟也都在思念思念他。

    喜欢一个人,在一起的时候会很开心 

    爱一个人,在一起的时候,会莫名的失落

    喜欢一个人,在一起的时候永远是欢乐 

    爱一个人,你会常常流泪

    喜欢一个人,当你想起他,你会微微一笑 

    爱一个人,当你想起他,你会对着天空发呆

    喜欢一个人,你要得只是今天 

    爱一个人,你期望的是永远

    喜欢一个人,是看到了他的优点 

    爱一个人,是包容了他的缺点

    当你不想再爱一个人,你要闭上眼睛并忍着泪水 

    当你不想再喜欢一个人,你只要掩住双耳!

    喜欢,是一种心情
    爱,是一种感情
    喜欢,是一种直觉
    爱,是一种感觉
    喜欢,可以停止
    爱,没有休止

    喜欢一个人,特别自然
    爱一个人,特别坦然
    喜欢一个人,有时候盼和他在一起
    爱一个人,有时候怕和他在一起

    喜欢一个人,不停的和他争执
    爱一个人,不停的为他付出
    喜欢一个人,希望他可以随时找到自己
    爱一个人,希望可以随时找到他

    喜欢你,却不一定爱你
    爱你,就一定很喜欢你

///////////////////////////////////////////////////////////////////////////////////////////////////////////

貌似很对,喜欢很多,却忘不了那一个!

在Google Talk上与MSN好友聊天

   俺是一铁打的google fans,对google的产品颇有好感,当然聊天工具也不例外,gtalk简约的界面,自由的思想,让俺心旷神怡,不过没有几个朋友使用gtalk,大多都是使用msn或者qq,偶然发现有在gtalk上与msn通讯的方法,可参照http://soft.yesky.com/lianluo/315/2550315.shtml 的一篇文章。于是立即试验了一把。注意文中的PSI需要去http://psi-im.org/ 下载;服务器的列表在这里http://imfederation.com/networks.html 。
 
 
但是实际使用还是不爽,首先没有找到比较好的支持MSN的服务器,只找到一个jaim.at,但是却不能自动登入。相当郁闷,而且取消也很麻烦,可详见这里http://www.mmmca.com/blog_moccafe/p_full/97696.html 。无奈之下还是算了吧!
 
期待出现一统一的IM平台,可以与所有主流的IM通信,支持主流的功能,最好还是使用统一的帐号登录。其实也就是统一的信息接入方式,统一的服务方式,统一的认证!试想你的聊天,邮箱,BBS,文档管理,BLOG,RSS订阅,手机,校友录....等其他个人定制服务都无缝整合到一齐!那就比较爽了。GOOGLE的所有业务都体现了这一点,也许GOOGLE能完成这一重任!

2009年1月5日星期一

元旦三天

第一天,跟同事从石老人走到栈桥;
第二天,陪朋友买电脑;
第三天,在朋友家看电影,吃喝;
 
累啊!