?? pwm2.c
字號:
/* vim: set ts=4: *//* * Copywrite 2002 Der Herr Hofrat * License GPL V2 * Author der.herr@hofr.at *//* * example of a simple PWM using a proc interface to set the duty cylcle */#include <rtl.h>#include <time.h>#include <rtl_sched.h>#include <rtl_sync.h>#include <pthread.h>#include <posix/unistd.h>#include <linux/proc_fs.h> /* proc filesystem stuff */struct proc_dir_entry *proc_pwm_duty_cycle;#include <asm/io.h> /* outb */#define LPT 0x378#define LPT_CNTRL LPT+2 #define MAX_DUTY_CYCLE 90#define MIN_DUTY_CYCLE 10#define DC_SCALAR 10000 /* 10 micro seconds */#define PERIOD 100*DC_SCALAR /* period is 100% duty cycle */pthread_t pwm_thread;void *pwm_code(void *);int stop = 0;unsigned long duty_cycle=MIN_DUTY_CYCLE*DC_SCALAR;int simple_atoi(const char *);#define MAXLEN 3 /* maximum number of digits to use */void *pwm_code(void *arg){ struct timespec t; clock_gettime(CLOCK_REALTIME,&t); while(!stop){ outb(0x0,LPT); timespec_add_ns(&t,PERIOD-duty_cycle); clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &t, NULL); outb(0xff,LPT); timespec_add_ns(&t,duty_cycle); clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &t, NULL); } return (void *)stop;}int get_duty_cycle( char *page, char **start, off_t off, int count, int *eof, void *data){ int size = 0; MOD_INC_USE_COUNT; size+=sprintf(page+size,"Duty Cycle:%d %%\n",(int)duty_cycle/DC_SCALAR); MOD_DEC_USE_COUNT; return(size);}static int set_duty_cycle( struct file *file, const char *user_buffer, unsigned long count, void *data){ MOD_INC_USE_COUNT; duty_cycle=simple_atoi(user_buffer)*DC_SCALAR; printk("duty_cylce set to %ld\n",duty_cycle); MOD_DEC_USE_COUNT; return count;}int init_module(void){ proc_pwm_duty_cycle = create_proc_entry("pwm_duty_cycle", S_IFREG | S_IWUSR, &proc_root); proc_pwm_duty_cycle->read_proc = get_duty_cycle; proc_pwm_duty_cycle->write_proc = set_duty_cycle; if(pthread_create(&pwm_thread,NULL,pwm_code,NULL)) { printk("Pthread_create failed\n"); return -1; } return 0;}void cleanup_module(void){ stop = 1; pthread_join(pwm_thread,NULL); remove_proc_entry("thread_status", &proc_root);}int simple_atoi(const char * number){ int i; int retval=0; int len = strnlen(number,MAXLEN); /* should always do sanity checks on data passed via /proc */ if(len>MAXLEN){ return MIN_DUTY_CYCLE; }else{ /* striped down atoi */ for(i=0;i<len;i++){ if(number[i]<='9' && number[i]>='0'){ retval*=10; retval+=number[i]-'0'; } } /* bounds check on requested duty cycle */ if(retval > MAX_DUTY_CYCLE){ rtl_printf("Warning duty cycle requested was out of bounds\n"); return MAX_DUTY_CYCLE; } else if(retval < MIN_DUTY_CYCLE){ rtl_printf("Warning duty cycle requested was out of bounds\n"); return MIN_DUTY_CYCLE; } else return retval; }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -