timer.c 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. #include "os/timer.h"
  2. #include "os/co_task.h"
  3. #include "bsp/bsp.h"
  4. extern u64 g_task_ticks64;
  5. static void timer_task_handler(void *);
  6. static timer_t timer_head = {
  7. .prev = &timer_head,
  8. .next = &timer_head
  9. };
  10. static bool _timer_start = false;
  11. void timer_post(timer_t *timer, u32 delay)
  12. {
  13. timer_t *node;
  14. u64 time = g_task_ticks64 + (delay > 0 ? delay : 1);
  15. __disable_irq();
  16. if (timer->prev != NULL) {
  17. timer->prev->next = timer->next;
  18. }
  19. if (timer->next != NULL) {
  20. timer->next->prev = timer->prev;
  21. }
  22. for (node = timer_head.next; node != &timer_head; node = node->next) {
  23. if (node->time > time) {
  24. break;
  25. }
  26. }
  27. timer->prev = node->prev;
  28. node->prev->next = timer;
  29. node->prev = timer;
  30. timer->next = node;
  31. timer->time = time;
  32. __enable_irq();
  33. if (!_timer_start) {
  34. co_task_create(timer_task_handler, NULL, 384);
  35. _timer_start = true;
  36. }
  37. }
  38. void timer_cancel(timer_t *timer)
  39. {
  40. __disable_irq();
  41. if (timer->prev != NULL && timer->next != NULL) {
  42. timer->prev->next = timer->next;
  43. timer->next->prev = timer->prev;
  44. }
  45. timer->next = timer->prev = timer;
  46. __enable_irq();
  47. }
  48. static void timer_task_handler(void *args)
  49. {
  50. while (1) {
  51. timer_t *timer = timer_head.next;
  52. if (timer->time > g_task_ticks64) {
  53. co_task_delay((u32)(timer->time - g_task_ticks64));
  54. }
  55. if (timer != &timer_head) {
  56. timer_cancel(timer);
  57. timer->handler(timer);
  58. }
  59. co_task_yield();
  60. }
  61. }