task.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #include "libs/task.h"
  2. #include "hal/hal.h"
  3. #include "bsp/bsp.h"
  4. static u64 task_mseconds;
  5. static task_t _task_handler[MAX_TASK];
  6. static u32 timer_task_handler(void);
  7. static timer_t timer_head = {
  8. .prev = &timer_head,
  9. .next = &timer_head
  10. };
  11. static task_t task_head = {
  12. .next = &task_head,
  13. .handler = timer_task_handler
  14. };
  15. void system_tick_handler(void)
  16. {
  17. task_mseconds++;
  18. }
  19. u64 get_mseconds(void)
  20. {
  21. return task_mseconds;
  22. }
  23. u32 get_seconds(void){
  24. return task_mseconds/1000;
  25. }
  26. void task_ticks_enable(void)
  27. {
  28. CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
  29. DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
  30. }
  31. u32 task_ticks_abs(void)
  32. {
  33. return DWT->CYCCNT;
  34. }
  35. u32 task_ticks_rel(u32 start)
  36. {
  37. u32 ticks = DWT->CYCCNT;
  38. if (ticks >= start) {
  39. return ticks - start;
  40. }
  41. return 0xFFFFFFFF - start + ticks + 1;
  42. }
  43. void task_ticks_delay(u32 ticks)
  44. {
  45. u32 start;
  46. start = task_ticks_abs();
  47. while (task_ticks_rel(start) < ticks);
  48. }
  49. void task_udelay(u32 delay)
  50. {
  51. task_ticks_delay(delay * (SystemCoreClock / 1000000));
  52. }
  53. static inline void timer_sync(void)
  54. {
  55. task_head.time = timer_head.next->time;
  56. }
  57. void timer_post(timer_t *timer, u32 delay)
  58. {
  59. timer_t *node;
  60. u64 time;
  61. __disable_irq();
  62. time = task_mseconds + (delay > 0 ? delay : 1);
  63. if (timer->prev != NULL) {
  64. timer->prev->next = timer->next;
  65. }
  66. if (timer->next != NULL) {
  67. timer->next->prev = timer->prev;
  68. }
  69. for (node = timer_head.next; node != &timer_head; node = node->next) {
  70. if (node->time > time) {
  71. break;
  72. }
  73. }
  74. timer->prev = node->prev;
  75. node->prev->next = timer;
  76. node->prev = timer;
  77. timer->next = node;
  78. timer->time = time;
  79. timer_sync();
  80. __enable_irq();
  81. }
  82. void timer_cancel(timer_t *timer)
  83. {
  84. __disable_irq();
  85. if (timer->prev != NULL && timer->next != NULL) {
  86. timer->prev->next = timer->next;
  87. timer->next->prev = timer->prev;
  88. }
  89. timer->next = timer->prev = timer;
  90. timer_sync();
  91. __enable_irq();
  92. }
  93. static u32 timer_task_handler(void)
  94. {
  95. while (1) {
  96. timer_t *timer = timer_head.next;
  97. if (timer->time > task_mseconds) {
  98. return timer->time - task_mseconds;
  99. }
  100. if (timer != &timer_head) {
  101. timer_cancel(timer);
  102. timer->handler(timer);
  103. } else {
  104. break;
  105. }
  106. wdog_reload();
  107. }
  108. return 0xFFFFFFFF;
  109. }
  110. void task_add(task_t *task)
  111. {
  112. __disable_irq();
  113. task->next = task_head.next;
  114. task_head.next = task;
  115. __enable_irq();
  116. }
  117. task_t* task_start(task_func func, u32 delay){
  118. task_t *task = NULL;
  119. for (int i = 0; i < MAX_TASK; i++) {
  120. __disable_irq();
  121. if (_task_handler[i].handler == NULL) {
  122. task = _task_handler + i;
  123. task->handler = func;
  124. task->time = delay;
  125. task->next = task_head.next;
  126. task_head.next = task;
  127. __enable_irq();
  128. return task;
  129. }
  130. __enable_irq();
  131. }
  132. return NULL;
  133. }
  134. void task_run(void)
  135. {
  136. task_t *head = &task_head;
  137. while (1) {
  138. wdog_reload();
  139. if (head->time <= task_mseconds) {
  140. head->time = task_mseconds + head->handler();
  141. }
  142. head = head->next;
  143. }
  144. }