2015年(109)
分类: LINUX
2015-01-23 16:35:23
原文地址:Linux驱动的Ioctrl函数和指针参数 作者:myleeming
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就是起到一个标志的作用,让后面的程序可以根据这个标志知道这个指针的状态。