shark_task.c 2.3 KB

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