diff options
| -rw-r--r-- | src/ao.h | 13 | ||||
| -rw-r--r-- | src/ao_task.c | 23 | 
2 files changed, 33 insertions, 3 deletions
| @@ -40,6 +40,7 @@  /* An AltOS task */  struct ao_task {  	__xdata void *wchan;		/* current wait channel (NULL if running) */ +	uint16_t alarm;			/* abort ao_sleep time */  	uint8_t	stack_count;		/* amount of saved stack */  	uint8_t task_id;		/* index in the task array */  	__code char *name;		/* task name */ @@ -55,8 +56,12 @@ extern __xdata struct ao_task *__data ao_cur_task;   ao_task.c   */ -/* Suspend the current task until wchan is awoken */ -void +/* Suspend the current task until wchan is awoken. + * returns: + *  0 on normal wake + *  1 on alarm + */ +uint8_t  ao_sleep(__xdata void *wchan);  /* Wake all tasks sleeping on wchan */ @@ -67,6 +72,10 @@ ao_wakeup(__xdata void *wchan);  void  ao_wake_task(__xdata struct ao_task *task); +/* set an alarm to go off in 'delay' ticks */ +void +ao_alarm(uint16_t delay); +  /* Yield the processor to another task */  void  ao_yield(void) _naked; diff --git a/src/ao_task.c b/src/ao_task.c index 136444b0..14aa84c8 100644 --- a/src/ao_task.c +++ b/src/ao_task.c @@ -129,6 +129,13 @@ ao_yield(void) _naked  				break;  			} +			/* Check if the alarm is set for a time which has passed */ +			if (ao_cur_task->alarm && +			    (int16_t) (ao_time() - ao_cur_task->alarm) >= 0) { +				ao_cur_task_index = ao_next_task_index; +				break; +			} +  			/* Enter lower power mode when there isn't anything to do */  			if (ao_next_task_index == ao_cur_task_index)  				PCON = PCON_IDLE; @@ -181,13 +188,20 @@ ao_yield(void) _naked  	_endasm;  } -void +uint8_t  ao_sleep(__xdata void *wchan)  {  	__critical {  		ao_cur_task->wchan = wchan;  	}  	ao_yield(); +	if (ao_cur_task->wchan) { +		ao_cur_task->wchan = NULL; +		ao_cur_task->alarm = 0; +		return 1; +	} +	ao_cur_task->alarm = 0; +	return 0;  }  void @@ -201,6 +215,13 @@ ao_wakeup(__xdata void *wchan)  }  void +ao_alarm(uint16_t delay) +{ +	if (!(ao_cur_task->alarm = ao_time() + delay)) +		ao_cur_task->alarm = 1; +} + +void  ao_wake_task(__xdata struct ao_task *task)  {  	task->wchan = NULL; | 
