首先,我定义了一个字符设备结构体
struct globalmem_dev
{
struct cdev my_cdev; //字符设备之基础结构体
unsigned char mem[GLOBALMEM_SIZE];
struct semaphore sem;/
};
接下来我实例化了一个该设备的指针对象
struct globalmem_dev *pdev;
后来在open函数中我是这么来用的
int globalmem_open(struct inode *inode, struct file *filp)关于filp的产生和消亡参见《驱动详解》P92
{
struct globalmem_dev *pdev;
printk("\nFunction globalmem_open Invoked\n");
pdev = container_of(inode->i_cdev, struct globalmem_dev, my_cdev);
filp->private_da
if(down_trylock(&pdev->sem))//获得信号量, 真的我爱 container_of!!!! 我爱死container_of 了!!!
return -EBUSY;
return 0;
}
对以上用法的说明:
参数3是参数2这个结构体的一个成员的名字!而不是类型名!参数1是一个指针,它指向参数3这个成员
inode 中的i_cdev字段是一个指针,当我们成功insmod了一个设备驱动的时候,我们会通过mknod创建一个设备文件节点并和具体设备(驱动)想关联,这个设备文件节点所对应的就是struct inode结构体的一个实例,这个结构体有一个字段i_cdev,是个struct cdev类型的指针,它会指向设备结构体的my_cdev字段。至此你已经有了一个指向某个 globalmem_dev的my_cdev字段的一个指针(在调用open前pdev的内存分配假定已经完成)由此container_of可以帮你计算出指向该设备结构体的指针。
当一个设备驱动对应多个设备(子设备)时,你就知道container_of发挥的作用了!当你针对每一个设备调用 open时,因为每个设备对应的设备文件节点不一样,那么根据该节点的i_cdev字段所计算的设备结构体指针也不一样,你就可以找到特定节点所对应的设备结构体!而不至于对不同的子设备编写大同小异的各自的设备驱动。