请帮帮忙,自己写了一个简单的字符设备驱动,调试的时候出了点问题。
一下是驱动程序:在IDE口上,基地址是0XD100 0000H
#include <linux/module.h> //所有模块都需要的头文件
#include <linux/init.h> // init&exit相关宏
#include <linux/fs.h>
#include <linux/slab.h>
#include <asm/io.h>
MODULE_LICENSE("GPL"
static int Device_Open = 0;
#define SUCCESS 0
#define CS3 0xD1000000
static void *cs3_mapped;
int cs3_irq = 8;
//char *cs3_buf;
static int cs3_open (struct inode *inode, struct file *file);
static int cs3_close (struct inode *inode, struct file *file);
static int cs3_read (struct file *file, char *buf, size_t count, loff_t *ppos);
static int cs3_write (struct file *file, const char *buf, size_t count, loff_t *ppos);
static int cs3_open(struct inode *, struct file *);
static int cs3_close(struct inode *, struct file *);
static int cs3_read(struct file *, char *, size_t, loff_t *);
static int cs3_write(struct file *, const char *, size_t, loff_t *);
static int cs3_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg);
irqreturn_t cs3_interrupt(int irq ,void *dev_id,struct pt_regs *regs);
static struct file_operations cs3_fops = {
owner: THIS_MODULE,
write: cs3_write,
ioctl: cs3_ioctl,
open: cs3_open,
release: cs3_close,
read: cs3_read,
};
static int cs3_open (struct inode *inode, struct file *file)
{
printk("cs3_open\n"
if(Device_Open)
return -EBUSY;
Device_Open++;
MOD_INC_USE_COUNT; //程序打开期间禁止卸载
cs3_mapped=ioremap(CS3, 0x0;
printk("CS3: physical address=%08lx\n",(unsigned long)CS3); /* test-only */
printk("CS3: mapped address=%08lx\n", (unsigned long)cs3_mapped); /* test-only */
// 启用中断;
if(cs3_irq>=0)
{
result=request_irq(cs3_irq,cs3_interrupt,SA_INTERRUPT,"cs3",NULL); ///快速中断处理例程
if(result)
{printk(KERN_INFO "cs3:can't get assigned irq %i\n",cs3_irq);
cs3_irq=-1;
}
else{
//启动中断;
outb(0x10,控制寄存器);
}
}
return SUCCESS;
}
static int cs3_close (struct inode *inode, struct file *file)
{
printk("cs3_close\n"
Device_Open--;
MOD_DEC_USE_COUNT;
iounmap(cs3_mapped);
//注销中断
free_irq(cs3_irq,NULL);
return 0;
}
static int cs3_read (struct file *file, char *buf, size_t count, loff_t *ppos)
{ int i=0;
printk("hello_read\n"
char *cs3_buf =kmalloc(sizeof(buf), GFP_KERNEL);
while(count--)
{
cs3_buf[i++]=inb(cs3_mapped);
rmb();
return count;
}
copy_to_user(buf,cs3_buf,count);
kfree(cs3_buf);
}
static int cs3_write (struct file *file, const char *buf, size_t count, loff_t *ppos)
{
int i=0;
// const char *cs3_buf;
printk("hello_write\n"
char *cs3_buf =kmalloc(sizeof(buf), GFP_KERNEL);
copy_from_user(cs3_buf,buf,count);
// iowrite8_rep(cs_mapped,cs3_buf,count);
// ioread8_rep(cs3_mapped,,count);
// printk("CS3: mapped address=%08lx\n", (unsigned long)cs3_mapped); /* test-only */
while(count--)
{
outb(cs3_buf[i++],cs3_mapped);
wmb();
}
// copy_from_user(,buf,count);
kfree(cs3_buf);
return count;
}
static int cs3_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
unsigned int minor = MINOR(inode->i_rdev);
int status;
int retval = 0;
#ifdef LP_DEBUG
printk(KERN_DEBUG "lp%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
#endif
if (minor >= LP_NO)
return -ENODEV;
if ((LP_F(minor) & LP_EXIST) == 0)
return -ENODEV;
switch ( cmd ) {
struct timeval par_timeout;
long to_jiffies;
case LPTIME:
LP_TIME(minor) = arg * HZ/100;
break;
case LPCHAR:
LP_CHAR(minor) = arg;
break;
case LPABORT:
if (arg)
LP_F(minor) |= LP_ABORT;
else
LP_F(minor) &= ~LP_ABORT;
break;
case LPABORTOPEN:
if (arg)
LP_F(minor) |= LP_ABORTOPEN;
else
LP_F(minor) &= ~LP_ABORTOPEN;
break;
case LPCAREFUL:
if (arg)
LP_F(minor) |= LP_CAREFUL;
else
LP_F(minor) &= ~LP_CAREFUL;
break;
case LPWAIT:
LP_WAIT(minor) = arg;
break;
case LPSETIRQ:
return -EINVAL;
break;
case LPGETIRQ:
if (copy_to_user((int *) arg, &LP_IRQ(minor),
sizeof(int)))
return -EFAULT;
break;
case LPGETSTATUS:
lp_claim_parport_or_block (&lp_table[minor]);
status = r_str(minor);
lp_release_parport (&lp_table[minor]);
if (copy_to_user((int *) arg, &status, sizeof(int)))
return -EFAULT;
break;
case LPRESET:
lp_reset(minor);
break;
#ifdef LP_STATS
case LPGETSTATS:
if (copy_to_user((int *) arg, &LP_STAT(minor),
sizeof(struct lp_stats)))
return -EFAULT;
if (capable(CAP_SYS_ADMIN))
memset(&LP_STAT(minor), 0,
sizeof(struct lp_stats));
break;
#endif
case LPGETFLAGS:
status = LP_F(minor);
if (copy_to_user((int *) arg, &status, sizeof(int)))
return -EFAULT;
break;
case LPSETTIMEOUT:
if (copy_from_user (&par_timeout,
(struct timeval *) arg,
sizeof (struct timeval))) {
return -EFAULT;
}
/* Convert to jiffies, place in lp_table */
if ((par_timeout.tv_sec < 0) ||
(par_timeout.tv_usec < 0)) {
return -EINVAL;
}
to_jiffies = ROUND_UP(par_timeout.tv_usec, 1000000/HZ);
to_jiffies += par_timeout.tv_sec * (long) HZ;
if (to_jiffies <= 0) {
return -EINVAL;
}
lp_table[minor].timeout = to_jiffies;
break;
default:
retval = -EINVAL;
}
return retval;
}
static int __init cs3_init (void)
{
int result;
//注册设备号
result = register_chrdev(100,"cs3", &cs3_fops);
if(result<0)
{
printk("cs3 warning:can't get major %d\n", 100);
return -EIO;
}
printk("cs3 module init\n"
// return 0;
return 0;
}
static void __exit cs3_exit (void)
{
//释放设备
// if(unregister_chrdev(100,"cs3"!=0)
if(unregister_chrdev(100,"cs3"!=0)
{
printk("cs3 unregistered is failed \n"
}
// printk("cs3 module exit\n"
printk("cs3 module exit\n");
}
module_init(cs3_init);
module_exit(cs3_exit);
//中断处理例程程序
irqreturn_t cs3_interrupt(int irq ,void *dev_id,struct pt_regs *regs)
{}
//struct time}
测试函数:
#include <stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<fcntl.h>
#define cs3 "dev/"
static int cs3_fd=-1
static int init_device(viod)
{
if((cs3_fd=open(cs3,O_RDWR))<0){
pintf("Error opening %s device\n", cs3);
return -1;
}
return 0;
}
int main(void){
int i;
int buf[256]
int data;
if(init_device()<0)
return -1;
read(cs3_fd,buf,256);
for(i=0;i<256;i++)
{
pintf("d%\n"buf);
}
write(cs3_fd,buf,256);
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不知道是不是,头文件的问题,一些内核函数无法识别如printk,iroemap,等