- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我是一个尝试编写串行驱动程序(基于 PCI)的新手,我不想使用 container_of()
因为缺乏向下兼容性。我可能会编译模块的内核版本将是 < 2.6.x,所以我想让它与大多数新旧版本兼容。
我想访问串行卡驱动程序的结构成员。该结构是一个包含原子变量的自定义结构,例如 - use_count 及其相关操作 - atomic_inc(&serial_card->use_count )
。我不想使用 container_of()
函数来访问它们,该函数会给我包含结构container_of() 函数是否有任何替代方法。如果我没记错的话,Allesandro Roubini 撰写的文本 LINux 设备驱动程序在第 174 页上描述了一种方法 |第 6 章:高级字符驱动程序操作。但我仍然对如何分配类似 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页的完整描述如下
Single-Open Devices
The brute-force way to provide access control is to permit a device to be opened by only one process at a time (single openness). This technique is best avoided because it inhibits user ingenuity. A user might want to run different processes on the same device, one reading status information while the other is writing data. In some cases, users can get a lot done by running a few simple programs through a shell script, as long as they can access the device concurrently. In other words, implementing a singleopen behavior amounts to creating policy, which may get in the way of what your users want to do. Allowing only a single process to open a device has undesirable properties, but it is also the easiest access control to implement for a device driver, so it’s shown here. The source code is extracted from a device called scullsingle.
scullsingle设备维护了一个atomic_t变量,叫做scull_s_available;那变量被初始化为值一,表明该设备确实可用。open 调用递减并测试 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 */
}
另一方面,release 调用将设备标记为不再忙碌:
static int scull_s_release(struct inode *inode, struct file *filp)
{
atomic_inc(&scull_s_available); /* release the device */
return 0;
}
通常,我们建议您将打开标志 scull_s_available 放在设备结构(此处为Scull_Dev)
因为,从概念上讲,它属于设备。这然而,scull 驱动程序使用独立变量来保存标志,因此它可以使用相同的设备结构和方法作为裸 scull 设备并最小化代码重复。
请让我知道任何替代方案
感谢和问候
最佳答案
也许我没有捕获要点,但是“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) );})
关于c - 替代 container_of(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5469255/
List.h 定义了一个名为 list_entry 的宏,它是 container_of() 函数的包装器。一个优雅的函数,看起来很精致: 考虑这段代码: tmp = list_entry(pos,(
这个问题在这里已经有了答案: Rationale behind the container_of macro in linux/list.h (1 个回答) 关闭 9 年前。 嗨,为什么 conta
谁能给我解释一下这两个宏? #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #define container_of(pt
我不确定我做错了什么,但现在是时候多加留意了。我使用 device_create() 制作一个设备,提供一些“额外数据”,如下所示: pDevice = device_create(ahcip
我试图通过编写一个小程序来理解 container_of 宏,但我没有得到预期的结果。我写的程序是: typedef struct node { int id1; int id2;
如果我有: struct my_container { int x; struct some_struct *ss; } 如果我有指针 ss,通过它我可以访问 some_struct
我尝试在 linux 内核中使用 container_of 宏。 我通过google得到的结果如下 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *
我是一个尝试编写串行驱动程序(基于 PCI)的新手,我不想使用 container_of() 因为缺乏向下兼容性。我可能会编译模块的内核版本将是 use_count )。我不想使用 container
例如在 Linux 驱动程序开发中,可以找到 container_of宏。本质上,它是 -> 的反向运算符,如果您获得指向成员的指针,则生成指向包含结构的指针。 除了 Greg Kroah 的博客之外
Linux内核(和其他地方)中常用的宏是container_of,其(基本上)定义如下: #define container_of(ptr, type, member) (((type) *)((ch
我知道宏是做什么的。 在许多内核级代码中,经常使用它来遍历链表。 我想找到其他有用的案例。 你什么时候使用 container_of 或 CONTAINING_RECORD宏? 什么时候宏非常有用?
我想知道如何使用 container_of 设置 epoll。我正在使用最新版本的 ubuntu 和 eclipse-cdt (gcc)。我的想法是抓取事件,然后抓取事件来自的容器。 如果我有这样的结
我正在编写一个访问 PCI 卡的简单字符驱动程序。它在新类的帮助下注册到 sysfs。现在我想以一种方便的方式访问设备的多个参数(即版本、状态、控制......)。我想向设备注册多个属性(通过 dev
我正在阅读 John Madieu 的 Linux Device Drivers Development,其中一段说 The container_of macro won't work for cha
我一直在使用我自己的 container_of 类型函数,它不依赖于 GNU 或 C99,(即,它适用于不同版本的 MSVC。) #include /* offsetof */ #include
宏定义为 #define container_of(ptr, type, member) ({ \ const typeof( ((type
我们有container_of的链表实现如下: #define container_of(ptr, type, member) ({ const typeof( ((type *)0)->memb
我想从头开始实现 container_of 宏/函数,就像 linux 内核中可用的那样,以从父结构的成员获取父结构的地址。 例如如果父结构是 struct parent{ int id; struc
在查看 Linux 内核的双向链接循环列表实现时,我发现了以下宏: #define container_of(ptr, type, member) ({ \ const typeo
我正在尝试访问内核链表,结构是 struct my_struct { struct my_hardware_context ahw; struct net_device *netdev; struct
我是一名优秀的程序员,十分优秀!