| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- #include "libs/task.h"
- #include "bsp/bsp.h"
- static u64 task_mseconds;
- static task_t _task_handler[MAX_TASK];
- static u32 timer_task_handler(void);
- static timer_t timer_head = {
- .prev = &timer_head,
- .next = &timer_head
- };
- static task_t task_head = {
- .next = &task_head,
- .handler = timer_task_handler
- };
- void system_tick_handler(void)
- {
- task_mseconds++;
- }
- u64 get_mseconds(void)
- {
- return task_mseconds;
- }
- u32 get_seconds(void){
- return task_mseconds/1000;
- }
- void task_ticks_enable(void)
- {
- CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
- DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
- }
- u32 task_ticks_abs(void)
- {
- return DWT->CYCCNT;
- }
- u32 task_ticks_rel(u32 start)
- {
- u32 ticks = DWT->CYCCNT;
- if (ticks >= start) {
- return ticks - start;
- }
- return 0xFFFFFFFF - start + ticks + 1;
- }
- void task_ticks_delay(u32 ticks)
- {
- u32 start;
- start = task_ticks_abs();
- while (task_ticks_rel(start) < ticks);
- }
- void task_udelay(u32 delay)
- {
- task_ticks_delay(delay * (SystemCoreClock / 1000000));
- }
- static inline void timer_sync(void)
- {
- task_head.time = timer_head.next->time;
- }
- void timer_post(timer_t *timer, u32 delay)
- {
- timer_t *node;
- u64 time;
- __disable_irq();
- time = task_mseconds + (delay > 0 ? delay : 1);
- if (timer->prev != NULL) {
- timer->prev->next = timer->next;
- }
- if (timer->next != NULL) {
- timer->next->prev = timer->prev;
- }
- for (node = timer_head.next; node != &timer_head; node = node->next) {
- if (node->time > time) {
- break;
- }
- }
- timer->prev = node->prev;
- node->prev->next = timer;
- node->prev = timer;
- timer->next = node;
- timer->time = time;
- timer_sync();
- __enable_irq();
- }
- void timer_cancel(timer_t *timer)
- {
- __disable_irq();
- if (timer->prev != NULL && timer->next != NULL) {
- timer->prev->next = timer->next;
- timer->next->prev = timer->prev;
- }
- timer->next = timer->prev = timer;
- timer_sync();
- __enable_irq();
- }
- static u32 timer_task_handler(void)
- {
- while (1) {
- timer_t *timer = timer_head.next;
- if (timer->time > task_mseconds) {
- return timer->time - task_mseconds;
- }
- if (timer != &timer_head) {
- timer_cancel(timer);
- timer->handler(timer);
- } else {
- break;
- }
- wdog_reload();
- }
- return 0xFFFFFFFF;
- }
- void task_add(task_t *task)
- {
- __disable_irq();
- task->next = task_head.next;
- task_head.next = task;
- __enable_irq();
- }
- task_t* task_start(task_func func, u32 delay){
- task_t *task = NULL;
-
- for (int i = 0; i < MAX_TASK; i++) {
- __disable_irq();
- if (_task_handler[i].handler == NULL) {
- task = _task_handler + i;
- task->handler = func;
- task->time = delay;
- task->next = task_head.next;
- task_head.next = task;
- __enable_irq();
- return task;
- }
- __enable_irq();
- }
- return NULL;
- }
- void task_run(void)
- {
- task_t *head = &task_head;
- while (1) {
- wdog_reload();
- if (head->time <= task_mseconds) {
- head->time = task_mseconds + head->handler();
- }
- head = head->next;
- }
- }
|