LDD3 scull示例中的cdev文件操作初始化

时间:2017-09-26 19:02:55

标签: linux drivers

了解Linux中的设备驱动程序。在线阅读Linux设备驱动程序。本书讨论了以下代码

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main()
    {
        // create the records
        TestRecords testRecord1 = new TestRecords(){Id = 1, ResourceGroup = "SIP", ServerName = "win1234", CircuitId = 0, ChannelId = 1};
        TestRecords testRecord2 = new TestRecords(){Id = 2, ResourceGroup = "SIP", ServerName = "win1234", CircuitId = 0, ChannelId = 2};
        TestRecords testRecord3 = new TestRecords(){Id = 3, ResourceGroup = "TDM", ServerName = "win5678", CircuitId = 0, ChannelId = 35};
        TestRecords testRecord4 = new TestRecords(){Id = 4, ResourceGroup = "TDM", ServerName = "win5678", CircuitId = 0, ChannelId = 36};
        TestRecords testRecord5 = new TestRecords(){Id = 5, ResourceGroup = "SIP", ServerName = "win5678", CircuitId = 4, ChannelId = 47};
        TestRecords testRecord6 = new TestRecords(){Id = 6, ResourceGroup = "TDM", ServerName = "win1234", CircuitId = 8, ChannelId = 56};

        // create an empty list of TestRecords to hold the records above
        List<TestRecords> listTestRecords = new List<TestRecords>();

        // add records to list
        listTestRecords.Add(testRecord1);
        listTestRecords.Add(testRecord2);
        listTestRecords.Add(testRecord3);
        listTestRecords.Add(testRecord4);
        listTestRecords.Add(testRecord5);
        listTestRecords.Add(testRecord6);

        // group the records by ServerName
        var resultGrouped = listTestRecords.GroupBy(x => new{x.ServerName, x.ResourceGroup}).ToList();

        // select the items you need based off of the groupings
        var result = resultGrouped.Select(x => new{Server = x.Key.ServerName, ResourceGroup = x.Key.ResourceGroup, CountChannel = x.Count()}).ToList();

        foreach(var item in result){
            Console.WriteLine(item.Server + " " + item.ResourceGroup + " " + item.CountChannel);
        }

        // Result:
        //win1234 SIP 2
        //win5678 TDM 2
        //win5678 SIP 1
       // win1234 TDM 1
    }
}

public class TestRecords
{
    public int Id {get;set;}
    public string ResourceGroup {get;set;}
    public string ServerName {get;set;}
    public int CircuitId {get;set;} 
    public int ChannelId {get;set;}
}

不要static void scull_setup_cdev(struct scull_dev *dev, int index) { int err, devno = MKDEV(scull_major, scull_minor + index); cdev_init(&dev->cdev, &scull_fops); dev->cdev.owner = THIS_MODULE; dev->cdev.ops = &scull_fops; err = cdev_add (&dev->cdev, devno, 1); /* Fail gracefully if need be */ if (err) printk(KERN_NOTICE "Error %d adding scull%d", err, index); } cdev_init(&dev->cdev, &scull_fops)做同样的事情吗?

1 个答案:

答案 0 :(得分:0)

严格来说,它们不会做同样的事情,因为 cdev_init(&dev->cdev, &scull_fops) 不仅仅是将 scull_fopscdev 实例相关联。但是,正如您通过查看 kernel source code 已经注意到的那样,传递给 cdev_initcdevfile_operations 的两个结构确实与它相关联。这就是为什么 dev->cdev.ops = &scull_fops 实际上是多余的。

但是,如果您在运行时使用 cdev_alloccdev 分配内存,那么您必须手动将 file_operations 实例与其关联(例如,通过多余的线):

struct cdev *cdev_ptr = cdev_alloc();

if (cdev_ptr != NULL) 
{
  cdev_ptr->ops = &scull_fops; 
}
else 
{
  /* cdev_alloc() failed */ 
}

我猜这就是本书示例代码中出现冗余行背后的原因。