shark_task.c 2.2 KB

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