请帮帮忙,自己写了一个简单的字符设备驱动,调试的时候出了点问题。

发布于 2022-09-19 15:56:39 字数 20807 浏览 15 评论 0

一下是驱动程序:在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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冬天旳寂寞 2022-09-26 15:56:39

不知道是不是,头文件的问题,一些内核函数无法识别如printk,iroemap,等

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文