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

📄 stepper.c

📁 linux下 步进电机驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
     switch(cmd) {        case(STEPPER_SET_DEBUG):           /* unfriendly user might crash system */           /* by setting debug too high.  Only allow */           /* root to change debug */           if((current->uid==0) || (current->euid==0)) {	      debug=arg;           } else {              return(EPERM);           }           break;        case(STEPPER_SET_SKIPTICKS):           skipticks=arg;           break;        case(STEPPER_SET_VERBOSE_IO):           verbose_io=arg;           break;        case(STEPPER_SET_VERBOSE_MOVE):           verbose_move=arg;           break;        case(TCGETS):           break;        #if 0           /* autostart and start/stop are not implemented */           /* these would be used to enable interrupts */           /* only when the driver is in use and to */           /* allow a program to turn them on and off */	   case(STEPPER_START):	      if(debug) printk("stepper_ioctl(): start\n");	      stepper_start();	      break;	   case(STEPPER_STOP):	      if(debug) printk("stepper_ioctl(): stop\n");	      stepper_stop();	      break;	   case(STEPPER_CLEAR_BUFFERS):	      if(debug) {                  printk("stepper_ioctl(): clear buffers\n");              }	      ring_buffer_init(&read_buffer);	      ring_buffer_init(&write_buffer);	      break;	   case(STEPPER_AUTO):	     if(debug) {		printk("stepper_ioctl(): enable autostart\n");	     }	     autostart = 1;	     break;	   case(STEPPER_NOAUTO):	     if(debug) {		printk("stepper_ioctl(): disable autostart\n");	     }	     autostart = 0;	     break;        #endif	default:	   printk("stepper_ioctl(): Unknown ioctl %d\n",cmd);	   break;     }     return(0);   }    static int stepper_open(struct inode *inode,        struct file *file)    {       int rc;       int minor;       minor = MINOR(inode->i_rdev);       printk("stepper: stepper_open() - file->f_mode=%d\n",          file->f_mode);       /*        * As written, only one process can have the device         * open at once.  For some applications, it might be         * nice to have multiple processes (one controlling, for        *  example, X and Y while the other controls Z).        * I use two separate entries in /dev/, with         * corresponding minor device numbers, to allow a         * program to open for ioctl while another program         * has the data connection open.        * This would allow a Panic Stop application to be         * written,         * for example.        *    Minor device = 0  - read and write         *    Minor device = 1  - ioctl() only         */       /* if minor!=0, we are just opening for ioctl */       if(minor!=0) {	  MOD_INC_USE_COUNT;	  return(0);       }          if(autostart) stepper_start();       if(file->f_mode==1) {	  /* read */	 if(read_is_open) {           printk("stepper: stepper_open() - read busy\n");	   return(-EBUSY);	 } else {	   read_is_open=1;	   abort_read=0;	   MOD_INC_USE_COUNT;	 }             } else if(file->f_mode==2) {	 /* write */	 if(write_is_open) {           printk("stepper: stepper_open() - write busy\n");	   return(-EBUSY);	 } else {	   write_is_open=1;	   abort_write=0;	   MOD_INC_USE_COUNT;	 }             } else {          printk("stepper: stepper_open() - unknown mode\n");	  return(-EINVAL);       }       if(debug) printk("stepper: stepper_open() - success\n");       return(0);    }   void stepper_release(struct inode *inode, struct file *file)    {      int minor;      minor = MINOR(inode->i_rdev);      if(minor!=0) {	 MOD_DEC_USE_COUNT;	 return;      }      printk("stepper: stepper_release() - file->f_mode=%d\n",         file->f_mode);      if(file->f_mode==1) {	 /* read */	if(read_is_open) {	  abort_read=1;	  if(read_is_sleeping) {             wake_up_interruptible(&read_wait);          }	  read_is_open=0;	  MOD_DEC_USE_COUNT;	} else {	  printk("stepper: ERROR: stepper_release() "             "called unexpectedly (read)\n");	}      } else if(file->f_mode==2) {	/* write */	if(write_is_open) {	  abort_write=1;	  if(write_is_sleeping) {             wake_up_interruptible(&write_wait);          }	  write_is_open=0;	  MOD_DEC_USE_COUNT;	} else {	  printk("stepper: ERROR: stepper_release() called"             " unexpectedly (write)\n");	}      } else {	printk("stepper: stepper_release() "           "- invalid file mode\n");      }      if(!read_is_open && !write_is_open) {	 stepper_stop();      }     }   static struct file_operations stepper_fops = {      stepper_lseek,      stepper_read,      stepper_write,      NULL,           /* readdir */      NULL,           /* select */      stepper_ioctl,           /* ioctl */      NULL,           /* mmap */      stepper_open,      stepper_release,      NULL,           /* fsync */      NULL,           /* fasync */      NULL,           /* check_media_change */      NULL            /* revalidate */   };   static int using_jiffies = 0;   static struct wait_queue *tick_die_wait_queue = NULL;   /* forward declaration to resolve circular reference */   static void timer_tick_handler(void *junk);   static struct tq_struct tick_queue_entry = {      NULL, 0, timer_tick_handler, NULL   };    static void bottom_half()   {      int rc;      char c;      tick_counter++;      if(tick_die_wait_queue) {        /* cleanup_module() is waiting for us */	/* Don't reschedule interrupt and wake up cleanup */         using_jiffies = 0;         wake_up(&tick_die_wait_queue);      } else {         if((skipticks==0) || ((tick_counter % skipticks)==0)) {	    /* Don't process any move commands if */	    /* we haven't finished the last one */	    if( (xdest==xpos)             && (ydest==ypos)             && (zdest==zpos) ) {	       /* process command characters */	       while(                  (rc=ring_buffer_read(&write_buffer,&c,1))==1               ){		   parse_one_char(c);		   if((xdest!=xpos) 		   || (ydest!=ypos) 		   || (zdest!=zpos) ) {		      /* parse_one_char() started a move; */		      /* stop reading commands so current move*/		      /* can complete first. */		      break;		   }	       }	       if(write_is_sleeping) {		  wake_up_interruptible(&write_wait);	       }	    }         }         move_one_step();                  /* put ourselves back in the queue for the next tick*/         if(using_jiffies) {            queue_task(&tick_queue_entry, &tq_timer);	 }      }   }   static void timer_tick_handler(void *junk)   {      /* let bottom_half() do the work */      bottom_half();   }    void interrupt_handler(int irq, void *dev_id,       struct pt_regs *regs)   {      /* let bottom_half() do the work */      bottom_half();   }   int init_module(void)   {      int rc;      ring_buffer_init(&read_buffer);      ring_buffer_init(&write_buffer);      read_is_sleeping=0;      write_is_sleeping=0;          if ((stepper_major = register_chrdev(major,"step",      &stepper_fops)) <0 ) {        printk("stepper: unable to get major device\n");        return(-EIO);     }      /* register_chrdev() does not return the major device */     /* number,  workaround will not be correct if major=0 */     stepper_major = major;     if(debug) printk("stepper:init_module():stepper_major=%d\n",        stepper_major);     if(check_region(base,4)) {        printk("stepper: port in use");        unregister_chrdev(stepper_major, "step");        return;     }     request_region(base,4);     if(irq && (!interrupts_are_enabled)) {        rc=request_irq(irq,interrupt_handler,0,"stepper",NULL);	if(rc) {	   printk("stepper: stepper_start() - request_irq() "              "returned %d\n",rc);	} else {	   printk("stepper: stepper_start() "              "- enabled interrupts\n");           interrupts_are_enabled = 1;           /* now that we are ready to receive them */           /* enable interrupts on parallel card */                     word = irq_enable_bit;           verbose_outb( (word >> 8), base+2);	}     }     if(!irq) {        using_jiffies = 1;        queue_task(&tick_queue_entry, &tq_timer);     }          /* give ourselves some work to do */     xdest = ydest = zdest = 400;     if(debug) printk( "stepper: module loaded\n");     return(0);   }   void cleanup_module(void)   {     abort_write=1;     if(write_is_sleeping) wake_up_interruptible(&write_wait);     abort_read=1;     if(read_is_sleeping) wake_up_interruptible(&read_wait);     #if 1        /* Delay 1s for read and write to exit */        current->state = TASK_INTERRUPTIBLE;        current->timeout = jiffies + 100;         schedule();     #endif     release_region(base,4);     if(MOD_IN_USE) {        printk("stepper: device busy, remove delayed\n");        return;     }     printk("unregister_chrdev(%d,%s)\n",stepper_major, "step");     if( unregister_chrdev(stepper_major, "step") ) {        printk("stepper: unregister_chrdev() failed.\n");        printk("stepper: /proc/devices will cause core dumps\n");        /* Note: if we get here, we have a problem */        /* There is still a pointer to the name of the device */        /* which is in the address space of the LKM */        /* which is about to go away  and we cannot abort 	/* the unloading of the module */     }     /* note: we need to release the interrupt here if */     /* necessary otherwise, interrupts may cause kernel */     /* page faults */     if(interrupts_are_enabled) {        /* Disable interrupts on card before we unregister */        word &= ~irq_enable_bit;        verbose_outb( (word >> 8), base+2);                free_irq(irq,NULL);     }     if(using_jiffies) {        /* If we unload while we are still in the jiffie */        /* queue, bad things will happen.  We have to wait */        /* for the next jiffie interrupt */        sleep_on(&tick_die_wait_queue);     }     if(power_down_on_exit) {        word=flipbits;        /* output low byte to data register */        verbose_outb( (word & 0x00FF), base+0);        /* output high byte to control register */        verbose_outb( (word >> 8), base+2);     }     if(debug) printk("stepper: module unloaded\n");   }#else  /* ! __KERNEL__ */main(){   char c;   /* unbuffer output so we can see in real time */     setbuf(stdout,NULL);   printf("this program must be run as root\n");   iopl(3);   /* Enable i/o (if root) */   printf("Here are some example motion commands:\n");   printf("   X=100,Y=100,Z=50\n");   printf("   X=100,Y=100\n");   printf("   Y=100,Z=50\n");   printf("   X=+100,Y=-100\n");   printf("   ?   (reports position)");   printf("End each command with a newline.\n");   printf("Begin typing motion commands\n");   while(!feof(stdin)) {      c = getc(stdin);      parse_one_char(c);      move_all();   }   if(power_down_on_exit) {      word=flipbits;      /* output low byte to data register */      verbose_outb( (word & 0x00FF), base+0);      /* output high byte to control register */      verbose_outb( (word >> 8), base+2);   }}#endif

⌨️ 快捷键说明

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