linux设备驱动程序开发--并口控制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 <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/parport.h>
#include <asm/uaccess.h>
#include <linux/platform_device.h>
#include <linux/pci.h>
#include <linux/device.h> //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