我是一个新手,试图编写一个串行驱动程序(基于PCI),我不想使用container_of(),因为缺少向下的compatibility.The内核版本,我可能会编译模块< 2.6.x,所以我想使它与大多数新旧版本兼容。
我想访问串行卡driver.the结构的结构成员是一个自定义的结构成员,例如包含原子变量-- use_count及其相关操作-- atomic_inc(&serial_card->use_count).I不想使用container_of()函数来访问它们,这将给我包含的结构-- container_of() function.If有什么可替代的地方,我没有错。Allesandro描述的文本LINux设备驱动程序在第6章174号页上描述了一种方法:高级Char驱动程序操作。但是我仍然对如何分配像struct scull_dev *dev = &scull_s_device这样的东西很感兴趣。如果结构本身包含一个类型为struct pc_device *dev的变量,则上面的语句填充一个类似的变量,并分配给dev,
在我的例子中,我声明了一个结构和相关功能,如下所示
struct serial_card
{
unsigned int id; // to identify the each card
//atomic_t use_count; // variable used to check whether the device is already opened or not
wait_queue_head_t rx_queue[64]; // queue in which the process are stored
unsigned int data_ready[64]; // queue in which the process is ready
unsigned int rx_chan; // used by interrupt handler
unsigned int base, len; // holds physical base address , holds the total area ( for each card )
unsigned int *base; // holds virtual address
/*struct cdev cdev; // kernel uses this structure to represent the EACH char device
not using the new method to represent char devices in kernel instead using the old method of register_chrdev();*/
struct pci_dev *device; // pci_dev structure for EACH device.
//struct semaphore sem; //Semaphore needed to handle the co-ordination of processes,use incase need arises
};
static struct serial_card *serial_cards; // pointer to array of structures [ depending on number of cards ],NO_OF_CARDS #defined in header file
static int serialcard_open(struct inode *inode,struct file *filep)
{
//getting the structure details of type struct serialcard,using the pointer inode->i_cdev and field type cdev
//struct serial_card *serial_cards = container_of(inode->i_cdev, struct serial_card, cdev);
// read the current value of use_count
static int Device_Open = 0;
if ( Device_Open ) //Device_Open is static varibale used here for checking the no of times a device is opened
{
printk("cPCIserial: Open attempt rejected\n");
return -EBUSY;
}
Device_Open++;
// using the card so increment use_count
//atomic_inc(&serial_cards->use_count);
//filep->private_data = serial_cards;
return 0;
}第174-175页的完整说明如下:
单开式器件
提供访问控制的蛮力方式是一次只允许一个进程打开一个设备(单一的开放)。最好避免这种技术,因为它抑制了用户的独创性。用户可能希望在同一设备上运行不同的进程,一种是读取状态信息,另一种是写入数据。在某些情况下,只要用户能够同时访问设备,就可以通过shell脚本运行一些简单的程序来完成大量工作。换句话说,实现单一开放行为等于创建策略,这可能会妨碍用户想要做的事情。只允许一个进程打开设备具有不受欢迎的属性,但它也是设备驱动程序实现的最简单的访问控制,因此如下所示。源代码是从一个名为scullsingle的设备中提取出来的。
scullsingle设备维护一个名为scull_s_available的scull_s_available变量;该变量被初始化为值为1,表明该设备确实可用。打开的调用减少并测试scull_s_available,如果其他人已经打开设备,则拒绝访问:
static atomic_t scull_s_available = ATOMIC_INIT(1);
static int scull_s_open(struct inode *inode, struct file *filp)
{
struct scull_dev *dev = &scull_s_device; /* device information */
if (! atomic_dec_and_test (&scull_s_available)) {
atomic_inc(&scull_s_available);
return -EBUSY; /* already open */
}
/* then, everything else is copied from the bare scull device */
if ( (filp->f_flags & O_ACCMODE) = = O_WRONLY) {
scull_trim(dev);
filp->private_data = dev;
return 0; /* success */
}另一方面,释放调用标志着设备不再繁忙:
static int scull_s_release(struct inode *inode, struct file *filp)
{
atomic_inc(&scull_s_available); /* release the device */
return 0;
}通常,我们建议您将打开标志scull_s_available放在device structure (Scull_Dev here)中,因为从概念上讲,它属于设备。然而,scull驱动程序使用独立的变量来保存标志,这样它就可以使用与裸scull设备相同的设备结构和方法,并尽量减少代码重复。
请告诉我有什么别的办法吗?
谢谢和问候
发布于 2011-03-29 12:35:44
也许我错过了重点,但是"cotainer_of“不是一个函数,而是一个宏。如果您有移植方面的问题,如果系统标头没有实现,您可以通过自己的服务器安全地定义它。这里是一个基本的实现:
#ifndef container_of
#define container_of(ptr, type, member) \
((type *) \
( ((char *)(ptr)) \
- ((char *)(&((type*)0)->member)) ))
#endif或者,下面是最近linux头中的实现--更准确地说:
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr);
(type *)( (char *)__mptr - offsetof(type,member) );})发布于 2011-12-16 12:08:29
在该代码中,容器用于轻松地存储和检索正确的dev结构。在读和写函数中也可以检索到正确的结构,而无需访问private_data。我不知道您为什么不想使用私有->数据和容器,但是您总是可以从struct文件指针中检索您的次要数字。
int minor=MINOR(filp->f_dentry_d_inode->i__rdev);然后使用以下内容访问多个设备向量
struct scull_dev* dev = &scull_devices[minor]:并利用它。
发布于 2011-04-16 13:12:07
您需要使用filp->私有数据来存储在读/写中也使用的“每次打开”信息。您需要决定存储什么,以确保正确的信息是可用的。
也许你想要两种结构。一个“设备结构”和一个“开放结构”。开放结构可以在“开放”中动态分配,并存储在private_data中。在释放的时候,它会被释放。它应该有成员,这样您就可以在读/写中使用它们来访问所需的数据。
设备结构将按“卡”排列。在您的驱动程序init中,您可能希望循环卡片的数量,并为每个卡创建一个新的设备结构(serial_card)。您可以让它们成为一个静态数组,或者动态分配,这并不重要。我也会把小数字存储在结构里。小数是由你选择的,所以从1开始,再通过#卡片。如果需要,可以为系统级接口保留"0“,也可以只从0开始。
在open中,您将得到用户打开的次要号码。检查您的serial_card列表,寻找匹配。如果你找不到它,错误就会被打开。否则,您就有了您的信息,可以使用它分配一个“开放结构”,填充它,并将其存储在filp->private_data中。
https://stackoverflow.com/questions/5469255
复制相似问题