protothread 示例之門鎖流程

protothread 用法示例

#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>

#include "pt.h"



static struct pt codelock_pt, input_pt;

static const char code[4] = {'1', '4', '2', '3'};

static char key_pressed_flag;

static char pass_code[4] = {0};
static char pass_code_index;

struct timer {
	int start;
	int interval;
};

static struct timer codelock_timer, input_timer;

static int key_pressed()
{
	if (key_pressed_flag != 0) {
		key_pressed_flag = 0;
		return 1;
	}
	
	return 0;
}


static int clock_time()
{
	struct timeval tv;
	struct timezone tz;
	gettimeofday(&tv, &tz);
	
	return tv.tv_sec * 1000 + tv.tv_usec / 1000; 
}




static void timer_set(struct timer *t, int interval)
{
	t->interval = interval;
	t->start = clock_time();
}



static int timer_expired(struct timer *t)
{
	return (int)(clock_time() - t->start) >= (int)t->interval;
}



static PT_THREAD(codelock_thread(struct pt *pt))
{
	static int keys;
	
	PT_BEGIN(pt);
	
	while(1) {
		
		for (keys=0; keys < sizeof(code); ++keys) {
			
			if (keys == 0)
				PT_WAIT_UNTIL(pt, key_pressed());
			else {
				
				timer_set(&codelock_timer, 1000);	
				PT_WAIT_UNTIL(pt, key_pressed() || timer_expired(&codelock_timer));
				
				if (timer_expired(&codelock_timer)) {
					pass_code_index = 0;
					printf("Code lock timer expired \n");
					break;
				}
			}
		}
		
		if (keys == sizeof(code)) {
			
			printf("Correct code entered, waiting for 500 ms before unlocking \n");
	
			timer_set(&codelock_timer, 500);
			PT_WAIT_UNTIL(pt, key_pressed() || timer_expired(&codelock_timer));
			
			printf("code is: ");
			for (keys=0; keys < sizeof(code); ++keys)
				printf("'%c' ", code[keys]);
			printf("\n");
			
			printf("pass_code is: ");
			for (keys=0; keys < sizeof(code); ++keys)
				printf("'%c' ", pass_code[keys]);
			printf("\n");
			
			if (!timer_expired(&codelock_timer))
				printf("Key pressed during final wait, code lock locked again \n");
			else {
				
				if (memcmp(pass_code, code, sizeof(code)) == 0) {
					
					printf("Code lock unlocked \n");
					PT_EXIT(pt);	
				}
				
				printf("Code error, Try again \n");
				pass_code_index = 0;
			}	
		}
	}
	
	PT_END(pt);
}


static void press_key(char k)
{
	printf("--- Key '%c' pressed \n", k);
	pass_code[pass_code_index] = k;
	pass_code_index = (pass_code_index + 1) % 4;
	key_pressed_flag = 1;
}


static PT_THREAD(input_thread(struct pt *pt))
{
	PT_BEGIN(pt);
	
	printf("Waiting 1 second before entering first key \n");
	
	timer_set(&input_timer, 1000);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('1');
	
	timer_set(&input_timer, 100);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('2');
	
	timer_set(&input_timer, 100);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('3');
	
	
	
	timer_set(&input_timer, 2000);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('1');
	
	
	timer_set(&input_timer, 200);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('4');
	
	
	timer_set(&input_timer, 200);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('2');
	
	timer_set(&input_timer, 2000);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('3');
	
	
	timer_set(&input_timer, 200);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('1');
	
	timer_set(&input_timer, 200);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('4');
	
	timer_set(&input_timer, 200);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('2');
	
	
	timer_set(&input_timer, 100);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('3');
	
	
	timer_set(&input_timer, 100);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('4');
	
	timer_set(&input_timer, 1500);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('1');
	
	timer_set(&input_timer, 300);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('4');
	
	timer_set(&input_timer, 400);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('2');
	
	timer_set(&input_timer, 500);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('8');
	
	timer_set(&input_timer, 2000);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('1');
	
	timer_set(&input_timer, 300);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('4');
	
	timer_set(&input_timer, 400);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('2');
	
	timer_set(&input_timer, 500);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	press_key('3');
	
	timer_set(&input_timer, 2000);
	PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
	
	PT_END(pt);
}






int main()
{
	//初始化 2 個 protothread 的控制結構體
	PT_INIT(&input_pt);
	PT_INIT(&codelock_pt);
	
	//調度 2 個 protothread, 直到 codelock_thread 退出
	while(PT_SCHEDULE(codelock_thread(&codelock_pt))) {
		
		PT_SCHEDULE(input_thread(&input_pt));
		
		usleep(10);
	}
	
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章