|
|
@@ -3,6 +3,18 @@
|
|
|
|
|
|
static u64 shark_mseconds;
|
|
|
|
|
|
+static u32 shark_timer_task_handler(void);
|
|
|
+
|
|
|
+static shark_timer_t shark_timer_head = {
|
|
|
+ .prev = &shark_timer_head,
|
|
|
+ .next = &shark_timer_head
|
|
|
+};
|
|
|
+
|
|
|
+static shark_task_t shark_task_head = {
|
|
|
+ .next = &shark_task_head,
|
|
|
+ .handler = shark_timer_task_handler
|
|
|
+};
|
|
|
+
|
|
|
void SysTick_Handler(void)
|
|
|
{
|
|
|
shark_mseconds++;
|
|
|
@@ -13,20 +25,86 @@ u64 shark_get_mseconds(void)
|
|
|
return shark_mseconds;
|
|
|
}
|
|
|
|
|
|
-static u32 shark_task_timer(void)
|
|
|
+static inline void shark_timer_sync(void)
|
|
|
{
|
|
|
- return 1000;
|
|
|
+ shark_task_head.time = shark_timer_head.next->time;
|
|
|
}
|
|
|
|
|
|
-static shark_task_t shark_task_head = {
|
|
|
- .next = &shark_task_head,
|
|
|
- .handler = shark_task_timer
|
|
|
-};
|
|
|
+void shark_timer_post(shark_timer_t *timer, u32 delay)
|
|
|
+{
|
|
|
+ shark_timer_t *node;
|
|
|
+ u64 time;
|
|
|
+
|
|
|
+ __disable_irq();
|
|
|
+
|
|
|
+ time = shark_mseconds + (delay > 0 ? delay : 1);
|
|
|
+
|
|
|
+ if (timer->prev != NULL) {
|
|
|
+ timer->prev->next = timer->next;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (timer->next != NULL) {
|
|
|
+ timer->next->prev = timer->prev;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (node = shark_timer_head.next; node != &shark_timer_head; node = node->next) {
|
|
|
+ if (node->time > time) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ timer->prev = node->prev;
|
|
|
+ node->prev->next = timer;
|
|
|
+ node->prev = timer;
|
|
|
+ timer->next = node;
|
|
|
+ timer->time = time;
|
|
|
+ shark_timer_sync();
|
|
|
+
|
|
|
+ __enable_irq();
|
|
|
+}
|
|
|
+
|
|
|
+void shark_timer_cancel(shark_timer_t *timer)
|
|
|
+{
|
|
|
+ __disable_irq();
|
|
|
+
|
|
|
+ timer->prev->next = timer->next;
|
|
|
+ timer->next->prev = timer->prev;
|
|
|
+ timer->next = timer->prev = timer;
|
|
|
+ shark_timer_sync();
|
|
|
+
|
|
|
+ __enable_irq();
|
|
|
+}
|
|
|
+
|
|
|
+static u32 shark_timer_task_handler(void)
|
|
|
+{
|
|
|
+ while (1) {
|
|
|
+ shark_timer_t *timer = shark_timer_head.next;
|
|
|
+
|
|
|
+ if (timer->time > shark_mseconds) {
|
|
|
+ return timer->time - shark_mseconds;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (timer != &shark_timer_head) {
|
|
|
+ shark_timer_cancel(timer);
|
|
|
+ timer->handler();
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ fwdgt_counter_reload();
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0xFFFFFFFF;
|
|
|
+}
|
|
|
|
|
|
void shark_task_add(shark_task_t *task)
|
|
|
{
|
|
|
+ __disable_irq();
|
|
|
+
|
|
|
task->next = shark_task_head.next;
|
|
|
shark_task_head.next = task;
|
|
|
+
|
|
|
+ __enable_irq();
|
|
|
}
|
|
|
|
|
|
void shark_task_run(void)
|
|
|
@@ -39,14 +117,12 @@ void shark_task_run(void)
|
|
|
NVIC_SetPriority(SysTick_IRQn, 0x00U);
|
|
|
|
|
|
while (1) {
|
|
|
- shark_task_t *next = head->next;
|
|
|
- u64 time = shark_mseconds;
|
|
|
+ fwdgt_counter_reload();
|
|
|
|
|
|
- if (head->time <= time) {
|
|
|
- head->time = time + head->handler();
|
|
|
+ if (head->time <= shark_mseconds) {
|
|
|
+ head->time = shark_mseconds + head->handler();
|
|
|
}
|
|
|
|
|
|
- head = next;
|
|
|
- fwdgt_counter_reload();
|
|
|
+ head = head->next;
|
|
|
}
|
|
|
}
|