⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 diopsis.c

📁 Linux 核心驱动程序。提供多线程访问和保护能力。快速I/O访问。
💻 C
📖 第 1 页 / 共 2 页
字号:
  if(enc_io)  {        printk(KERN_INFO "cannot reserve encoder io: %x\n", counterlow_reg);  }  request_region(counterlow_reg, PORT_SIZE, "mesa_countlow");   /* allocate io region for encoder *//*------- allocationg io port for MESA counter high register ----------*/  enc_io = check_region(counterhigh_reg, PORT_SIZE);          /* check if region is free? */  if(enc_io)  {        printk(KERN_INFO "cannot reserve encoder io: %x\n", counterhigh_reg);  }  request_region(counterhigh_reg, PORT_SIZE, "mesa_counthigh");   /* allocate io region for encoder */  /*--------------------------------------------------------*/  init_MUTEX_LOCKED(&sem);                     /* initialise mutual exlcusive */  init_MUTEX_LOCKED(&sem2);  /*-----------------------------------------------------------   |      ALLOCATING BUFFER MEMORY FOR EACH ENCODER INPUT     |   | ---------------------------------------------------------|   | i)  allocate memory using kmalloc                        |   | ii) round up to page boundry                             |   | iii)reserve the pages                                    |   -----------------------------------------------------------*/  /* -----------------encoder channel 0----------------------- */  enc_buf_0 = (int*)kmalloc(MEM_SIZE * PAGE_SIZE, GFP_KERNEL);  /* allocate memory */  printk(KERN_INFO "enc_buf_0 = %p \n", enc_buf_0);  if (!enc_buf_0) {     result = -ENOMEM;    printk(KERN_INFO "memory error\n");  }   /* round kmalloc to page boundry */  kmalloc_area_0 = (int *)((((unsigned long)enc_buf_0) + PAGE_SIZE - 1) & PAGE_MASK);  /* reserve pages */  for (i = 0; i < MEM_SIZE * PAGE_SIZE; i+= PAGE_SIZE)   {       SetPageReserved(virt_to_page(((unsigned long)kmalloc_area_0) + i));  }  /*-------------------------------------------------------------*/  /*-----------------encoder channel 1---------------------------*/  enc_buf_1 = (int*)kmalloc(MEM_SIZE * PAGE_SIZE, GFP_KERNEL);    /* allocate memory */   printk(KERN_INFO "enc_buf_1 = %p \n", enc_buf_1);  if (!enc_buf_1) {     result = -ENOMEM;    printk(KERN_INFO "memory error\n");  }   /* round kmalloc to page boundry */  kmalloc_area_1 = (int *)((((unsigned long)enc_buf_1) + PAGE_SIZE - 1) & PAGE_MASK);  /* reserve pages */ for (i = 0; i < MEM_SIZE * PAGE_SIZE; i+= PAGE_SIZE)  {      SetPageReserved(virt_to_page(((unsigned long)kmalloc_area_1) + i)); } /*----------------------------------------------------------------*/  /*------------------encoder channel 2----------------------------*/  enc_buf_2 = (int*)kmalloc(MEM_SIZE * PAGE_SIZE, GFP_KERNEL);     /* allocate memory */  printk(KERN_INFO "enc_buf_2 = %p \n", enc_buf_2);  if (!enc_buf_2) {     result = -ENOMEM;    printk(KERN_INFO "memory error\n");  }   /* round kmalloc to page boundry */  kmalloc_area_2 = (int *)((((unsigned long)enc_buf_2) + PAGE_SIZE - 1) & PAGE_MASK);  /* reserve pages */  for (i = 0; i < MEM_SIZE * PAGE_SIZE; i+= PAGE_SIZE)   {      SetPageReserved(virt_to_page(((unsigned long)kmalloc_area_2) + i));  }  /*--------------------------------------------------------------*/  /*-------------------encoder channel 3--------------------------*/  enc_buf_3 = (int*)kmalloc(MEM_SIZE * PAGE_SIZE, GFP_KERNEL);     /* allocate memory */  printk(KERN_INFO "enc_buf_3 = %p \n", enc_buf_3);  if (!enc_buf_3) {     result = -ENOMEM;    printk(KERN_INFO "memory error\n");  }   /* round kmalloc to page boundry */  kmalloc_area_3 = (int *)((((unsigned long)enc_buf_3) + PAGE_SIZE - 1) & PAGE_MASK);  /* reserve pages */  for (i = 0; i < MEM_SIZE * PAGE_SIZE; i+= PAGE_SIZE)   {     SetPageReserved(virt_to_page(((unsigned long)kmalloc_area_3) + i));  }  /*--------------------------------------------------------------*/    /* initialise encoder buffers, as valid data values will not be added     until a read function operates*/  (*enc_buf_0)= 0;  (*enc_buf_1)= 0;   (*enc_buf_2)= 0;  (*enc_buf_3)= 0;    return SUCCESS;}/* interrupt function - triggered by genlock pulse from the ioport genlock                        mapped to 'genport 0xXXX'                            */static irqreturn_t diopsis_interrupt(int irq, void *dev_id, struct pt_regs *regs){   //printk(KERN_INFO "Interrupt function\n");   //up(&sem2);  //interrupt_cnt++;                                           /* number of interrupts */  //printk(KERN_INFO "interrupt count: %d\n", interrupt_cnt);  /* for TEST purpose     */    outw(0x00, countHigh);       /* latch all MESA counters */  /* communicates with user application sending SIGIO. This will indicate      that the genlock has been triggered, and the encoder data should be read.      Caught by the signal() command in the associated user application */   kill_fasync(&dev_async_queue, SIGIO, POLL_IN);                    //down_interruptible(&sem2);    /* lock mutex */   return IRQ_HANDLED;}/* User space communication - function that adds and removes entries from the                              list of interestesd processes when the FAYNC flag chnages                            - kill_fasync() used to singal interested processes when                               data arrives                                             */static int dev_fasync(int fd, struct file *filp, int on){	return fasync_helper(fd, filp, on, &dev_async_queue);}/* exit function */void diopsis_exit(void) {  int i;    unregister_chrdev(diopsis_major, "diopsis");      /* Freeing the major number */    free_irq(diopsis_irq, NULL);                      /* Freeing interrupt */     /* Freeing ioports */  release_region(gen_port       , PORT_SIZE);   release_region(index_reg      , PORT_SIZE);  release_region(counterlow_reg , PORT_SIZE);  release_region(counterhigh_reg, PORT_SIZE);    /*------------------------------------------------------------   |     unreserve the pages for allocated encoder buffers     |   ------------------------------------------------------------- */  for (i = 0; i < MEM_SIZE * PAGE_SIZE; i+= PAGE_SIZE)   {      SetPageReserved(virt_to_page(((unsigned long)kmalloc_area_0) + i));  }  for (i = 0; i < MEM_SIZE * PAGE_SIZE; i+= PAGE_SIZE)   {      SetPageReserved(virt_to_page(((unsigned long)kmalloc_area_1) + i));  }  for (i = 0; i < MEM_SIZE * PAGE_SIZE; i+= PAGE_SIZE)   {      SetPageReserved(virt_to_page(((unsigned long)kmalloc_area_2) + i));  }  for (i = 0; i < MEM_SIZE * PAGE_SIZE; i+= PAGE_SIZE)   {      SetPageReserved(virt_to_page(((unsigned long)kmalloc_area_3) + i));  }  /* Free allocated memory for encoder buffers*/  kfree(enc_buf_0);  kfree(enc_buf_1);  kfree(enc_buf_2);  kfree(enc_buf_3);  printk(KERN_INFO "Removing interrupt: %d\n", diopsis_irq);  printk(KERN_INFO "Removing diopsis module\n");}/* open function to open driver */int diopsis_open(struct inode *inode, struct file *filp){    printk(KERN_INFO "Open Success\n");    /* send SIGIO to user application, used here for testing, comment out      when testing interrupt function                                    */   //kill_fasync(&dev_async_queue, SIGIO, POLL_IN);   return SUCCESS;}/* release function to release driver */int diopsis_release(struct inode *inode, struct file *filp) {   printk(KERN_INFO "Release Success\n");  return SUCCESS;}/* read function - reads ioport enc_port to read encoder data, then copies                   to user space                                          */ssize_t diopsis_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) {    const char data[30];         int data_len;   /* talk to MESA encoder board to read encoder data*/   outw(IDXAutoInc_bit, index);      /* enables auto increment feature to read all channels */   enc_0_lo = inw(countLow);         /* lower word of counter */     enc_0_hi = inw(countHigh) << 16;  /* upper word of counter made into 32 bit value */   enc_1_lo = inw(countLow);   enc_1_hi = inw(countHigh) << 16;   enc_2_lo = inw(countLow);   enc_2_hi = inw(countHigh) << 16;   enc_3_lo = inw(countLow);   enc_3_hi = inw(countHigh) << 16;  (*enc_buf_0)= enc_0_hi + enc_0_lo;    /* combine lower and upper word for 32 bit value   */  (*enc_buf_1)= enc_1_hi + enc_1_lo;    /* for each channel, store in shared memory buffer */  (*enc_buf_2)= enc_2_hi + enc_2_lo;  (*enc_buf_3)= enc_3_hi + enc_3_lo;    /* print encoder data *//*  printk(KERN_INFO "encoder data b0 : %d \n", *enc_buf_0);  printk(KERN_INFO "encoder data b1 : %d \n", *enc_buf_1);  printk(KERN_INFO "encoder data b2 : %d \n", *enc_buf_2);  printk(KERN_INFO "encoder data b3 : %d \n", *enc_buf_3);*/   /* place encoder data into string to pass through to user space */   sprintf(data, " %d %d %d %d ", *enc_buf_0, *enc_buf_1, *enc_buf_2, *enc_buf_3);   data_len = strlen(data);          up(&sem);             /* unlock mutex */   /* mdelay(5000); */        /* creates a delay so that the blocking can be tested */  /* check limits */   if (*f_pos >= data_len)         return 0;                             if (*f_pos + count >= data_len)         count = data_len - *f_pos;      copy_to_user(buf, data + *f_pos, count);     /* copies to user space */          *f_pos += count;           printk(KERN_INFO "Read Success\n");    //read_cnt++;                                     /* counts number off read function calls - TEST purpose */   //printk(KERN_INFO "read cnt: %d\n", read_cnt);   down_interruptible(&sem);    /* lock mutex */   return count;}/* write not supported as no need to write to genlock or encoder */ssize_t diopsis_write( struct file *filp, char __user *buf, size_t count, loff_t *f_pos) {    printk(KERN_INFO "Operation Not Supported\n");  return -EINVAL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -