shark_task.c 2.4 KB

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