/* 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操作系统中,但你的引脚没有高或低,所以请帮帮我
答案 0 :(得分:1)
你是如何检查答案的?安装好模块后 dmesg
答案 1 :(得分:0)
实际上你不能在0x378获得区域。因为默认情况下系统会将此分配给parport0。
执行cat / proc / ioports所以你会发现在0x378有parport0。 您可以直接在该地址(0x378)上写入,而无需使用该检查和请求。
我的建议是不要直接以复杂的形式进行。在写函数中只写 outb(0x378,1)并检查(通过插入具有LED的硬件)LED在数据引脚上打开/关闭。