最新日志

发表于:2008-7-3 14:24:30
标签:无标签

0

2.6 内核驱动框架

Linux 2.6 和 2.4 的比较我不想废话,总体来说 2.6 功能更强,但是资源消耗更多。
  由于 2.6 内核在驱动框架,底层调用上和 2.4 内核有很多差别,所以本文主要是为程序员提供 2.4 到 2.6 迁移的指导。
  2.6 和 2.4 主要的不同在于
  ? 内核的 API 变化,增加了不少新功能(例如 mem pool )
  ? 提供 sysfs 用于描述设备树
  ? 驱动模块从 .o 变为 .ko
  移植 hello word 下面是一个最简单的 2.4 驱动:
  #define MODULE
  #include <linux/module.h>
  #include <linux/kernel.h>
  int init_module(void)
  {
  printk(KERN_INFO "Hello, world\n");
  return 0;
  }
  void cleanup_module(void)
  {
  printk(KERN_INFO "Goodbye cruel world\n");
  }
  2.6的hello world版本!
  #include < linux/module.h>
  #include < linux/config.h>
  #include < linux/init.h>
  MODULE_LICENSE("GPL");// 新,否则有 waring, 去掉了 #define MODULE, 自动定义
  static int hello_init(void)
  {
  printk(KERN_ALERT "Hello, world\n");
  return 0;
  }
  static void hello_exit(void)
  {
  printk(KERN_ALERT "Goodbye, cruel world\n");
  }
  module_init(hello_init);// 必须!!
  module_exit(hello_exit); // 必须!!
  注意,在 2.4 中 module_init 不是必须的,只要驱动的初始化函数以及析沟函数命名使用了缺省的 init_module 和 cleanup_module
  编译生成: 2.4
  gcc -D__KERNEL__ -DMODULE -I/usr/src/linux- 2.4.27 /include -O2 -c testmod.c
  2.6
  makefile 中要有 obj-m:= hello.o
  然后:
  make -C /usr/src/linux- 2.6.11 SUBDIRS=$PWD modules (当然简单的 make 也可以)
  哈哈够简单!!
  其他不同: 计数器: 以前 2.4 内核使用 MOD_INC_USE_COUNT 增加计数例如:
  void
  inc_mod(void)
  {
  MOD_INC_USE_COUNT;
  } /* end inc_mod */
  
  /************************************************************************
  * Calculator DEC
  ************************************************************************/
  void
  dec_mod(void)
  {
  MOD_DEC_USE_COUNT;
  } /* end dec_mod */
  现在这个也过时了 !!
  2.6 ,用户函数要加载模块,使用:
  int try_module_get(&module);
  函数卸载模块使用
  module_put()
  而驱动中不必显示定义 inc 和 dec
  没有 kdev_t 了 现在都流行用 dev_t 了 , 而且是 32 位的
  结构体初始化 老版本使用:
  static struct some_structure = {
  field1: value,
  field2: value
  };
  现在流行用:
  static struct some_structure = {
  .field1 = value,
  .field2 = value,
  ...
  };
  malloc.h 要用核态内存?用 <linux/slab.h> 好了,
  内存池内存管理变化不大,添加了memory pool*(#include<linux/mempool.h> )。(现在什么都是pool,内存 线程 ....)这是为块设备提供的,使用mempool最大的优点是分配内存不会错,也不会等待(怎么这个也和RTEMS学)。对于embed的设备还是有些用处的。标准调用方式:
  mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn, mempool_free_t *free_fn, void *pool_data);
  使用mempool的函数 :
  mempool_alloc_t / mempool_free_t
  mempool_alloc_slab / mempool_free_slab
  mempool_alloc / mempool_free
  mempool_resize
  
  结构体赋值 以前,驱动中结构体赋值使用:
  static struct some_structure = {
  field1: value,
  field2: value
  };
  
  现在要用:
  static struct some_structure = {
  .field1 = value,
  .field2 = value,
  ...
  };
  例如 :
  static struct file_operations yourdev_file_ops = {
  .open = yourdev_open,
  .read = yourdev_read_file,
  .write = yourdev_write_file,
  };
  
  min() , max() 不少程序员定义自己的 min 和 max 宏,大家也知道宏不安全, Linux 定义了 min 和 max 函数(注意不是模板函数,需要自己制定比较类型!)
  原型变化 call_usermodehelper()
  request_module()
  函数原型变化了,用到的赶快查 !!!
  Devfs 唉,还没怎么用,就过时了的技术,这就是 linux 。不是我们落伍,是世界变化快
  
  字符设备 2.6 中主从设备编号不再局限于原来的 8bit
  register_chrdev() 可以升级为:
  int register_chrdev_region(dev_t from, // 设备号 unsigned count, // 注册号 char *name); // 名称
  该函数的动态版本(不知道主设备号时使用)
  int alloc_chrdev_region(dev_t *dev, unsigned baseminor,
  unsigned count, char *name);
  
  新的 file_operations register_chrdev_region 没有使用 register_chrdev_region 参数,因为设备现在使用 struct cdev 来定义他在 <linux/cdev.h> 中定义。
  struct cdev {
  struct kobject kobj;
  struct module *owner;
  struct file_operations *ops;
  struct list_head list;
  dev_t dev;
  unsigned int count;
  };
  使用时首先需要分配空间: struct cdev *cdev_alloc(void);
  然后对其初始化:
  void cdev_init(struct cdev *cdev, struct file_operations *fops);
  cdev 使用 kobject_set_name 设置名称:例如:
  struct cdev *my_cdev = cdev_alloc(); kobject_set_name(&cdev->kobj, "my_cdev%d", devnum);
  此后就可以使用 int cdev_add(struct cdev *cdev, dev_t dev, unsigned count); 将 cdev 加入到系统中。
  删除 cdev 使用
  void cdev_del(struct cdev *cdev);
  对于没有使用 cdev_add 添加的 cdev 使用 kobject_put(&cdev->kobj); 删除 也就是使用: struct kobject *cdev_get(struct cdev *cdev); void cdev_put(struct cdev *cdev);
  太极链; struct inode -> i_cdev -> cdev
  这样就从 inode 链接到 cdev
  
  驱动体系: /dev 到 /sys
  /dev 也过时了,设备文件都跑到 /sys 里了!
  # cd /sys
  # ls
  block bus class devices firmware 

点击此处查看原文 >>

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

评论(0) | 阅读(20)
发表于:2008-7-2 14:37:25
标签:无标签

0

介绍linux驱动程序中ioctl的概念、意义和用法

     我这里说的ioctl函数是在驱动程序里的,因为我不知道还有没有别的场合用到了ioctl,
      所以就规定了我们讨论的范围。为什么要写篇文章呢,是因为我前一阵子被ioctl给搞混
      了,这几天才弄明白它,于是在这里清理一下头脑。 
      
      一、 什么是ioctl。 
      ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就
      是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的调用方法
      如下: 
      int ioctl(int fd, int cmd, …); 
      其中fd就是用户程序打开设备时使用open函数返回的文件标示符,cmd就是用户程序对设
      备的控制命令,至于后面的省略号,那是一些补充参数,一般最多一个,有或没有是和
      cmd的意义相关的。 
      ioctl函数是文件结构中的一个属性分量,就是说如果你的驱动程序提供了对ioctl的支
      持,用户就可以在用户程序中使用ioctl函数控制设备的I/O通道。 
      
      二、 ioctl的必要性 
      如果不用ioctl的话,也可以实现对设备I/O通道的控制,但那就是蛮拧了。例如,我们可
      以在驱动程序中实现write的时候检查一下是否有特殊约定的数据流通过,如果有的话,
      那么后面就跟着控制命令(一般在socket编程中常常这样做)。但是如果这样做的话,会
      导致代码分工不明,程序结构混乱,程序员自己也会头昏眼花的。 
      所以,我们就使用ioctl来实现控制的功能。要记住,用户程序所作的只是通过命令码告
      诉驱动程序它想做什么,至于怎么解释这些命令和怎么实现这些命令,这都是驱动程序要
      做的事情。 
      
      三、 ioctl如何实现 
      这是一个很麻烦的问题,我是能省则省。要说清楚它,没有四五千字是不行的,所以我这
      里是不可能把它说得非常清楚了,不过如果有读者对用户程序怎么和驱动程序联系起来感
      兴趣的话,可以看我前一阵子写的《write的奥秘》。读者只要把write换成ioctl,就知
      道用户程序的ioctl是怎么和驱动程序中的ioctl实现联系在一起的了。 
      我这里说一个大概思路,因为我觉得《Linux设备驱动程序》这本书已经说的非常清楚
      了,但是得化一些时间来看。 
      在驱动程序中实现的ioctl函数体内,实际上是有一个switch{case}结构,每一个case对
      应一个命令码,做出一些相应的操作。怎么实现这些操作,这是每一个程序员自己的事
      情,因为设备都是特定的,这里也没法说。关键在于怎么样组织命令码,因为在ioctl中
      命令码是唯一联系用户程序命令和驱动程序支持的途径。 
      命令码的组织是有一些讲究的,因为我们一定要做到命令和设备是一一对应的,这样才不
      会将正确的命令发给错误的设备,或者是把错误的命令发给正确的设备,或者是把错误的
      命令发给错误的设备。这些错误都会导致不可预料的事情发生,而当程序员发现了这些奇
      怪的事情的时候,再来调试程序查找错误,那将是非常困难的事情。 
      所以在Linux核心中是这样定义一个命令码的: 
      ____________________________________
      | 设备类型 | 序列号 | 方向 |数据尺寸|
      |----------|--------|------|--------|
      | 8 bit    |  8 bit |2 bit |8~14 bit|
      |----------|--------|------|--------|

      这样一来,一个命令就变成了一个整数形式的命令码。但是命令码非常的不直观,所以
      Linux Kernel中提供了一些宏,这些宏可根据便于理解的字符串生成命令码,或者是从
      命令码得到一些用户可以理解的字符串以标明这个命令对应的设备类型、设备序列号、数
      据传送方向和数据传输尺寸。
       
      这些宏我就不在这里解释了,具体的形式请读者察看Linux核心源代码中的和,文件里给
      除了这些宏完整的定义。这里我只多说一个地方,那就是"幻数"。 
      幻数是一个字母,数据长度也是8,所以就用一个特定的字母来标明设备类型,这和用一
      个数字是一样的,只是更加利于记忆和理解。就是这样,再没有更复杂的了。 
      更多的说了也没有,读者还是看一看源代码吧,推荐各位阅读《Linux 设备驱动程序》所
      带源代码中的short一例,因为它比较短小,功能比较简单,可以看明白ioctl的功能和细
      节。 

      四、 cmd参数如何得出 
      这里确实要说一说,cmd参数在用户程序端由一些宏根据设备类型、序列号、传送方向、
      数据尺寸等生成,这个整数通过系统调用传递到内核中的驱动程序,再由驱动程序使用解
      码宏从这个整数中得到设备的类型、序列号、传送方向、数据尺寸等信息,然后通过
      switch{case}结构进行相应的操作。 
      要透彻理解,只能是通过阅读源代码,我这篇文章实际上只是一个引子。Cmd参数的组织
      还是比较复杂的,我认为要搞熟它还是得花不少时间的,但是这是值得的,驱动程序中最
      难的是对中断的理解。 

      五、 小结 
      ioctl其实没有什么很难的东西需要理解,关键是理解cmd命令码是怎么在用户程序里生成
      并在驱动程序里解析的,程序员最主要的工作量在switch{case}结构中,因为对设备的
      I/O控制都是通过这一部分的代码实现的。 

      参考资料: 
      1.《Linux 设备驱动程序》,鲁宾尼著,中国电力出版社。 
      2.《write的奥秘》,coly,真情流露(202.204.7.235)->电脑技术->Linux技术。

点击此处查看原文 >>

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

评论(0) | 阅读(77)
发表于:2008-7-2 14:36:09
标签:结构体  

0

什么是结构体?


  简单的来说,结构体就是一个可以包含不同数据类型的一个结构,它是一种可以自己定义的数据类型,它的特点和数组主要有两点不同,首先结构体可以在一个结构中声明不同的数据类型,第二相同结构的结构体变量是可以相互赋值的,而数组是做不到的,因为数组是单一数据类型的数据集合,它本身不是数据类型(而结构体是),数组名称是常量指针,所以不可以做为左值进行运算,所以数组之间就不能通过数组名称相互复制了,即使数据类型和数组大小完全相同。

  定义结构体使用struct修饰符,例如:

struct test
{
     float a

     int b

};

  上面的代码就定义了一个名为test的结构体,它的数据类型就是test,它包含两个成员ab,成员a的数据类型为浮点型,成员b的数据类型为整型。

  由于结构体本身就是自定义的数据类型,定义结构体变量的方法和定义普通变量的方法一样。

test pn1;

  这样就定义了一test结构体数据类型的结构体变量pn1,结构体成员的访问通过点操作符进行,pn1.a=10 就对结构体变量pn1的成员a进行了赋值操作。

  注意:结构体声明的时候本身不占用任何内存空间,只有当你用你定义的结构体类型定义结构体变量的时候计算机才会分配内存。

  结构体,同样是可以定义指针的,那么结构体指针就叫做结构指针。

  结构指针通过->符号来访问成员,下面我们就以上所说的看一个完整的例子:

#include <iostream>   
#include <string>   
using namespace std; 
 
struct test//
定义一个名为test的结构体 

    int a;//
定义结构体成员
    int b;//
定义结构体成员
}; 
 
void main()     

    test pn1;//
定义结构体变量pn1 
    test pn2;//
定义结构体变量pn2 
 
    pn2.a=10;//
通过成员操作符.给结构体变量pn2中的成员a赋值 
    pn2.b=3;//
通过成员操作符.给结构体变量pn2中的成员b赋值 
 
    pn1=pn2;//
pn2中所有的成员值复制给具有相同结构的结构体变量pn1 
    cout<<pn1.a<<"|"<<pn1.b<<endl; 
    cout<<pn2.a<<"|"<<pn2.b<<endl; 
 
    test *point;//
定义结构指针 
 
    point=&pn2;//
指针指向结构体变量pn2的内存地址 
    cout<<pn2.a<<"|"<<pn2.b<<endl; 
    point->a=99;//
通过结构指针修改结构体变量pn2成员a的值 
    cout<<pn2.a<<"|"<<pn2.b<<endl; 
    cout<<point->a<<"|"<<point->b<<endl; 
    cin.get(); 
}

  总之,结构体可以描述数组不能够清晰描述的结构,它具有数组所不具备的一些功能特性。

 下面我们来看一下,结构体变量是如何作为函数参数进行传递的。

#include <iostream>   
#include <string>   
using namespace std; 
 
struct test 

    char name[10]; 
    float socre; 
}; 
 
void print_score(test pn)//
以结构变量进行传递 

    cout<<pn.name<<"|"<<pn.socre<<endl; 

 
void print_score(test *pn)//
一结构指针作为形参 

    cout<<pn->name<<"|"<<pn->socre<<endl; 

 
void main()     

    test a[2]=,}; 
    int num = sizeof(a)/sizeof(test); 
    for(int i=0;i<num;i++) 
    { 
        print_score(a[i]); 
    } 
    for(int i=0;i<num;i++) 
    { 
        print_score(&a[i]); 
    } 
    cin.get(); 
}

  void print_score(test *pn)的效率是要高过void print_score(test pn)的,因为直接内存操作避免了栈空间开辟结构变量空间需求,节省内存。

  下面我们再说一下,传递结构引用的例子。

  利用引用传递的好处很多,它的效率和指针相差无几,但引用的操作方式和值传递几乎一样,种种优势都说明善用引用可以做到程序的易读和易操作,它的优势尤其在结构和大的时候,避免传递结构变量很大的值,节省内存,提高效率。

 

 

#include <iostream>   
#include <string>   
using namespace std; 
 
struct test 

    char name[10]; 
    float socre; 
}; 
 
void print_score(test &pn)//
以结构变量进行传递 

    cout<<pn.name<<"|"<<pn.socre<<endl; 

 
void main()     

    test a[2]=,}; 
    int num = sizeof(a)/sizeof(test); 
    for(int i=0;i<num;i++) 
    { 
        print_score(a[i]); 
    } 
    cin.get(); 
}
 上面我们说明了易用引用对结构体进行操作的优势,下面我们重点对比两个例程,进一部分析关于效率的问题。

//-------------------------------------例程1--------------------------------- 
 
#include <iostream>   
#include <string>   
using namespace std; 
 
struct test 

    char name[10]; 
    float socre; 
}; 
 
void print_score(test &pn) 

    cout<<pn.name<<"|"<<pn.socre<<endl; 

 
test get_score() 

    test pn; 
    cin>>pn.name>>pn.socre; 
    return pn; 

void main() 

    test a[2]; 
    int num = sizeof(a)/sizeof(test); 
    for(int i=0;i<num;i++) 
    { 
        a[i]=get_score(); 
    } 
    cin.get(); 
    for(int i=0;i<num;i++) 
    { 
        print_score(a[i]); 
    } 
    cin.get(); 

 
//-------------------------------------
例程2---------------------------------  
  
#include <iostream>   
#include <string>   
using namespace std; 
 
struct test 

    char name[10]; 
    float socre; 
}; 
 
void print_score(test &pn) 

    cout<<pn.name<<"|"<<pn.socre<<endl; 

 
void get_score(test &pn) 

    cin>>pn.name>>pn.socre; 

void main() 

    test a[2]; 
    int num = sizeof(a)/sizeof(test); 
    for(int i=0;i<num;i++) 
    { 
        get_score(a[i]); 
    } 
    cin.get(); 
    for(int i=0;i<num;i++) 
    { 
        print_score(a[i]); 
    } 
    cin.get(); 
}

  例程2的效率要远高过例程1的原因主要有以下两处:


  第一:

  例程1中的

test get_score()
{
test pn;
cin>>pn.name>>pn.socre;
return pn;
}

  调用的时候在内部要在栈空间开辟一个名为pn的结构体变量,程序pn的时候又再次在栈内存空间内自动生成了一个临时结构体变量temp,在前面的教程中我们已经说过,它是一个copy,而例程2中的:

void get_score(test &pn)
{
cin>>pn.name>>pn.socre;
}

  却没有这一过程,不开辟任何新的内存空间,也没有任何临时变量的生成。

  第二:

  例程1mian()中,必须对返回的结构体变量进行一次结构体变量与结构体变量直接的相互赋值操作。

for(int i="0";i<num;i++)
{
a[i]=get_score();
}

  而例程2中由于是通过内存地址直接操作,所以完全没有这一过程,提高了效率。

for(int i="0";i<num;i++)
{
get_score(a[i]);
}

  函数也是可以返回结构体应用的,例子如下:

#include <iostream>   
#include <string>   
using namespace std; 
 
struct test 

    char name[10]; 
    float socre; 
}; 
 
test a; 
 
 
test &get_score(test &pn) 

    cin>>pn.name>>pn.socre; 
    return pn; 

 
void print_score(test &pn)   
{   
    cout<<pn.name<<"|"<<pn.socre<<endl;   
}   
 
void main() 

    test &sp=get_score(a); 
    cin.get(); 
    cout<<sp.name<<"|"<<sp.socre; 
    cin.get();  
}

  调用get_score(a);结束并返回的时候,函数内部没有临时变量的产生,返回直接吧全局结构变量a的内存地址赋予结构引用sp

  最后提一下指针的引用

  定义指针的引用方法如下:

void main() 

int a=0; 
int b=10; 
int *p1=&a; 
int *p2=&b; 
int *&pn=p1; 
cout <<pn<<"|"<<*pn<<endl; 
pn=p2; 
cout <<pn<<"|"<<*pn<<endl; 
cin.get(); 
}

  pn就是一个指向指针的引用,它也可以看做是指针别名,总之使用引用要特别注意它的特性,它的操作是和普通指针一样的,在函数中对全局指针的引用操作要十分小心,避免破坏全局指针!

 

点击此处查看原文 >>

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

评论(0) | 阅读(18)
发表于:2008-6-25 10:23:57
标签:FREEDOM  

0

美国没有户籍管理为什么不乱套

摘自http://laoxuetu.blog.sohu.com/90513622.html

 

点击看大图

 

美国没有户籍管理为什么不乱套

 

(摄于佛罗里达州坦帕)

      这次去美国,看到劳伦斯又搬家了。这是我认识他以来他的第五次搬家。

      我是1997年认识劳伦斯的, 11年来他搬了5次家,平均2年多点时间就搬一次家,真是够频的。

      美国人就是这样,随意搬家,不在乎搬家,甚至热爱搬家。

      美国人刚参加工作时,由于收入不高,一般是租住小房子;收入高点了,就换租大点的房子;有条件供房了,再搬到自己买的房子里;收入再增加了,把买的小房子卖掉再买大房子;再发达了,换到更好的社区更好的房子里去;到老了,房子不会留给子女的,卖掉,再搬到老人公寓里去颐养天年,去天堂以前把信用卡里的美元都花光,没准还透支呢。

      美国人换工作也比较频,到另一个城市另一个州去,甚至从西海岸到东海岸去工作,在美国人看来是很简单的事情。美国人的祖先最先从欧洲移民到北美时,就有一句著名的口号,“哪里有面包,哪里就是祖国。”现代美国人继承了这个精神,哪里生活好,哪里就是家园。美国有的企业招聘外地员工时,甚至给支付搬家费。

      美国人搬家的理由还多呢,哪个地方环境好哪个地方税收少哪个地方学校好哪个地方本族裔人口多哪个地方称心的餐馆多,都会成为搬家的理由。据说美国人平均一生要搬十几次家。

      美国人热爱生活,热爱家庭。人到了哪里,家就必须迁移到哪里绝对不可能两地生活,绝对不可以为了事业而不顾家庭的。房子可以换,家可以搬,就是夫妻不能分居,未成年的孩子不能分离。美国人绝对不理解中国民工一年只回一次家的境况,他们认为那样太不人道了。

      可以肯定,如果有哪个威权总统敢发一个命令剥夺了美国人的迁徙自由,把类似中国的户籍制度强塞给他们,美国人一定会弹劾他的,如果弹劾不成,一定会再打一次独立战争或解放战争。

      问题是,美国没有户籍制度,美国人没有户口,也没有派出所村委会居委会这样的管理机构,他们这样搬来搬去的,那社会不乱套了吗?政府怎么管理呀?

      我把这个问题提给劳伦斯。

      劳伦斯对“政府管理”这个概念很反感。他说,谁管理谁呀?政府不是管理公民的,是要为公民服务的,应当是公民管理政府。我每次搬家到一个新地方,都是政府或想进入政府的政客(竞选议员或政府官员的人)上门来请我,一个新到来的公民,去管理他们,而不是他们来管理我。

      说的也是。在美国,没有哪个政治家或官员敢认为自己是公民的领导、上级、管理者,也没有哪个公民会买有这种意识的人的帐,想领导人民管理人民的人绝对没有任何机会涉足政治领域,老老实实恭恭敬敬地为选民服务才有机会。

      美国公民每迁徙到一个新的地方,就自动成为了那里的居民,自动地拥有了该地的管理地方政府的权利――选举权和其他政治参与权利,自动的享受当地的社会福利待遇。不需要申请或批准,不需要办理什么户籍手续。你只要在那个地方居住,即使时租住的房子,当地政府也会主动找到你,请你行使权利。比如做选民登记,做陪审团候选资格登记等。选举时,候选人的竞选班子会主动向你寄送竞选资料,寻求你的支持和“管理”。

      问题是没有户籍制度,没有户口的转入转出,原居住地政府怎么知道你这个“管理者”走了,新居住地的政府又怎么知道有新“管理者”来了。特别是新政府怎么知道你住在那里,如何了解你的基本情况。你不去政府报到,政府怎么找到你呀。

      劳伦斯告诉我,美国的各级政府是从DMV(机动车辆处)那里获得公民信息的。在美国,几乎所有的公民都有驾驶执照,美国关于驾驶执照的规定是,驾驶人员每到一个地方超过15天,就必须到DMV登记,否则会被视为持无效证件驾驶。所以,每个公民搬家了,会到DMV登记变更住所的信息,这样,DMV就有了有驾照人员流入流出的详细信息,当地政府也由此得到了本地居民的流入流出情况。

      在美国,驾照就是身份证,乘坐国内飞机要出示驾照,住宾馆要出示驾照,凡是需要身份证明的地方都需要出示驾照。

      那么,不会开车没有驾照的人怎么办呢?比如一辈子都不开车的残疾人,或者新移民来的老人等。这一类人就办身份证。身份证也是到DMV去办。在机动车辆处办理身份证,而且身份证的样子与驾照是一样的,对身份证如此不重视,大概只有美国人这样。

      美国政府了解公民信息的另一个渠道是居民的社会保障记录。在美国的所有合法居民,都有一个社会保障卡,社会保障号码(也翻译为社会安全号码)是唯一的,是从生到死伴随每个人一生的。一个人就业、开工资、缴纳保险、缴税和获得所有的社会保障,都要依据这个号码,这是美国人的福利保障的依据,是命根子。美国人每到一个新地方,都要到社会保障机构办理住所变更手续,以便社会保障部门与自己的联系不中断,给自己的资料能寄到,有好事情不漏掉自己。

      美国人挺自私,绝不大公无私。他们对国家和政府的定位是十分功利主义的。他们绝没有建设一个伟大祖国的雄心壮志,也没有振兴美利坚民族的宏伟愿望,更没有为着后代的美好生活而牺牲今天自己的幸福的献身精神。所以他们从来不认为人民需要一个强有力的领导来支配他们带领他们走向未来。他们绝不会以缴税的名义把钱交给另一部分人随意支配。他们把政府看作是“一个人无法做的事情大家不得不凑份子请一些人来做的雇用者们”政府是他们雇来为全体公民服务的,为全体公民谋取最现实的利益的。政府就是大家凑钱为大家办事的。每个公民出钱了,凑份子了,不仅有权委托各级议会里的议员们代表自己对如何花钱进行审查、批准和监督,而且还必须从交给政府的钱中拿回一块,由政府以社会保障的形式回报给自己。公民交给政府的份子钱如何记录?公民靠什么领取回报?就是社会保障卡里的记录。

      所以,美国人的流动情况工作变动情况收入变化情况和缴税缴费情况等都被一清二楚地随时记录着的。无论你到了哪里。

      驾照和社会保障卡使得世界上人口流动量最大的国家的人口流动情况被随时清楚地掌握着。所以,社会不会失控。

      可能有人会说,掌握情况不等于有序。那么多人说搬家就搬家说流动就流动,社会秩序能不乱吗?大家都往大城市跑怎么办?都去经济发达地区怎么办?人口流动不控制不管理不可能不乱套。

      但事实上美国没有乱套,自由迁徙随意迁徙甚至是爱好迁徙的美国一点都没有乱套。其实,世界上有户籍管理制度的国家只有区区三个国家,绝大多数国家是可以自由迁徙的,绝大多数国家都没有乱套。

      为什么呢?因为自由。在自由的领域里,始终会有一只“看不见的手”在起着调节的作用,自由总会比行政控制更有效更合理更自如地调节着供需的平衡,保证着不乱套。

      大家都往大城市挤,那里的住房和物价就会提高,就业机会就会减少,准入的门槛就会越来越高。企业也会选择到新的成本低的地区去发展,如此就会把人流引到新的地区。

      再比如荒凉的地方没有人去,当地人自然就会想办法吸引人。美国的内华达州大多是沙漠,工业农业的资源都不行。穷则思变,于是这个州的法律允许办赌场,以赌为诱饵发展旅游业。这个州有两个著名的赌城,拉斯维加斯和里诺。其中拉斯维加斯是世界级的赌城。美国人在道德领域里非常现实,既然赌博是客观存在的,与其让美国人去摩纳哥的赌场送钱,还不如让全世界的赌徒来美国送钱。如此,荒凉的沙漠里建起了最热闹的都市,不仅赌博业旅游业发展了,拉斯维加斯还成了商业会展中心。

      由此可见,政治上经济上的自由是最有效的调节机制。保证不乱套的往往不是控制、管理和强制,而是自由,是老子的无为而治。从宏观的角度思考,如果把人看作是自然的一部分,政治上和经济上的自由主义本质上是自然主义,就是让自然规律起作用的主义,而不是由人类的空想臆想幻想设想理想来限制人类的自由。

      自由挺好。

点击此处查看原文 >>

系统分类: 自由话题   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(61)
发表于:2008-6-23 11:10:16
标签:无标签

0

手机电路的浪涌防护和TVS应用的电路实例

手机电路的浪涌防护和TVS应用的电路实例

 

 

.手机电路简介

 

现代数字移动电话的智能化越来越高,而其体积.重量则不断降低,使本已很复杂的手机设计又造成巨大压力,做为TVS的供应商我们应给予技术支持把最新.体积最小的.功能齐全的TVS组合芯片介绍给广大用户

 

数字移动电话的电路基本由射频/数字信号处理/终端接口/电源管理等部分组成,其中:

 

*射频电路包括:接收器.发送器.频率合成器和功放。

*数字信号处理包括:数字信息处理和信号控制器。

*终端接口包括:液晶显示/背光电路;键盘/键盘背光电路;SIM卡的CPU读卡电路;耳机/麦克风/振铃电路;数据接口;数字接口等。

*电源管理电路包括:用低压差线性稳压器{LDO}分别为功放/RF和模拟电路/DSP及其它数字电路/LCD供电等。

 

.”手机电路中需要进行浪涌冲击防护的部位有:

1.      SIM卡的CPU读卡电路;

2.      键盘电路;

3.      耳机.麦克风电路;

4.      数据接口;

5.      电源接口;

6.      数字接口{USB};

7.      彩屏LCD驱动接口;

8.      LCD背光电路。[LCD背光电路在制造时已经采取了TVS保护措施]

 

.手机的电磁兼容”{EMC}的试验和测试内容有:

1.      静电放电抗扰度测试;

2.      电磁辐射骚扰抗扰度测试;

3.      电快速瞬变脉冲群抗扰度测试;

4.      共模/差模浪涌冲击抗扰度测试;

5.      射频场感应的传导骚扰抗扰度测试;

6.      电压暂降和短时中断抗扰度测试。

 

EMC的测试和审核是保障受试产品不受电磁干扰或产生电磁干扰”,抑制静电放电[ESD].电快速瞬变脉冲群[EFT]和共模/差模浪涌冲击[SURGE]均需要使用TVS做防护。

*EMC测试:

[1].抗瞬态骚扰的性能判据

 

1).试验时,手机应建立并保持通信连接”;

2).试验后手机应能正常工作,不能发生用户可察觉的通信质量降低.控制功能丧失或存储数据丢失,并继续保持通信连接。

[2].试验

1.{ESD}静电放电抗扰度试验             

*对于接触放电应能通过±2KV±4KV的试验等级;

*对于空气放电应能通过±2KV. ±4KV±8KV的试验等级。

2.{EFT}电快速瞬变脉冲群抗扰度试验

*信号/通信/控制端口的试验电平为开路电压0.5KV;

*DC电源输入端口的试验电平为开路电压1KV;

*AC电源输入端口的试验电平为开路电压2KV

3.{Surge}浪涌[冲击]抗扰度试验

*通信端口的线对地,试验电压为开路电压0.5KV;

*AC电源端口的线对地,试验电压为开路电压1KV;

*AC电源端口的线对线,试验电压为开路0.5KV

 

#在手机的测试和审核时主要是测试手机每个端口对ESD骚扰的防护能力。

 

.瞬态电压抑制器{简称:TVS}的嵌位特性

 

瞬态电压抑制器,英文:TransientVoltageSuppressor简称:TVS

TVS的特性曲线中有关断电压”[Vwm].