X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fcore%2Fao_task.c;h=65654731aeaeaccc9f45477e156ffa1419d13c0b;hb=175380a436efa35bbfae2ee5e29e12e9ef86fbde;hp=910f158785fbf894dc10415d2c8bce5cfdc1352e;hpb=9d3fe2a80d0925e3eded6d738d05c5b4ea61504c;p=fw%2Faltos diff --git a/src/core/ao_task.c b/src/core/ao_task.c index 910f1587..65654731 100644 --- a/src/core/ao_task.c +++ b/src/core/ao_task.c @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include "ao.h" +#include #define AO_NO_TASK_INDEX 0xff @@ -28,6 +28,20 @@ __xdata struct ao_task *__data ao_cur_task; ao_arch_task_globals #endif +#define AO_CHECK_STACK 0 + +#if AO_CHECK_STACK +static uint8_t in_yield; + +static inline void ao_check_stack(void) { + uint8_t q; + if (!in_yield && ao_cur_task && &q < &ao_cur_task->stack[0]) + ao_panic(AO_PANIC_STACK); +} +#else +#define ao_check_stack() +#endif + void ao_add_task(__xdata struct ao_task * task, void (*start)(void), __code char *name) __reentrant { @@ -68,35 +82,39 @@ ao_yield(void) ao_arch_naked_define ao_arch_isr_stack(); +#if AO_CHECK_STACK + in_yield = 1; +#endif /* Find a task to run. If there isn't any runnable task, * this loop will run forever, which is just fine */ { - __pdata uint8_t ao_next_task_index = ao_cur_task_index; + __pdata uint8_t ao_last_task_index = ao_cur_task_index; for (;;) { - ++ao_next_task_index; - if (ao_next_task_index == ao_num_tasks) - ao_next_task_index = 0; + ++ao_cur_task_index; + if (ao_cur_task_index == ao_num_tasks) + ao_cur_task_index = 0; + + ao_cur_task = ao_tasks[ao_cur_task_index]; - ao_cur_task = ao_tasks[ao_next_task_index]; - if (ao_cur_task->wchan == NULL) { - ao_cur_task_index = ao_next_task_index; + /* Check for ready task */ + if (ao_cur_task->wchan == NULL) 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; + (int16_t) (ao_time() - ao_cur_task->alarm) >= 0) break; - } /* Enter lower power mode when there isn't anything to do */ - if (ao_next_task_index == ao_cur_task_index) { + if (ao_cur_task_index == ao_last_task_index) ao_arch_cpu_idle(); - } } } +#if AO_CHECK_STACK + cli(); + in_yield = 0; +#endif ao_arch_restore_stack(); } @@ -107,6 +125,7 @@ ao_sleep(__xdata void *wchan) ao_yield(); if (ao_cur_task->wchan) { ao_cur_task->wchan = NULL; + ao_cur_task->alarm = 0; return 1; } return 0; @@ -117,6 +136,7 @@ ao_wakeup(__xdata void *wchan) { uint8_t i; + ao_check_stack(); for (i = 0; i < ao_num_tasks; i++) if (ao_tasks[i]->wchan == wchan) ao_tasks[i]->wchan = NULL; @@ -138,6 +158,16 @@ ao_clear_alarm(void) ao_cur_task->alarm = 0; } +static __xdata uint8_t ao_forever; + +void +ao_delay(uint16_t ticks) +{ + ao_alarm(ticks); + ao_sleep(&ao_forever); + ao_clear_alarm(); +} + void ao_exit(void) { @@ -155,7 +185,7 @@ ao_exit(void) void ao_task_info(void) { - uint8_t i; + uint8_t i; __xdata struct ao_task *task; for (i = 0; i < ao_num_tasks; i++) {