Chinaunix首页 | 论坛 | 博客
  • 博客访问: 985000
  • 博文数量: 153
  • 博客积分: 4195
  • 博客等级: 上校
  • 技术积分: 2631
  • 用 户 组: 普通用户
  • 注册时间: 2009-06-22 11:32
文章存档

2012年(7)

2010年(35)

2009年(111)

分类: LINUX

2009-06-22 12:42:11

1.内核空间和内核空间打交道可以通过ioctl的最后一个参数来实现,

 

static int sep4020_psam_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)

{

       int reg_status;

       switch(cmd)

       {

              case COLDRESET:

                     {

                            *(volatile unsigned long*)SMC1_CTRL_V |= 0x00000001;                                                                //使能PSAM

                            psamdev->receive_len = 0;

                            reg_status = *(volatile unsigned long*)SMC1_STATUS_V;

                            while((reg_status & 0x48) != 0x48)                                                            //不为空,且不超时

                            {

                                   if ((reg_status & 0x40) != 0x40)                                                          //not empty,接收fifo不空

                                   {

                                          psamdev->receive_data[psamdev->receive_len] = *(volatile unsigned long*)SMC1_RX_V;            //读取接收FIFO中的数据

                                          psamdev->receive_len ++;                  

                                   }

                                   reg_status = *(volatile unsigned long*)SMC1_STATUS_V;

                            }

                            put_user(psamdev->receive_len,(char*)arg);

                            copy_to_user((void *)arg+1, psamdev->receive_data, psamdev->receive_len);                      break;

                     }

              case CHALLENGE:

                     {

                            Psam1Pro(challenge);

                            put_user(psamdev->receive_len,(char*)arg);

                            copy_to_user((void*)arg+1, psamdev->receive_data, psamdev->receive_len);

                            break;

                     }

              case MAINFILE:

                     {

                            Psam1Pro(mainfile);

                            put_user(psamdev->receive_len,(char*)arg);

                            copy_to_user((void *)arg+1, psamdev->receive_data, psamdev->receive_len);

                            break;

                     }

              default:

                     return -EINVAL;

       }

       return 0;

}

 

 

通过这种方式可以看到,函数中的最后参数unsigned long arg是传递进来的地址,

       put_user(psamdev->receive_len,(char*)arg);

上面这句话是指把这个地址的前两个字节放psamdev->receive_len这个数,注意(char*)是指将这个地址(指针)强制转换为char型的指针,不是说取地址的数,和*arg不同。

 

       copy_to_user((void *)arg+1, psamdev->receive_data, psamdev->receive_len);

arg+1是指下一个元素的地址,而不是下一个字节,比如(int *arg+1就是指第四个字节,(char*) arg +1是指从第二个字节,这里用(void*arg+1,(void*)来修饰的时候指可以指向任何类型,因此与上层应用使用的指针类型有关,我们在上层的测试程序中使用了char*

 

 

 

2.使用指针一定要初始化

1.为什么指针变量定义时一定要初始化?
:因为你首先要理解一点.内存空间不是你分配了才可以使用

只是你分配了之后使用才安全,为什么要进行对他初始化呢

因为,如果你没对他初始化,而引用这个指针并却其指向的内存进行修改

因为指针未被初始化,所以指针所指向的也是随机的,他是个野指针,如果你引用指针,并修改这个指针所指向的内容,而如果这个指针所指向的内容恰好是另外一个程序的数据的话,你将其进行修改了,就会导致另外一个程序可能不能正常运行了.所以使用前一定要进行初始化

 

2.关于NULL

没有说一定要初始化,不初始化同样也可以用。
初始化是为了避免野指针,指针不初始化时,如char *p,有些编译器会随便给它赋个地址,这个地址是不可知的,为了避免出现不必要的麻烦,才用NULL 初始化一下。

一般来说,NULL赋给指针用的最多是在指针的内存被delete 或者 free操作回收之后,它所值的地址已经不可用了,需要将它赋NULL。以便于后面的程序判断它的内存是否已经被回收。

说白了,NULL就是起到一个标志的作用,让后面的程序可以根据这个标志知道这个指针的状态。

阅读(3849) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~