shark_task.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #include "libs/shark_task.h"
  2. #include "bsp/shark_bsp.h"
  3. static u64 shark_mseconds;
  4. static u32 shark_timer_task_handler(void);
  5. static shark_timer_t shark_timer_head = {
  6. .prev = &shark_timer_head,
  7. .next = &shark_timer_head
  8. };
  9. static shark_task_t shark_task_head = {
  10. .next = &shark_task_head,
  11. .handler = shark_timer_task_handler
  12. };
  13. void SysTick_Handler(void)
  14. {
  15. shark_mseconds++;
  16. }
  17. u64 shark_get_mseconds(void)
  18. {
  19. return shark_mseconds;
  20. }
  21. u32 shark_get_seconds(void){
  22. return shark_mseconds/1000;
  23. }
  24. static inline void shark_timer_sync(void)
  25. {
  26. shark_task_head.time = shark_timer_head.next->time;
  27. }
  28. void shark_timer_post(shark_timer_t *timer, u32 delay)
  29. {
  30. shark_timer_t *node;
  31. u64 time;
  32. __disable_irq();
  33. time = shark_mseconds + (delay > 0 ? delay : 1);
  34. if (timer->prev != NULL) {
  35. timer->prev->next = timer->next;
  36. }
  37. if (timer->next != NULL) {
  38. timer->next->prev = timer->prev;
  39. }
  40. for (node = shark_timer_head.next; node != &shark_timer_head; node = node->next) {
  41. if (node->time > time) {
  42. break;
  43. }
  44. }
  45. timer->prev = node->prev;
  46. node->prev->next = timer;
  47. node->prev = timer;
  48. timer->next = node;
  49. timer->time = time;
  50. shark_timer_sync();
  51. __enable_irq();
  52. }
  53. void shark_timer_cancel(shark_timer_t *timer)
  54. {
  55. __disable_irq();
  56. timer->prev->next = timer->next;
  57. timer->next->prev = timer->prev;
  58. timer->next = timer->prev = timer;
  59. shark_timer_sync();
  60. __enable_irq();
  61. }
  62. static u32 shark_timer_task_handler(void)
  63. {
  64. while (1) {
  65. shark_timer_t *timer = shark_timer_head.next;
  66. if (timer->time > shark_mseconds) {
  67. return timer->time - shark_mseconds;
  68. }
  69. if (timer != &shark_timer_head) {
  70. shark_timer_cancel(timer);
  71. timer->handler(timer);
  72. } else {
  73. break;
  74. }
  75. wdog_reload();
  76. }
  77. return 0xFFFFFFFF;
  78. }
  79. void shark_task_add(shark_task_t *task)
  80. {
  81. __disable_irq();
  82. task->next = shark_task_head.next;
  83. shark_task_head.next = task;
  84. __enable_irq();
  85. }
  86. void shark_task_run(void)
  87. {
  88. shark_task_t *head = &shark_task_head;
  89. /* setup systick timer for 1000Hz interrupts */
  90. SysTick_Config(SystemCoreClock / 1000);
  91. /* configure the systick handler priority */
  92. NVIC_SetPriority(SysTick_IRQn, 0x00U);
  93. while (1) {
  94. wdog_reload();
  95. if (head->time <= shark_mseconds) {
  96. head->time = shark_mseconds + head->handler();
  97. }
  98. head = head->next;
  99. }
  100. }