📄 step.c
字号:
#include "step.h"
#include "hard.h"
ring_buffer_t read_buffer;
ring_buffer_t write_buffer;
static int irq = IRQ;
static int major = 0;
static int stepper_major = 0;
struct wait_queue *read_wait = NULL;
struct wait_queue *write_wait = NULL;
static int verbose_io;
static int verbose_move;
static int power_down_on_exit = 1;
static int delay = 50000;
static int fastdelay = 0;
static int skipticks = 0;
static int do_io = 1;
static int read_is_sleeping = 0;
static int write_is_sleeping = 0;
static int abort_read = 0;
static int abort_write = 0;
static int read_is_open = 0;
static int write_is_open = 0;
static int interrupts_are_enabled = 0;
static int autostart = 1;
static int tick_counter = 0;
int xdest = 0;
int xuser = 0;
int xpos = 0;
int ydest = 0;
int yuser = 0;
int ypos = 0;
int zdest = 0;
int zuser = 0;
int zpos = 0;
unsigned short word;
static int using_jiffies = 0;
static struct wait_queue *tick_die_wait_queue = NULL;
static struct tq_struct tick_queue_entry = {
NULL, 0, timer_tick_handler, NULL
};
static struct file_operations stepper_fops{
llseek: stepper_lseek,
read: stepper_read,
write: stepper_write,
ioctl: stepper_ioctl,
open: stepper_open,
release: stepper_release,
};
static int stepper_lseek(struct inode *inode, struct file *file, off_t offset, int orig)
{
return(file->f_pos = 0);
}
static int stepper_open(struct inode *inode, struct file *file)
{
int rc;
int minor;
minor = MINOR(inode->i_rdev);
printk("file open mode is %d\n", file->f_mode);
if(minor != 0){
MOD_INC_USE_COUNT;
return(0);
}
if(autostart) stepper_start();
if(file->f_mode == 1){
if(read_is_open){
printk("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){
if(write_is_open){
printk("stepper_open: write busy\n");
return(-EBUSY);
}else{
write_is_open = 1;
abort_write = 0;
MOD_INC_USE_COUNT;
}
}else{
printk("stepper_open: unknown mode\n");
}
return(0);
}
void stepper_release(struct inode *inode, struct file *file)
{
int minor;
minor = MINOR(inode->i_rdev);
printk("file open mode is %d\n", file->f_mode);
if(minor != 0){
MOD_INC_USE_COUNT;
return(0);
}
if(file->f_mode == 1){
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_release: unexpect read\n");
}
}else if(file->f_mode == 2){
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_release: unexpect write\n");
}
}else{
printk("stepper_release: unknown mode");
}
return(0);
}
static int stepper_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
switch(cmd){
case(STEPPER_SET_SKIPTICKS):
skipticks = arg;
break;
case(STEPPER_SET_VERBOSE_IO):
verbose_io = arg;
break;
case(STEPPER_START):
printk("stepper_ioctl: stepper_start\n");
break;
case(STEPPER_CLEAR_BUFFERS):
printk("clear buffers\n");
ring_buffer_init(&read_buffer);
ring_buffer_init(&write_buffer);
break;
default:
break;
}
}
static int stepper_read(struct inode *inode, struct file *file, char *buf, int count)
{
int rc;
int bytes_transferred = 0;
char xferbuf;
char *i_buf,*o_buf;
o_buf = ibuf;
if(!read_is_open){
printk("the file has not open\n");
return(0);
}
for(i=0; i<count; i++){
while(1){
rc = ring_buffer_read(&read_buffer, &xferbuf, 1);
if(rc == 1){
bytes_transferred++;
*i_buf++ = xferbuf;
break;
}
read_is_sleeping = 1;
interruptible_sleep_on(&read_wait);
read_is_sleeping = 0;
if(abort_read) return(0);
}
}
copy_to_user(buf, o_buf, bytes_transferred);
if(write_is_sleeping) wake_up_interruptible(&write_wait);
}
static int stepper_write(struct inode *inode, struct file *file, char *buf, int count)
{
int rc;
int bytes_transferred = 0;
char xferbuf;
if(!write_is_open){
printk("the file has not open\n");
return(0);
}
for(i=0; i<count; i++){
while(1){
put_fs_byte(xferbuf, buf++);
rc = ring_buffer_write(&write_buffer, &xferbuf, 1);
if(rc == 1){
bytes_transferred++;
break;
}
write_is_sleeping = 1;
interruptible_sleep_on(&write_wait);
write_is_sleeping = 0;
if(abort_write) return(0);
}
}
if(read_is_sleeping) wake_up_interruptible(&read_wait);
}
void parse_one_char(char c)
{
static int value;
static int dest=' ';
static int negative=0;
if( (c > 'a') && (c < 'z') ) c = c - 'a' + 'A';
switch(c){
case('X'):
case('Y'):
case('Z'):
dest = c;
break;
case('='):
break;
case('-'):
negative = !negative;
case('+'):
negative = 0;
case('0'):
case('1'):
case('2'):
case('3'):
case('4'):
case('5'):
case('6'):
case('7'):
case('8'):
case('9'):
value *= 10;
value += (c - '0');
break;
case(','):
case('\n'):
case('\r'):
if(negative){
value = -value;
}
if(dest == 'X'){
xuser = value;
}else if(dest == 'Y'){
yuser = value;
}else(dest == 'Z'){
zuser = value;
}
if( (c == '\r') || (c == '\n') ){
xdest = xuser;
ydest = yuser;
zdest = zuser;
}
break
}
}
static void bottom_half()
{
int rc;
char c;
tick_counter++;
if(tick_die_wait_queue){
using_jiffies = 0;
wake_up(tick_die_wait_queue);
}else{
if((skipticks == 0) || ((tick_counter % skipticks) == 0)){
if((xdest == xpos) && (ydest == ypos) && (zdest == zpos)){
while((rc = ring_buffer_read(&write_buffer, &c, 1)) == 1){
parse_one_char(c);
if((xdest != xpos) || (ydest != ypos) || (zdest != zpos)){
break;
}
}
if(write_is_sleeping){
wake_up_interruptible(&write_wait);
}
}
}
move_one_step();
if(using_jiffies){
queue_task(&tick_queue_entry, &tq_timer);
}
}
}
static void timer_tick_hander(void *junk)
{
bottom_half();
}
void interrupt_handler(int irq, void *dev_id, struct pt_regs *regs)
{
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(register_chrdev(major, "step", &stepper_fops)<0){
printk("stepper: unable to get major device\n");
return(-EIO);
}
if(check_region(base, 4)){
printk("stepper: port in use\n");
unregister_chrdev(major, "step");
return;
}
request_region(base, 4);
if(irq && (!interrupts_are_enabled)){
rc = request_irq(irq, interrupt_hander, 0, "stepper", NULL);
if(rc){
printk("stepper: request irq return %d\n", rc);
}else{
printk("stepper: enable irq");
interrupts_are_enabled = 1;
enableirq();
}
}
if(!irq){
using_jiffies = 1;
queue_task(&tick_queue_entry, &tq_timer);
}
xdest = ydest = zdest = 400;
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);
release_region(base, 4);
if(unregister_chrdev(major, "step")){
printk("stepper: unregister_chrdev() failed.\n");
}
if(interrupts_are_enable){
disableirq();
free_irq(irq, NULL);
}
if(using_jiffies){
sleep_on(&tick_die_wait_queue);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -