From 2dc2d790a325747920dfe8cabde3c1d69ff23bb8 Mon Sep 17 00:00:00 2001 From: YuzukiTsuru Date: Thu, 11 Jan 2024 21:49:18 +0800 Subject: [PATCH] [syterkit] add basic timer support --- include/os.h | 53 ++++++++++++++++++++++++++ src/CMakeLists.txt | 3 ++ src/os.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 include/os.h create mode 100644 src/os.c diff --git a/include/os.h b/include/os.h new file mode 100644 index 00000000..c3a360e0 --- /dev/null +++ b/include/os.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef __OS_H__ +#define __OS_H__ + +#include +#include +#include +#include + +#include + +#define TIMER_ALWAYS_RUN 0xFFFFFFFF + +typedef struct task_struct { + void (*callback)(void *arg, uint32_t event); + void *arg; + uint32_t run_count; + uint32_t max_run_count; + uint32_t interval; + uint32_t elapsed_time; + struct task_struct *next; +} task_t; + +typedef struct timer_struct { + task_t task; + uint32_t interval; +} timer_t; + +/** + @brief Create a timer. + @param timer A pointer to a timer_t object to save the newly created timer. + @param callback A pointer to the function that will be called when the timer times out. + @param arg A void pointer used to pass arguments to the callback function. +*/ +void timer_create(timer_t *timer, void (*callback)(void *arg, uint32_t event), void *arg); + + +/** + @brief Start a timer. + @param timer A pointer to an already created timer_t object. + @param max_run_count The maximum number of times the timer will run. 0 means it will run indefinitely. + @param interval The time interval of the timer in milliseconds. +*/ + +void timer_start(timer_t *timer, uint32_t max_run_count, uint32_t interval); + +/** + @brief Timer processing function, needs to be called continuously in the main loop to achieve normal operation of the timer. +*/ +void timer_handle(); + +#endif// __OS_H__ \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b3c22d96..ce845bb4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -27,6 +27,9 @@ add_library(SyterKit STATIC image/uimage.c image/zimage.c + # os + os.c + # malloc smalloc.c diff --git a/src/os.c b/src/os.c new file mode 100644 index 00000000..47a23612 --- /dev/null +++ b/src/os.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include + +#include + +#include "os.h" + +static task_t *task_list = NULL; + +// Add a new task to the linked list +static void add_task(task_t *new_task) { + new_task->run_count = 0; // Set the run count of the new task to 0 + new_task->elapsed_time = 0;// Set the elapsed time of the new task to 0 + new_task->next = NULL; // Set the next pointer of the new task to NULL + + // If the task list is empty, set the new task as the head of the list + if (task_list == NULL) { + task_list = new_task; + } else {// Otherwise, traverse the list and append the new task to the end + task_t *cur_task = task_list; + while (cur_task->next != NULL) { + cur_task = cur_task->next; + } + cur_task->next = new_task; + } +} + +// Remove a given task from the linked list +static void remove_task(task_t *task) { + task_t *cur_task = task_list;// Initialize a current task pointer to the head of the list + task_t *prev_task = NULL; // Initialize a previous task pointer to NULL + + // Traverse the list to find the task to be removed + while (cur_task != NULL) { + if (cur_task == task) { + // If the task is the head, set the next task as the new head + if (prev_task == NULL) { + task_list = cur_task->next; + } else {// Otherwise, remove the task by connecting the previous and next tasks + prev_task->next = cur_task->next; + } + break; + } + + prev_task = cur_task; + cur_task = cur_task->next; + } +} + +// Loop through all tasks in the linked list and execute them if needed +static void task_loop() { + task_t *cur_task = task_list;// Initialize a current task pointer to the head of the list + + while (cur_task != NULL) { + cur_task->elapsed_time += 1;// Increment the elapsed time of the current task by 1 (assuming a timeout of 1 unit) + + if (cur_task->elapsed_time >= cur_task->interval) { + cur_task->callback(cur_task->arg, cur_task->run_count);// Execute the callback function of the current task with its arguments + cur_task->elapsed_time = 0; // Reset the elapsed time of the current task to 0 + cur_task->run_count++; // Increment the run count of the current task + + // If the current task has reached its maximum run count and it is not set to always run, remove it from the list + if (cur_task->run_count >= cur_task->max_run_count && cur_task->max_run_count != TIMER_ALWAYS_RUN) { + remove_task(cur_task); + } + } + + cur_task = cur_task->next;// Move to the next task in the list + } +} + +// Create a timer with the given callback function and argument +void timer_create(timer_t *timer, void (*callback)(void *arg, uint32_t event), void *arg) { + timer->task.callback = callback;// Set the callback function of the timer's task to the given callback function + timer->task.arg = arg; // Set the argument of the timer's task to the given argument + timer->task.max_run_count = 0; // Set the maximum run count of the timer's task to 0 (default) + timer->task.interval = 0; // Set the interval of the timer's task to 0 (default) + timer->interval = 0; // Set the interval of the timer to 0 (default) +} + +// Start the timer with the given maximum run count and interval +void timer_start(timer_t *timer, uint32_t max_run_count, uint32_t interval) { + timer->task.max_run_count = max_run_count;// Set the maximum run count of the timer's task to the given maximum run count + timer->task.interval = interval; // Set the interval of the timer's task to the given interval + timer->interval = interval; // Set the interval of the timer to the given interval + add_task(&(timer->task)); // Add the timer's task to the task list +} + +void timer_handle() { + task_loop(); +} \ No newline at end of file