pwm2.c

来自「fsmlabs的real time linux的内核」· C语言 代码 · 共 145 行

C
145
字号
/* 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 + =
减小字号Ctrl + -
显示快捷键?