最新日志

发表于:2008-3-31 10:03:03
标签:资源  网站  

0

资源网站

http://softdata.studa.com           //下载 

http://ibook8.com/

http://www.dzzl.cn/   电子资料城

www.ithao123.com
http://www.no1edu.net/                     //中华学习网
http://www.stdcpp.cn/           //C++

 

http://www.jswl.cn/course/A1013/wljczs/index0303.htm     //计算机网络知识
http://www.networkdictionary.cn/                      //网络大典

源代码和技术资料站点
vchelp.net                gb
csdn.net                  gb
codeguru.com              en
codetools.com             en
dexv.com                  en
msdn.microsoft.com        en
programmerheaven.com      en
freshmeat.net             en
sourceforge.net           en
www-900.ibm.com/developerWorks/ gb

论坛和标准,组织
linuxaid.com.cn gb
linuxbyte.com gb
aka.org.cn gb
rfc.org en gb

 

全部免费.下载
一定能学到好东西
我也是自己一个人在学啊!

1.发现源码网
http://www.findcode.cn/
2.从菜鸟到高手:Linux系统实用教程
http://www.chinabyte.net/SoftCha ... 40812/1841862.shtml
3.专业电子书库
http://www.netyi.net/index.htm
4.vb爱好者乐园
http://www.vbgood.com/
5.电子资源书库(有很多教程,管理员挺负责)
http://www.downbooks.cn
6.豆豆源码下载(视频多多,排名3000多)
http://code.ddvip.net/list/sort000134_1.html
7.vb编程-安全中国
http://anqn.com/dev/vb/index.shtml
8.在线英语.推荐
http://www.tingroom.com/


/////////////IP通信联盟
http://www.microvoip.com/

//////////IPTV
http://www.iptvworld.net/

点击此处查看原文 >>

系统分类: 资源共享   |    用户分类:    |    来源: 整理

评论(0) | 阅读(192)
发表于:2008-2-28 17:53:42
标签:  

0

地的分类

1. 信号“地”;

信号“地”又称参考“地”,就是零电位的参考点,也是构成电路信号回路的公共段,图形符号“⊥”。

1) 直流地:直流电路“地”,零电位参考点。

2) 交流地:交流电的零线。应与地线区别开。

3) 功率地:大电流网络器件、功放器件的零电位参考点。

4) 模拟地:放大器、采样保持器、A/D转换器和比较器的零电位参考点。

5) 数字地:也叫逻辑地,是数字电路的零电位参考点。

6) “热地”:开关电源无需使用变压器,其开关电路的“地”和市电电网有关,既所谓的“热地”,它是带电的,图形符号为:“ ”。

7) “冷地”:由于开关电源的高频变压器将输入、输出端隔离;又由于其反馈电路常用光电耦合、既能传送反馈信号又将双方的“地”隔离;所以输出端的地称之为“冷地”,它
不带电。图形符号为“⊥”。

2.保护“地”;

保护“地”是为了保护人员安全而设置的一种接线方式。保护“地”线一端接用电器,另一端与大地作可靠连接。

3.音响中的“地”。

1) 屏蔽线接地:音响系统为防止干扰,其金属机壳用导线与信号“地”相接,这叫屏蔽接地。

2) 音频专用“地”:专业音响为了防止干扰,除了屏蔽“地”之外,还需与音频专用 “地”相连。此接地装置应专门埋设,并且应与隔离变压器、屏蔽式稳压电源的相应接地端相连后作为音控室中的专用音频接地点。


不同地线的处理方法:

1. 数字地和模拟地应分开;

在高要求电路中,数字地与模拟地必需分开。即使是对于A/D、D/A转换器同一芯片上两种“地”最好也要分开,仅在系统一点上把两种“地”连接起来。

2.浮地与接地;

系统浮地,是将系统电路的各部分的地线浮置起来,不与大地相连。这种接法,有一定抗干扰能力。但系统与地的绝缘电阻不能小于50MΩ,一旦绝缘性能下降,就会带来干扰。通常采用系统浮地,机壳接地,可使抗干扰能力增强,安全可靠。

3.一点接地;

在低频电路中,布线和元件之间不会产生太大影响。通常频率小于1MHz的电路,采用一点接地。

4.多点接地。

在高频电路中,寄生电容和电感的影响较大。通常频率大于10MHz的电路,采用多点接地.

点击此处查看原文 >>

系统分类: 嵌入式   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(225)
发表于:2008-2-28 17:52:31
标签:零欧姆电阻  

1

0欧姆电阻的作用

0欧姆电阻的作用

大概有以下几个功能:①做为跳线使用。这样既美观,安装也方便。②在数字和模拟等混合电路中,往往要求两个地分开,并且单点连接。我们可以用一个0欧的电阻来连接这两个地,而不是直接连在一起。这样做的好处就是,地线被分成了两个网络,在大面积铺铜等处理时,就会方便得多。附带提示一下,这样的场合,有时也会用电感或者磁珠等来连接。③做保险丝用。由于PCB上走线的熔断电流较大,如果发生短路过流等故障时,很难熔断,可能会带来更大的事故。由于0欧电阻电流承受能力比较弱(其实0欧电阻也是有一定的电阻的,只是很小而已),过流时就先将0欧电阻熔断了,从而将电路断开,防止了更大事故的发生。有时也会用一些阻值为零点几或者几欧的小电阻来做保险丝。不过不太推荐这样来用,但有些厂商为了节约成本,就用此将就了。④为调试预留的位置。可以根据需要,决定是否安装,或者其它的值。有时也会用*来标注,表示由调试时决定。⑤作为配置电路使用。这个作用跟跳线或者拨码开关类似,但是通过焊接固定上去的,这样就避免了普通用户随意修改配置。通过安装不同位置的电阻,就可以更改电路的功能或者设置地址。
 
 

点击此处查看原文 >>

系统分类: 嵌入式   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(312)
发表于:2008-2-28 17:48:21
标签:无标签

1

上拉电阻

上拉电阻:
1、当TTL电路驱动COMS电路时,如果TTL电路输出的高电平低于COMS电路的最低高电平(一般为3.5V),这时就需要在TTL的输出端接上拉电阻,以提高输出高电平的值。
2、OC门电路必须加上拉电阻,才能使用。
3、为加大输出引脚的驱动能力,有的单片机管脚上也常使用上拉电阻。
4、在COMS芯片上,为了防止静电造成损坏,不用的管脚不能悬空,一般接上拉电阻产生降低输入阻抗,提供泄荷通路。
5、芯片的管脚加上拉电阻来提高输出电平,从而提高芯片输入信号的噪声容限增强抗干扰能力。
6、提高总线的抗电磁干扰能力。管脚悬空就比较容易接受外界的电磁干扰。
7、长线传输中电阻不匹配容易引起反射波干扰,加上下拉电阻是电阻匹配,有效的抑制反射波干扰。
上拉电阻阻值的选择原则包括:
1、从节约功耗及芯片的灌电流能力考虑应当足够大;电阻大,电流小。
2、从确保足够的驱动电流考虑应当足够小;电阻小,电流大。
3、对于高速电路,过大的上拉电阻可能边沿变平缓。综合考虑
以上三点,通常在1k到10k之间选取。对下拉电阻也有类似道理
对上拉电阻和下拉电阻的选择应结合开关管特性和下级电路的输入特性进行设定,主要需要考虑以下几个因素:
1. 驱动能力与功耗的平衡。以上拉电阻为例,一般地说,上拉电阻越小,驱动能力越强,但功耗越大,设计是应注意两者之间的均衡。
2. 下级电路的驱动需求。同样以上拉电阻为例,当输出高电平时,开关管断开,上拉电阻应适当选择以能够向下级电路提供足够的电流。
3. 高低电平的设定。不同电路的高低电平的门槛电平会有不同,电阻应适当设定以确保能输出正确的电平。以上拉电阻为例,当输出低电平时,开关管导通,上拉电阻和开关管导通电阻分压值应确保在零电平门槛之下。
4. 频率特性。以上拉电阻为例,上拉电阻和开关管漏源级之间的电容和下级电路之间的输入电容会形成RC延迟,电阻越大,延迟越大。上拉电阻的设定应考虑电路在这方面的需求。
下拉电阻的设定的原则和上拉电阻是一样的。
OC门输出高电平时是一个高阻态,其上拉电流要由上拉电阻来提供,设输入端每端口不大于100uA,设输出口驱动电流约500uA,标准工作电压是5V,输入口的高低电平门限为0.8V(低于此值为低电平);2V(高电平门限值)。
选上拉电阻时:
500uA x 8.4K= 4.2即选大于8.4K时输出端能下拉至0.8V以下,此为最小阻值,再小就拉不下来了。如果输出口驱动电流较大,则阻值可减小,保证下拉时能低于 0.8V即可。当输出高电平时,忽略管子的漏电流,两输入口需200uA200uA x15K=3V即上拉电阻压降为3V,输出口可达到2V,此阻值为最大阻值,再大就拉不到2V了。选10K可用。COMS门的可参考74HC系列设计时管子的漏电流不可忽略,IO口实际电流在不同电平下也是不同的,上述仅仅是原理,一句话概括为:输出高电平时要喂饱后面的输入口,输出低电平不要把输出口喂撑了(否则多余的电流喂给了级联的输入口,高于低电平门限值就不可靠了)             
 
在数字电路中不用的输入脚都要接固定电平,通过1k电阻接高电平或接地。
1. 电阻作用:
   接电组就是为了防止输入端悬空
   减弱外部电流对芯片产生的干扰
   保护cmos内的保护二极管,一般电流不大于10mA
   上拉和下拉、限流
1. 改变电平的电位,常用在TTL-CMOS匹配
2. 在引脚悬空时有确定的状态
3.增加高电平输出时的驱动能力。
4、为OC门提供电流
   那要看输出口驱动的是什么器件,如果该器件需要高电压的话,而输出口的输出电压又不够,就需要加上拉电阻。
  如果有上拉电阻那它的端口在默认值为高电平你要控制它必须用低电平才能控制如三态门电路三极管的集电极,或二极管正极去控制把上拉电阻的电流拉下来成为低电平。反之,  尤其用在接口电路中,为了得到确定的电平,一般采用这种方法,以保证正确的电路状态,以免发生意外,比如,在电机控制中,逆变桥上下桥臂不能直通,如果它们都用同一个单片机来驱动,必须设置初始状态.防止直通!

2、定义:
  上拉就是将不确定的信号通过一个电阻嵌位在高电平!电阻同时起限流作用!下拉同理!
  上拉是对器件注入电流,下拉是输出电流
  弱强只是上拉电阻的阻值不同,没有什么严格区分
  对于非集电极(或漏极)开路输出型电路(如普通门电路)提升电流和电压的能力是有限的,上拉电阻的功能主要是为集电极开路输出型电路输出电流通道。

3、为什么要使用拉电阻:
  一般作单键触发使用时,如果IC本身没有内接电阻,为了使单键维持在不被触发的状态或是触发后回到原状态,必须在IC外部另接一电阻。
  数字电路有三种状态:高电平、低电平、和高阻状态,有些应用场合不希望出现高阻状态,可以通过上拉电阻或下拉电阻的方式使处于稳定状态,具体视设计要求而定!
  一般说的是I/O端口,有的可以设置,有的不可以设置,有的是内置,有的是需要外接,I/O端口的输出类似与一个三极管的C,当C接通过一个电阻和电源连接在一起的时候,该电阻成为上C拉电阻,也就是说,如果该端口正常时为高电平,C通过一个电阻和地连接在一起的时候,该电阻称为下拉电阻,使该端口平时为低电平,作用吗:比如:当一个接有上拉电阻的端口设为输如状态时,他的常态就为高电平,用于检测低电平的输入。
  上拉电阻是用来解决总线驱动能力不足时提供电流的。一般说法是拉电流,下拉电阻是用来吸收电流的,也就是你同学说的灌电流。

点击此处查看原文 >>

系统分类: 嵌入式   |    用户分类:    |    来源: 转贴

评论(1) | 阅读(257)
发表于:2008-2-28 17:46:37
标签:电平转换  

0

电平转换方案

 

1. 常用的电平转换方案

(1) 晶体管+上拉电阻法
    就是一个双极型三极管或 MOSFET,C/D极接一个上拉电阻到正电源,输入电平很灵活,输出电平大致就是正电源电平。

(2) OC/OD 器件+上拉电阻法
    跟 1) 类似。适用于器件输出刚好为 OC/OD 的场合。

(3) 74xHCT系列芯片升压 (3.3V→5V)
    凡是输入与 5V TTL 电平兼容的 5V CMOS 器件都可以用作 3.3V→5V 电平转换。
    ——这是由于 3.3V CMOS 的电平刚好和5V TTL电平兼容(巧合),而 CMOS 的输出电平总是接近电源电平的。
    廉价的选择如 74xHCT(HCT/AHCT/VHCT/AHCT1G/VHCT1G/...) 系列 (那个字母 T 就表示 TTL 兼容)。

(4) 超限输入降压法 (5V→3.3V, 3.3V→1.8V, ...)
    凡是允许输入电平超过电源的逻辑器件,都可以用作降低电平。
    这里的"超限"是指超过电源,许多较古老的器件都不允许输入电压超过电源,但越来越多的新器件取消了这个限制 (改变了输入级保护电路)。
    例如,74AHC/VHC 系列芯片,其 datasheets 明确注明"输入电压范围为0~5.5V",如果采用 3.3V 供电,就可以实现 5V→3.3V 电平转换。 

(5) 专用电平转换芯片
    最著名的就是 164245,不仅可以用作升压/降压,而且允许两边电源不同步。这是最通用的电平转换方案,但是也是很昂贵的 (俺前不久买还是¥45/片,虽是零售,也贵的吓人),因此若非必要,最好用前两个方案。

(6) 电阻分压法
    最简单的降低电平的方法。5V电平,经1.6k+3.3k电阻分压,就是3.3V。

(7) 限流电阻法
    如果嫌上面的两个电阻太多,有时还可以只串联一个限流电阻。某些芯片虽然原则上不允许输入电平超过电源,但只要串联一个限流电阻,保证输入保护电流不超过极限(如 74HC 系列为 20mA),仍然是安全的。

(8) 无为而无不为法
    只要掌握了电平兼容的规律。某些场合,根本就不需要特别的转换。例如,电路中用到了某种 5V 逻辑器件,其输入是 3.3V 电平,只要在选择器件时选择输入为 TTL 兼容的,就不需要任何转换,这相当于隐含适用了方法3)。

(9) 比较器法
    算是凑数,有人提出用这个而已,还有什么运放法就太恶搞了。

2. 电平转换的"五要素"

(1) 电平兼容
    解决电平转换问题,最根本的就是要解决逻辑器件接口的电平兼容问题。而电平兼容原则就两条:
    VOH > VIH
    VOL < VIL
    再简单不过了!当然,考虑抗干扰能力,还必须有一定的噪声容限:
    |VOH-VIH| > VN+
    |VOL-VIL| > VN-
    其中,VN+和VN-表示正负噪声容限。
    只要掌握这个原则,熟悉各类器件的输入输出特性,可以很自然地找到合理方案,如前面的方案(3)(4)都是正确利用器件输入特性的例子。

(2) 电源次序
    多电源系统必须注意的问题。某些器件不允许输入电平超过电源,如果没有电源时就加上输入,很可能损坏芯片。这种场合性能最好的办法可能就是方案(5)——164245。如果速度允许,方案(1)(7)也可以考虑。

(3) 速度/频率
    某些转换方式影响工作速度,所以必须注意。像方案(1)(2)(6)(7),由于电阻的存在,通过电阻给负载电容充电,必然会影响信号跳沿速度。为了提高速度,就必须减小电阻,这又会造成功耗上升。这种场合方案(3)(4)是比较理想的。

(4) 输出驱动能力
    如果需要一定的电流驱动能力,方案(1)(2)(6)(7)就都成问题了。这一条跟上一条其实是一致的,因为速度问题的关键就是对负载电容的充电能力。
 
(5) 路数
    某些方案元器件较多,或者布线不方便,路数多了就成问题了。例如总线地址和数据的转换,显然应该用方案(3)(4),采用总线缓冲器芯片(245,541,16245...),或者用方案(5)。

(6) 成本&供货
    前面说的164245就存在这个问题。"五要素"冒出第6个,因为这是非技术因素,而且太根本了,以至于可以忽略。

点击此处查看原文 >>

系统分类: 嵌入式   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(258)
发表于:2008-2-28 17:40:46
标签:软件基础  

0

字节对齐

字节对齐

一、概念
   对齐跟数据在内存中的位置有关。如果一个变量的内存地址正好位于它长度的整数倍,他就被称做自然对齐。比如在32位cpu下,假设一个整型变量的地址为0x00000004,那它就是自然对齐的。
二、为什么要字节对齐
   需要字节对齐的根本原因在于CPU访问数据的效率问题。假设上面整型变量的地址不是自然对齐,比如为0x00000002,则CPU如果取它的值的话需要访问两次内存,第一次取从0x00000002-0x00000003的一个short,第二次取从0x00000004-0x00000005的一个 short然后组合得到所要的数据,如果变量在0x00000003地址上的话则要访问三次内存,第一次为char,第二次为short,第三次为 char,然后组合得到整型数据。而如果变量在自然对齐位置上,则只要一次就可以取出数据。一些系统对对齐要求非常严格,比如sparc系统,如果取未对齐的数据会发生错误,举个例:
   

char ch[8];
char *p = &ch[1];
int i = *(int *)p;

运行时会报segment error,而在x86上就不会出现错误,只是效率下降。

三、正确处理字节对齐

对于标准数据类型,它的地址只要是它的长度的整数倍就行了,而非标准数据类型按下面的原则对齐:

  • 数组 :按照基本数据类型对齐,第一个对齐了后面的自然也就对齐了。
  • 联合 :按其包含的长度最大的数据类型对齐。
  • 结构体: 结构体中每个数据类型都要对齐。

比如有如下一个结构体:

struct stu{
    char sex;
    int length;
    char name[10];
};
struct stu my_stu;

由于在x86下,GCC默认按4字节对齐,它会在sex后面跟name后面分别填充三个和两个字节使length和整个结构体对齐。于是我们sizeof(my_stu)会得到长度为20,而不是15.

四、__attribute__选项

我们可以按照自己设定的对齐大小来编译程序,GNU使用__attribute__选项来设置,比如我们想让刚才的结构按一字节对齐,我们可以这样定义结构体

struct stu{
     char sex;
    int length;
     char name[10];
}__attribute__ ((aligned (1)));

struct stu my_stu;

则sizeof(my_stu)可以得到大小为15。

上面的定义等同于

struct stu{
     char sex;
    int length;
     char name[10];
}__attribute__ ((packed));
struct stu my_stu;

__attribute__((packed))得变量或者结构体成员使用最小的对齐方式,即对变量是一字节对齐,对域(field)是位对齐.

五、什么时候需要设置对齐

    在设计不同CPU下的通信协议时,或者编写硬件驱动程序时寄存器的结构这两个地方都需要按一字节对齐。即使看起来本来就自然对齐的也要使其对齐,以免不同的编译器生成的代码不一样.

现在回到我们关心的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、操作系统、编译器及编译时的对齐选项,而你的程序可能需要运行在多种平台上,你的源代码可能要被不同的人用不同的编译器编译(试想你为别人提供一个开放源码的库),那么除非绝对必需,否则你的程序永远也不要依赖这些诡异的内存布局。顺便说一下,如果一个程序中的两个模块是用不同的对齐选项分别编译的,那么它很可能会产生一些非常微妙的错误。如果你的程序确实有很难理解的行为,不防仔细检查一下各个模块的编译选项。

点击此处查看原文 >>

系统分类: 软件开发   |    用户分类:    |    来源: 无分类

评论(0) | 阅读(274)
发表于:2008-1-8 15:47:08
标签:内核  移植  

0

编译移植内核

 

第二章编译移植内核

因为三星公司的 smdk2410 开发板使用的是 2.4.18 的内核,所以目前国内有相当多的客户都很熟悉 2.4 的使用和配置,我们不再对这个内核作介绍了。我们在这一章中将主要讲述最新的 linux2.6.14 内核的移植过程。由于 2410 已经成为 linux2.6 的标准支持平台,所以移植起来相对并不是很复杂。

第一节在 hfrk2410 开发板上运行 linux2.6

一. 准备必要的文件

       我们首先去官方网站下载最新的 llinux 内核

     http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.14.tar.bz2

因为 linux2.6.14 内核需要更新版本的编译器,所以我们需要下载交叉编译器

  ftp://ftp.handhelds.org/projects/toolchain/arm-linux-gcc-3.4.1.tar.bz2

注:这个编译器已经包含在光盘的 \DISK4\linux 相关 \linuxtool 目录下面。

二. 安装文件

       我们把 gcc 安装在 /usr/local/arm/3.4.1 目录下,安装方法和安装 gcc2.95.3 gcc3.3.2 是相同的,在此我们不再描述了

接下来需要解压 linux 内核,输入命令:

[root · localhost hfrk]# tar jxvf linux-2.6.14.tar.bz2

内核被解压到 linux-2.6.14 目录下。

三. 修改 makefile 文件

       内核的编译是根据 makefile 文件的指示进行的, Makefile 文件来组织内核的各模块之间的关系,记录了各个模块之间的相互联系和依赖关系。

       我们首先修改 linux-2.6.14 的根目录下的 makfile 文件,我们须改的主要内容是目标代码的类型和为编译内核指定一个编译器。

   我们注释掉以下内容:

    #ARCH   ?= $(SUBARCH)

       #CROSS_COMPILE      ?=

       增加如下内容:

       ARCH     : = arm

       CROSS_COMPILE =/usr/local/arm/3.4.1/bin/arm-linux-

四. 修改相关的文件。

1.        修改 arch\arm\mach-s3c2410\devs.c 文件

       增加头文件定义

              /***********add here***********/

              #include  <linux/mtd/partitions.h>

              #include  <asm/arch/nand.h>

              #include  <linux/mtd/nand.h>

               /**************end add********/

 

 

 

 

 

              增加 nand flash 分区信息

              /***********add here***********/

              static struct mtd_partition partition_info[] ={

              {

              name: "loader",

              size: 0x00020000,

              offset: 0,

              }, {

              name: "param",

              size: 0x00010000,

              offset: 0x00020000,

              }, {

              name: "kernel",

              size: 0x001c0000,

              offset: 0x00030000,

              }, {

              name: "root",

              size: 0x00200000,

              offset: 0x00200000,

              mask_flags: MTD_WRITEABLE,

              }, {

              name: "user",

              size: 0x03af8000,

              offset: 0x00400000,

              }

              };

 

              struct s3c2410_nand_set nandset ={

              nr_partitions: 5 ,

              partitions: partition_info ,

              };

 

              struct s3c2410_platform_nand superlpplatform={

              tacls:0,

              twrph0:30,

              twrph1:0,

              sets: &nandset,

              nr_sets: 1,

              };

              /**************end add********/

 

              struct platform_device s3c_device_nand = {

              .name               = "s3c2410-nand",

              .id             = -1,

              .num_resources       = ARRAY_SIZE(s3c_nand_resource),

              .resource  = s3c_nand_resource,

 

              /***********add here****************/

              .dev = {

              .platform_data = &superlpplatform

              }

              /**************end here************/

              };

2. 修改 arch\arm\mach-s3c2410\mach-smdk2410.c 文件

              Startic struct platform_device *smdk2410_devices[] __initdata={

                     &s3c_device_usb,

                     &s3c_device_lcd;

                     &s3c_device_wdt,

                     &s3c_device_i2c;

                     &s3c_device_iis,

                     &s3c_device_nand, /*add here*/

              };

五. 我们做完以上修改以后,内核编译以后就可以在 hfrk2410 开发板上运行了。

       打开终端窗口,切换到 linux-2.6.14 目录下,输入命令:

[root · localhost linux-2.6.14]# mak smdk2410_defconfig

[root · localhost linux-2.6.14]# mak

等编译完成以后,会生成镜像文件 arch/arm/boot/zImage ,把这个文件下载到开发板上,就会看到 linux2.6 的内核启动信息,我们迈出了 linux2.6 内核移植的第一步!

点击此处查看原文 >>

系统分类: 嵌入式   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(489)
发表于:2008-1-8 14:10:28
标签:linux  网卡  驱动  移植  

2

linux2.6下dm9000网卡驱动移植


第一步:在arm/arm/mach-s3c2410/devs.c 文件中添加如下代码

//-----------------------------------------------------------      

static struct resource s3c_dm9000_resource[] = {

        [0] = {

          .start = 0x08000000 + 0x300,

          .end   = 0x08000000 + 0x300 + 0x03,

          .flags = IORESOURCE_MEM

},

        [1] = {

          .start = 0x08000000 + 0x300 + 0x04,

          .end   = 0x08000000 + 0x300 + 0x04 + 0x3,  //   0x3f

          .flags = IORESOURCE_MEM

},

        [2] = {

          .start = IRQ_EINT0,

          .end   = IRQ_EINT0,

          .flags = IORESOURCE_IRQ

}

};

static struct dm9000_plat_data s3c_device_dm9000_platdata = {

        .flags= DM9000_PLATF_16BITONLY

};

      struct platform_device s3c_device_dm9000 = {

        .name= "dm9000",

        .id= -1,

        .num_resources= ARRAY_SIZE(s3c_dm9000_resource),

        .resource= s3c_dm9000_resource,

        .dev= {

          .platform_data = &s3c_device_dm9000_platdata,

}

};

EXPORT_SYMBOL(s3c_device_dm9000);      

//-----------------------------------------------------

  第二步:在 arm/arm/mach-s3c2410/devs.h 文件中 添加如下一行

  extern struct platform_device s3c_device_dm9000;    //for dm9000   --------hainanyunyu --广州大学

//----------------------------------------------------------------

第三步:在  arm/arm/mach-s3c2410/mach-smdk2410.c  

文件中的*smdk2410_devices[] __initdata

添加&s3c_device_dm9000,//for dm9000   --------hainanyunyu --广州大学

如下所示:

static struct platform_device *smdk2410_devices[] __initdata = {

&s3c_device_usb,

&s3c_device_lcd,        

      &s3c_device_wdt,    

&s3c_device_i2c,

&s3c_device_iis,

      &s3c_device_dm9000,//for dm9000   --------hainanyunyu --广州大学

};

//----------------------------------------------------------------

第四步:在内核自带的dm9000网卡驱动源码driver/net/dm9000.c中添加下面两行 定义

#define INTMOD          (0x4A000004)

     static void *intmod;

    在driver/net/dm9000.c  的

      static int dm9000_probe(struct device *dev)  函数中添加下面两行:

     

      intmod="ioremap"_nocache(INTMOD,0x0000004);

      writel(0x0,intmod);

     

//-----------------------------------------------------------------

点击此处查看原文 >>

系统分类: 嵌入式   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(943)
发表于:2007-10-21 14:12:24
标签:优秀  工程师  

0

如何成为一名优秀的工程师

“工程师是科学家;工程师是艺术家;工程师也是思想家。”一位伟大的工程师曾经提出过这样的一段感言。不错,工程师是利用自然科学来创造工程的人。工程既是物质的也是思想上的。许多不朽的工程,伟大的发明以及出神入化的技术方案,许多人往往只看到了他们的瑰丽,而作为工程师则更应该看到设计的灵魂。因此我们应该深入的理解“工程师也是艺术家和思想家”。工程设计的本身就是一种艺术,也是工程师思想的结晶。一部精密的机械设备,一个高效而又健壮的程序,一个复杂而又无懈可击的电路,这些都反映着一些杰出工程师的思想和灵魂,有时你甚至会认为他们的生命已经融入到设计中。  

     成为一个杰出工程师最重要的因素就是“热爱自己的职业”。毕竟兴趣是最好的老师,许多优秀的电子工程师都是从小作为电子爱好者的。爱好不仅要体现在行动中更要深入内心甚至深入骨髓。有许多人问:“每天应该花多长时间在学习中和工作中。”可以肯定一份耕耘就会换来一份收获,但作为工程师和科学家想取得成功并不是比赛谁花的时间最多,而是看谁付出了更多的“思考”。不要以为一个学生坐在自习教室里看了多少小时的书就是“勤奋”,也可能比呆在寝室里的学生还要“懒惰”。也就是说“勤奋”是大脑的勤奋,而不是身体和和形式上的勤奋。我学电子也差不多有15年了,也发现了很多问题。一次别人问我你每天花多长时间来工作。我回答他:“每天除了吃饭睡觉几乎都在思考。”不夸张的说我的很多工程构想都是在梦境中诞生的。每天早起床后刷牙的时候、上班的路上、吃饭的时候甚至和别人谈话的空闲瞬间都有可能诞生灵感。当然热爱工程师职业的前提是一定要能领略到工程和自然科学中的美感。一个优秀的工程师同时也是一个热爱科学的人,从科学的常识到科学的精神都会渗透到他的生活中。一次我看到一位教研室里的老师安排答辩的顺序,尽管这位老师在机电领域写了很多的书也在所谓“理论领域”有很多建树,单从他安排这样一个简单的顺序来看,他并不是个理论很高的人。因为在我看来他的工作方法是效率极低的。换句话说就是在他的生活中没有科学的精神可言。  

     一个工程师和科学家在生活中也是工程师和科学家。这个问题引出后我们要提到的是培养自己的思维品质。包括思维的习惯,深度和广度,以及思维方式和思维素材的选取。成为一个工程师确实有很多品质是天生的和决定性的,学校的培养和自己的努力也只是一些辅助措施。一个人曾经问我一个关于感性负载的问题,其实我心里很清楚他并不理解这里面最基本的物理概念,首先对电感的认识就不是用语言和数学公式能解释得了的。所以物理学和数学的基础是对工程师有很高要求的,这里所提到的物理学和数学是指一种最基本的认识而不是停留于表面的文字和公式。我可以推断这个人不太适合作工程师,其实他提出的问题都真真切切的存在于生活中,抬头看看日光灯的启动,或者当你看到电源插头的放电瞬间。可这每一个瞬间都被示为理所应当的话就错了。那样当牛