正确的方法来初始化Linux驱动程序中的信号量

时间:2017-03-25 20:19:25

标签: c linux-kernel linux-device-driver semaphore

我写这个linux char驱动程序只是为了控制开放调用,

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/semaphore.h>
#include <linux/device.h>
#include <linux/cdev.h>

MODULE_LICENSE("GPL");
#define CLASS_NAME "myclass"
#define MINOR_NUM 0
#define MINOR_CNT 1
static struct class *myclass=NULL;
static struct device *mydevice=NULL;
static dev_t mycdevt;
static struct cdev *mycdev;
static struct semaphore *sem; 

static int myopen(struct inode *inod, struct file *fp)
{
    down(sem);
    printk(KERN_INFO "critical section\n");
    return 0;
}

static int myclose(struct inode *inod, struct file *fp )
{
    up(sem);
    printk(KERN_INFO "critical section freed\n");
    return 0;
}

static ssize_t myread(struct file *fp, char *buf, size_t len, loff_t *off)
{
    return 0;
}

static ssize_t mywrite(struct file *fp, char *buf, size_t len, loff_t *off)
{
    return 0;
}

static struct file_operations fops = 
{
    .open = myopen,
    .release = myclose,
    .read = myread,
    .write = mywrite,
};

static int __init myinit(void)
{
    int ret;

    ret = alloc_chrdev_region ( &mycdevt, MINOR_NUM, MINOR_CNT, "mycdevt");
    if(ret<0)
    {
        printk(KERN_INFO "chardev can't be allocated\n");
    //  goto label;//todo
    }

    mycdev = cdev_alloc();//instead of cdev_alloc, we can use cdev_init(&mycdev, &fops);
    if(mycdev == NULL)
    {
        printk(KERN_INFO"cdev_alloc failed\n");
    //  goto label;//todo
    }
    mycdev->ops = &fops;

    ret = cdev_add(mycdev, mycdevt, 1);
    if(ret < 0)
    {
        printk(KERN_INFO"cdev_add failed\n");
    //  goto label;//todo
    }

    myclass = class_create(THIS_MODULE, CLASS_NAME);
    if(myclass == NULL)
    {
        printk(KERN_INFO"class create failed\n");
    //  goto label;//todo
    }


    mydevice = device_create(myclass, NULL, mycdevt, NULL, "mydevice");
    if(mydevice == NULL)
    {
        printk(KERN_INFO"device create failed\n");
    //  goto label;//todo
    }

    sema_init(sem, 1);//here is the problem
    printk(KERN_INFO"myinit done\n");
    return 0;
}

static void __exit myexit(void)
{
    device_destroy(myclass, mycdevt);
    class_unregister(myclass);
    class_destroy(myclass);
    cdev_del(mycdev);
    unregister_chrdev(MAJOR(mycdevt), "mycdevt");
    printk(KERN_INFO "exited\n");
}   

module_init(myinit);
module_exit(myexit);

我正在关注ldd3书,并尝试使用简单的API为应用程序使用semahore。 发生的事情是我的内核在调用sema_init函数时崩溃了。我读到信号量用于互斥模式 http://www.makelinux.net/ldd3/chp-5-sect-3

我还读到信号量不是互斥量,因为没有所有权。我还没有探索过所有权&#39;事情,但是现在我无法做出简单的信号量。

我在这里做错了什么?

1 个答案:

答案 0 :(得分:0)

没有实际的信号量。

这一行:

NULL

为信号量创建指针,而不是信号量本身。它几乎肯定已初始化为static struct semaphore sem;

你可能想要像

这样的东西
sema_init( &sem, 1);

因此

up( &sem );

一起
down( &sem );

var hello = "Hello World!" 

请注意,这些调用采用的是实际信号量的地址。