linux设备驱动程序开发--并口控制LED的驱动源码

linux设备驱动程序开发--并口控制LED的驱动源码

  • 并口编程一些重要的函数
  • 并口控制LED的驱动源码

并口编程一些重要的函数

编写并行接口字符驱动程序

truct pardevice *pdev;
parport_claim_or_block(pdev);请求并口
parport_write_data(pdev->port,buf);
parport_release(pdev);释放并口

parport_register_device();
parport_register_driver();
parport_unregister_driver();

并口控制LED的驱动源码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include  //class

#define DEVICE_NAME "led"

static dev_t dev_number; /* Allotted device number */
static struct class *led_class; /* Class to which this device
                                   belongs */
struct cdev led_cdev; /* Associated cdev */
struct pardevice *pdev; /* Parallel port device */

/* LED open */
int led_open(struct inode *inode, struct file *file)
{
    return 0;
}

/* Write to the LED */
ssize_t led_write(struct file *file, const char *buf,size_t count, loff_t *ppos)
{
    char kbuf;
    if (copy_from_user(&kbuf, buf, 1)) return -EFAULT;
    /* Claim the port */
    parport_claim_or_block(pdev);
    /* Write to the device */
    parport_write_data(pdev->port, kbuf);
    /* Release the port */
    parport_release(pdev);
    return count;
}

/* Release the device */
int led_release(struct inode *inode, struct file *file)
{
    return 0;
}

/* File Operations */
static struct file_operations led_fops = {
    .owner = THIS_MODULE,
    .open = led_open,
    .write = led_write,
    .release = led_release,
};

static int
led_preempt(void *handle)
{
    return 1;
}

/* Parport attach method */
static void led_attach(struct parport *port)
{
    /* Register the parallel LED device with parport */
    pdev = parport_register_device(port, DEVICE_NAME,
         led_preempt, NULL,
         NULL, 0, NULL);
    if (pdev == NULL) printk("Bad register\n");
}

/* Parport detach method */
static void led_detach(struct parport *port)
{
    /* Do nothing */
}

/* Parport driver operations */
static struct parport_driver led_driver = {
    .name = "led",
    .attach = led_attach,
    .detach = led_detach,
};

/* Driver Initialization */
int __init led_init(void)
{
    /* Request dynamic allocation of a device major number */
    if (alloc_chrdev_region(&dev_number, 0, 1, DEVICE_NAME)< 0)
    {
        printk(KERN_DEBUG "Can't register device\n");
        return -1;
    }
    printk("alloc_chrdev_region..ok.\n");

    /* Create the led class */
    led_class = class_create(THIS_MODULE, DEVICE_NAME);
    if(IS_ERR(led_class))
        printk("Bad class create\n");
    else
        printk("class_create ok.\n");

    /* Connect the file operations with the cdev */
    cdev_init(&led_cdev, &led_fops);
    led_cdev.owner = THIS_MODULE;
    /* Connect the major/minor number to the cdev */
    if (cdev_add(&led_cdev, dev_number, 1))
    {
        printk("Bad cdev add\n");
        return 1;
    }
    else
        printk("cdev_add ok.\n");

    //class_device_create(led_class, NULL, dev_number,
    //     NULL, DEVICE_NAME);
    device_create(led_class, NULL, dev_number,
         NULL, DEVICE_NAME);

    /* Register this driver with parport */
    if(parport_register_driver(&led_driver))
    {
        printk(KERN_ERR "Bad Parport Register\n");
        return -EIO;
    }
    else
        printk("parport_register_driver ok\n");

    printk("LED Driver Initialized.\n");
    return 0;
}

/* Driver Exit */
void __exit led_cleanup(void)
{
    unregister_chrdev_region(dev_number, 1);
    //parport_unregister_driver();
    device_destroy(led_class,dev_number);
    class_destroy(led_class);
    return;
}

module_init(led_init);
module_exit(led_cleanup);
MODULE_LICENSE("GPL");



附件: parport.rar 将rar修改为tar.bz2

你可能感兴趣的:(Linux,linux,运维,服务器)