免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2070 | 回复: 0
打印 上一主题 下一主题

Linux驱动的Ioctrl函数和指针参数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-06-22 12:42 |只看该作者 |倒序浏览

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就是起到一个标志的作用,让后面的程序可以根据这个标志知道这个指针的状态。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/99423/showart_1972928.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP