0
/* Necessary includes for drivers */
#include <linux/init.h>
//#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>       /* printk() */
#include <linux/slab.h>         /* kmalloc() */
#include <linux/fs.h>           /* everything... */
#include <linux/errno.h>        /* error codes */
#include <linux/types.h>        /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h>        /* O_ACCMODE */
#include <linux/ioport.h>
#include <asm/system.h>         /* cli(), *_flags */
#include <asm/uaccess.h>        /* copy_from/to_user */
#include <asm/io.h>             /* inb, outb */

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Nikunj");


/* Function declaration of parlelport.c */ 
int parlelport_open(struct inode *inode, struct file *filp); 
int parlelport_release(struct inode *inode, struct file *filp); 
ssize_t parlelport_read(struct file *filp, char *buf, size_t count, loff_t *f_pos); 
ssize_t parlelport_write(struct file *filp, char *buf, size_t count, loff_t *f_pos); 
void parlelport_exit(void);
int parlelport_init(void);

/* Structure that declares the common */
/* file access fcuntions */
struct file_operations parlelport_fops = { 
    read    : parlelport_read,
    write   : parlelport_write,
    open    : parlelport_open,
    release : parlelport_release
    };

/* Driver global variables */
/* Major number */
int parlelport_major = 61;

/* Control variable for memory */ 
/* reservation of the parallel port*/
int port;

module_init(parlelport_init);
module_exit(parlelport_exit);

int parlelport_init(void) 
{ 
    int result;

    /* Registering device */
    result = register_chrdev(parlelport_major, "parlelport", &parlelport_fops);
    if (result < 0) 
    { 
        printk("<1>parlelport: cannot obtain major number %d\n",parlelport_major); 
        return result; 
    } 

    /* Registering port */
    port = check_region(0x378, 1);
    if (port) 
    { 
        printk("<1>parlelport: cannot reserve 0x378\n"); 
        result = port; 
        goto fail;
    }

    request_region(0x378, 1, "parlelport");

    printk("<1>Inserting parlelport module\n"); 
    return 0;

    fail: 
    parlelport_exit(); 
    return result;
}

void parlelport_exit(void) 
{
    /* Make major number free! */
    unregister_chrdev(parlelport_major, "parlelport");

     /* Make port free! */ 
    if (!port) 
    { 
            release_region(0x378,1);
    }

    printk("<1>Removing parlelport module\n");
}

int parlelport_open(struct inode *inode, struct file *filp) 
{
    /* Success */
    return 0;
}
int parlelport_release(struct inode *inode, struct file *filp) 
{
    /* Success */
    return 0; 
}
ssize_t parlelport_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) 
{

    /* Buffer to read the device */
    char parlelport_buffer;

    /* Reading port */
    parlelport_buffer = inb(0x378);

    /* We transfer data to user space */
    copy_to_user(buf,&parlelport_buffer,1); 

    /* We change the reading position as best suits */
    if (*f_pos == 0) 
    { 
        *f_pos+=1; 
        return 1; 
    } 
    else 
    { 
        return 0; 
    }
}
ssize_t parlelport_write( struct file *filp, char *buf, size_t count, loff_t *f_pos) 
{
    char *tmp;

    /* Buffer writing to the device */
    char parlelport_buffer;

    tmp=buf+count-1;
    copy_from_user(&parlelport_buffer,tmp,1);

    /* Writing to the port */
    outb(parlelport_buffer,0x378);

    return 1; 
}

这是并行端口设备驱动程序的代码,这是我的第一个 c 代码。请帮我解决以下问题

我已成功编译代码并成功创建 .ko 文件并成功加载到 ubuntu 9.10 操作系统中,但你的引脚没有高低,所以请帮帮我

4

2 回答 2

1

你如何检查答案?安装模块后执行
dmesg

于 2013-01-16T13:40:08.217 回答
0

实际上,您无法在 0x378 处获取区域。因为默认情况下系统将此分配给parport0。

执行 cat /proc/ioports,这样你会发现在 0x378 处有 parport0。您可以直接在该地址 (0x378) 上写入,而无需使用该检查和请求。

我的建议是不要直接采用复杂的形式。在写入功能中,只需写入 outb(0x378,1) 并检查(通过插入具有 LED 的硬件)数据引脚上的 LED 开/关。

于 2013-05-20T13:12:47.200 回答