Обновлено: 2025. 02. 05
KLite — это встраиваемое ядро операционной системы, написанное личным разработчиком в 2015 году и распространяемое с лицензией MIT.
Целевой аудиторией KLite являются начинающие разработчики встраиваемых систем реального времени (RTOS). Основная цель проекта — сделать RTOS более доступным за счет простоты использования и понимания. Ядро отличается чистым кодом, четкой архитектурой, простыми и удобными интерфейсами функций, отсутствием условной компиляции, легкостью портирования и отсутствием необходимости конфигурации и кастомизации.
Кроме того, KLite считается одним из самых простых и удобных RTOS на рынке.
KLite поддерживает следующие ядра: ARM7, ARM9, ARM11, Cortex-A7, Cortex-M0, Cortex-M3, Cortex-M4, Cortex-M7 и другие.
Примеры платформ включают Allwinner F1C100S, STM32FXXX, NRF528XX и другие. Для получения дополнительной информации обратитесь к примерам реализации.
Для микроконтроллеров на основе архитектуры Cortex-M требуется лишь изменение директив include в файле cpu_tick.c, например, замена на #include "stm32f10x.h"
.
Поскольку KLite не использует условную компиляцию, можно предварительно скомпилировать исходный код ядра в библиотеку kernel.lib и сохранить заголовочный файл kernel.h, что позволяет значительно сократить время повторной компиляции. Рекомендованная форма записи файла main.c приведена ниже:```c // Необходимо включить только этот заголовочный файл #include "kernel.h"
// Инициализация приложения void init(void *arg) { // Здесь выполняется инициализация периферий и драйверов // Создание дополнительных потоков для выполнения различных задач // thread_create(...) }
// Пустой поток, который просто вызывает kernel_idle() void idle(void *arg) { kernel_idle(); }
// Входная точка C-программы void main(void) { static uint8_t heap[HEAP_SIZE]; /* Определение кучи / kernel_init(heap, sizeof(heap)); / Инициализация системы / thread_create(idle, 0, 0); / Создание потока idle / thread_create(init, 0, 0); / Создание потока init / kernel_start(); / Запуск системы */ }
## 3. Основные функции
Основные функции находятся в директории `sources/kernel/`, это самая важная часть KLite.
Чтобы использовать эти функции, достаточно включить заголовочный файл
```c
#include "kernel.h"
heap_addr
— адрес начала динамического выделенияheap_size
— размер динамически выделяемой памятиvoid kernel_start(void);
```Параметры: отсутствуют
Возвращаемое значение: отсутствует
Описание: используется для запуска ядра; в обычных условиях этот метод управления не вернет, перед его вызовом следует создать хотя бы один поток.```
uint32_t kernel_version(void);
Параметры: отсутствуют
Возвращаемое значение: номер версии KLite, где BIT[31:24] — основной номер версии, BIT[23:16] — дополнительный номер версии, а BIT[15:0] — номер сборки
Описание: позволяет получить номер версии KLite
void kernel_idle(void);
Параметры: отсутствуют
Возвращаемое значение: отсутствует
Описание: используется для управления состоянием ядра в режиме ожидания; этот метод не вернет управление. Должен быть создан отдельный поток для его вызова.
uint32_t kernel_idle_time(void);
Параметры: отсутствуют
Возвращаемое значение: время работы системы в состоянии ожидания (миллисекунды)
Описание: позволяет получить общее время работы системы в состоянии ожидания с момента ее запуска; можно использовать вместе с kernel_tick_count()
для вычисления использования процессора.
void kernel_tick(uint32_t time);
Параметры: период тика (миллисекунды)
Возвращаемое значение: отсутствует
Описание: это не API пользователя, а внутренняя функция, вызываемая программой прерываний таймера процессора для обеспечения временной метки системе.Период тикера определяет детализацию функции учета времени системы; для процессоров с низкими тактовыми частотами рекомендуется использовать период 10 мс, а для процессоров с высокими тактовыми частотами — 1 мс.> Здесь время тика конвертируется в миллисекунды, чтобы приложение не использовало макросы для преобразования единиц измерения, что упрощает вызов.
Если аппаратный таймер не может генерировать тактовый сигнал с периодом 1 мс, например RTC = 32768 Гц, а только прерывание с частотой 1024 Гц и периодом 0,976 мс, это становится проблемой!
Вариант 1: программная коррекция ошибки путем пропуска равномерно распределенных 24 прерываний за 1024 периода.
Вариант 2: установка периода прерывания в 125 мс — минимальное целое значение времени, которое можно получить при частоте 32768 Гц.
Вариант 3: отказ от использования миллисекунд как единицы измерения времени и использование количества тиков вместо этого.```markdown
uint32_t kernel_tick_count(void); Параметры: нет Возвращаемое значение: общее время работы ядра (в миллисекундах) Описание: эта функция позволяет получить общее время работы ядра с момента его запуска
uint64_t kernel_tick_count64(void); Параметры: нет Возвращаемое значение: 64-битное общее время работы ядра (в миллисекундах) Описание: эта функция позволяет получить общее время работы ядра с момента его запуска
addr
— начальный адрес создаваемого блока памяти
size
— размер блока памяти
Возвращаемое значение: объект управления памятью; если выделение памяти завершилось неудачей, то возвращается NULL
Описание: создаёт блок памяти для динамического управления памятью в указанной области памяти
Для повышения стабильности и производительности системы рекомендуется создавать отдельные блоки памяти для различных модулей.
+ void *heap_alloc(heap_t heap, uint32_t size);
Параметры:
`heap` — объект управления памятью (если передан `NULL`, используется системный дефолтный блок памяти)
`size` — размер выделяемой памяти
Возвращаемое значение: указатель на выделенную память; если выделение памяти завершилось неудачей, то возвращается `NULL`
Описание: выделяет непрерывный блок памяти из пула памяти, аналогично функции стандартной библиотеки `malloc()`.
> По сути, следует проверять возвращаемое значение этой функции на `NULL`. Однако каждый раз при каждом вызове `heap_alloc` требуется проверка возвращаемого значения, что может быть сложным или легко забытым. Поэтому перед тем как вернуть `NULL`, эта функция вызывает функцию-обёртку `void heap_fault(void)` для обработки ошибки. В случае отказа выделения памяти для встраиваемых систем это серьёзная ошибка, поэтому мы можем использовать эту функцию для унифицированной обработки ошибок.
```markdown
+ void heap_free(heap_t heap, void *mem);
Параметры:
`heap` — объект кучи
`mem` — указатель на память, которую требуется освободить
Возвращаемое значение: отсутствует
Описание: освобождает память, выделенную с помощью `heap_malloc()`, аналогично функции стандартной библиотеки `free()`
```markdown
+ void heap_usage(heap_t heap, uint32_t *used, uint32_t *free);
Параметры:
`heap` — объект кучи
`used` — количество использованной памяти в байтах, этот параметр может быть равен `NULL`
``` `free` — количество свободной памяти в байтах; этот параметр может быть равен `NULL`.
Возвращаемое значение: отсутствует.
Описание: получает информацию о количестве используемой памяти, что позволяет контролировать использование системной памяти и корректно регулировать её распределение.
________________________________________________________________________________### 3.3 Управление потоками
+ thread_t thread_create(void (*entry)(void*), void *arg, uint32_t stack_size);
Параметры:
`entry` — входная функция потока
`arg` — аргумент входной функции потока
`stack_size` — размер стека потока в байтах, если равен нулю, используется значение по умолчанию системы (1024 байт)
Возвращаемое значение: при успешном выполнении возвращает дескриптор потока, при ошибке возвращает `NULL`
Описание: создаёт новый поток и добавляет его в очередь готовых к выполнению потоков
> Система автоматически выделяет память и пространство стека для нового потока; если размер стека слишком мал, это может привести к переполнению стека во время выполнения
________________________________________________________________________________
+ void thread_delete(thread_t thread);
Параметры:
`thread` — идентификатор потока, который требуется удалить
Возвращаемое значение: отсутствует
Описание: удаляет поток и освобождает память. Этот метод нельзя использовать для завершения текущего потока; для этого следует использовать `thread_exit()` или просто вернуться из основного цикла
> Недопустимо удалять поток напрямую, так как это может вызвать нестабильность системы, особенно если удалённый поток находится в критической секции и не успел её освободить
________________________________________________________________________________+ void thread_set_priority(thread_t thread, uint32_t prio);
Параметры:
`thread` — идентификатор потока
`prio` — новая приоритетная метка
> `THREAD_PRIORITY_HIGHEST` — самый высокий приоритет
> `THREAD_PRIORITY_HIGHER` — более высокий приоритет
> `THREAD_PRIORITY_HIGH` — высокий приоритет
> `THREAD_PRIORITY_NORMAL` — нормальный приоритет
> `THREAD_PRIORITY_LOW` — низкий приоритет
> `THREAD_PRIORITY_LOWER` — более низкий приоритет
> `THREAD_PRIORITY_LOWEST` — самый низкий приоритет
> `THREAD_PRIORITY_IDLE` — приоритет "ждущий"
Возвращаемое значение: отсутствует
Описание: перезапускает приоритет потока, изменения вступают в силу немедленно
________________________________________________________________________________________________________________________________________________________________
+ uint32_t thread_get_priority(thread_t thread);
Параметры: `thread` — идентификатор потока
Возвращаемое значение: приоритет указанного потока
Описание: получает приоритет заданного потока
_________________________________________________________________________________________________________
+ thread_t thread_self(void);
Параметры: отсутствуют
Возвращаемое значение: идентификатор вызывающего потока
Описание: используется для получения идентификатора текущего потока
_________________________________________________________________________________________________________
+ void thread_sleep(uint32_t time);
Параметры: `time` — время сна (миллисекунды)
Возвращаемое значение: отсутствует
Описание: помещает текущий поток в состояние сна на некоторое время, освобождает управление процессором
__________________________________________________________________________________
+ void thread_yield(void);
Параметры: отсутствуют
Возвращаемое значение: отсутствует
Описание: заставляет текущий поток немедленно освободить управление процессором и войти в очередь готовых потоков
__________________________________________________________________________________
+ void thread_exit(void);
Параметры: отсутствуют
Возвращаемое значение: отсутствует
Описание: завершает текущий поток; этот метод не освобождает память, занятую потоком сразу после выполнения, а лишь позволяет системе освободить её в удобное время
__________________________________________________________________________________
+ ~~void thread_suspend(void);~~
+ ~~void thread_resume(thread_t thread);~~
> Поскольку прямое приостановление других потоков является опасной операцией, эти две функции были удалены. Рекомендуется использовать семафоры для блокировки потока, чтобы достичь эффекта приостановки и пробуждения потока.
> Именно поэтому стандарт C11 и POSIX не определяют интерфейсы для приостановки и восстановления потока.
__________________________________________________________________________________
+ uint32_t thread_time(thread_t thread)
Параметры: `thread` — идентификатор потока
Возвращаемое значение: время работы указанного потока (миллисекунды)
Описание: получает время, затраченное потоком на использование процессора с момента его создания, время сна не учитывается.
> Можно использовать эту функцию для мониторинга использования процессора указанным потоком
### 3.4 Мьютекс
__________________________________________________________________________________
+ mutex_t mutex_create(void)
Параметры: отсутствуют
Возвращаемое значение: успешное создание возвращает идентификатор мьютекса, ошибочное создание возвращает `NULL`
Описание: создаёт объект мьютекса, поддерживающий рекурсивное блокирование
__________________________________________________________________________________
+ void mutex_delete(mutex_t mutex)
Параметры: `mutex` — идентификатор удаляемого мьютекса
Возвращаемое значение: отсутствует
Описание: Удаляет мьютекс и освобождает выделенную память
> Примечание: при удалении мьютекса ожидающие его потоки **не** будут разблокированы; поэтому перед удалением убедитесь, что нет активных потоков, использующих этот мьютекс.---
+ void mutex_lock(mutex_t mutex)
Параметры: `mutex` — идентификатор мьютекса
Возвращаемое значение: Нет
Описание: Отмечает мьютекс с указанным идентификатором как заблокированный. Если мьютекс уже заблокирован другим потоком, вызывающий поток будет заблокирован до тех пор, пока другой поток не разблокирует мьютекс.
> Ссылки:
> C11: https://cloud.tencent.com/developer/section/1009716
> POSIX: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_lock.html
---
+ bool mutex_try_lock(mutex_t mutex)
Параметры: `mutex` — идентификатор мьютекса
Возвращаемое значение: Возвращает `true`, если блокировка успешна, в противном случае — `false`.
Описание: Эта функция является неблокирующей версией `mutex_lock`.
> Ссылки:
> C11: https://cloud.tencent.com/developer/section/1009721
> POSIX: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_trylock.html
---
+ void mutex_unlock(mutex_t mutex)
Параметры: `mutex` — идентификатор мьютекса
Возвращаемое значение: Нет
Описание: Разблокирует мьютекс с указанным идентификатором. Если есть ожидающие потоки, то самый приоритетный поток будет разблокирован.
> Ссылки:
> C11: https://cloud.tencent.com/developer/section/1009722
> POSIX: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_unlock.html
### 3.5 Сигналы
---
+ sema_t sema_create(uint32_t value)
Параметры: `value` — начальное значение семафора
Возвращаемое значение: Возвращает идентификатор семафора при успехе, в противном случае — `NULL`.
Описание: Создает объект семафора
> Ссылки:
> POSIX: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_init.html
> WIN32: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createsemaphorea---
+ void sema_delete(sema_t sem)
Параметры: `sem` — идентификатор семафора
Возвращаемое значение: Нет
Описание: Удаление объекта возможно только при условии освобождения занимаемой им памяти, если нет активных потоков, использующих его; в противном случае могут возникнуть непредвиденные ошибки
_____________________________________________________________________________________
+ void sema_post(sema_t sem)
Параметры: `sem` — идентификатор семафора
Возвращаемое значение: Нет
Описание: Увеличивает счетчик значений семафора на единицу. Если есть ожидающие потоки, данный метод пробуждает поток с наибольшим приоритетом
> Ссылка:
> POSIX: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_post.html
> WIN32: https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-releasesemaphore
_____________________________________________________________________________________
+ void sema_wait(sema_t sem)
Параметры: `sem` — идентификатор семафора
Возвращаемое значение: Нет
Описание: Ожидание семафора, уменьшение значения счетчика семафора на единицу. Если текущее значение счетчика семафора равно нулю, поток блокируется до тех пор, пока значение счетчика не станет больше нуля
> Ссылка:
> POSIX: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_wait.html
> WIN32: https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject
_____________________________________________________________________________________
+ uint32_t sema_timed_wait(sema_t sem, uint32_t timeout)
Параметры: `sem` — идентификатор семафора
Параметры: `timeout` — время ожидания (в миллисекундах) Возвращаемое значение: Время, оставшееся до истечения времени ожидания; если возврат равен нулю, это указывает на то, что время ожидания истекло
Описание: Ожидание семафора с таймаутом, уменьшение значения счетчика семафора на единицу. Если текущее значение счетчика семафора равно нулю, поток блокируется до тех пор, пока значение счетчика не станет больше нуля, либо до истечения времени, указанного параметром `timeout`.
> Ссылка:
> POSIX: <https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_timedwait.html>
> WIN32: <https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject>
________________________________________________________________________________
+ uint32_t sema_value(sema_t sem)
Параметры: `sem` — идентификатор семафора
Возвращаемое значение: Значение счетчика семафора
Описание: Возвращает значение счетчика семафора
> Ссылка:
> POSIX: <https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_getvalue.html>
### 3. 6 Условные переменные
________________________________________________________________________________
+ cond_t cond_create(void)
Параметры: Нет
Возвращаемое значение: При успешном выполнении возвращает идентификатор условной переменной, при неудаче возвращает `NULL`
Описание: Создание объекта условной переменной
_________________________________________________________
+ void cond_delete(cond_t cond)
Параметры: `cond` — идентификатор условной переменной
Возвращаемое значение: отсутствует
Описание: Удаление условной переменной
_________________________________________________________
+ void cond_signal(cond_t cond) Параметры: `cond` — идентификатор условной переменной
Возвращаемое значение: отсутствует
Описание: пробуждает один поток, заблокированный условной переменной; если нет заблокированных потоков, то ничего не происходит
> Ссылка:
> C11: https://cloud.tencent.com/developer/section/1009711
> POSIX: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_signal.html
_________________________________________________________
+ void cond_broadcast(cond_t cond);
Параметры: `cond` — идентификатор условной переменной
Возвращаемое значение: отсутствует
Описание: пробуждает все потоки, заблокированные условной переменной; если нет заблокированных потоков, то ничего не происходит
> Ссылка:
> C11: https://cloud.tencent.com/developer/section/1009708
> POSIX: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_broadcast.html
_________________________________________________________
+ void cond_wait(cond_t cond, mutex_t mutex);
Параметры: `cond` — идентификатор условной переменной
Параметры: `mutex` — идентификатор мьютекса
Возвращаемое значение: отсутствует
Описание: блокирует поток и ожидает его пробуждения условной переменной
> Ссылка:
> C11: https://cloud.tencent.com/developer/section/1009713
> POSIX: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_wait.html
_________________________________________________________
+ uint32_t cond_timed_wait(cond_t cond, mutex_t mutex, uint32_t timeout);
Параметры: `cond` — идентификатор условной переменной
Параметры: `mutex` — идентификатор мьютекса
Параметры: `timeout` — время ожидания в миллисекундах
Возвращаемое значение: оставшееся время ожидания; если возврат равен нулю, это указывает на превышение времени ожидания
Функционал: временная блокировка потока и ожидание его пробуждения условной переменной
> Ссылка:
> C11: https://cloud.tencent.com/developer/section/1009712
> POSIX: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_timedwait.html
### 3. 7 Событие
_________________________________________________________
+ event_t event_create(bool auto_reset);
Параметры: `auto_reset` — автоматическое сбросовое событие
Возвращает: при успешном создании возвращается идентификатор события, при неудаче — `NULL`
Описание: создает объект события; если `auto_reset` установлено значение `true`, событие автоматически сбрасывается после успешной передачи
> См. также:
> WIN32: https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createeventa
________________________________________________________________________________
+ void event_delete(event_t event);
Аргументы: `event` — идентификатор события
Возвращает: ничего
Описание: удаляет объект события и освобождает память; удаление возможно только тогда, когда нет ни одного потока, использующего его, иначе могут возникнуть непредвиденные ошибки
________________________________________________________________________________
+ void event_set(event_t event);
Аргументы: `event` — идентификатор события
Возвращает: ничего Описание: устанавливает состояние события как активированное и пробуждает все ожидающие потоки; если `auto_reset` равно `true`, пробуждается только первый поток, а затем событие сбрасывается; если `auto_reset` равно `false`, пробуждаются все потоки, и событие остаётся активированным
> См. также:
> WIN32: https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-setevent
________________________________________________________________________________
+ void event_reset(event_t event);
Аргументы: `event` — идентификатор события
Возвращает: ничего
Описание: устанавливает состояние события как сброшенное; этот метод не пробуждает никакие потоки
> См. также:
> WIN32: https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-resetevent
________________________________________________________________________________
+ void event_wait(event_t event);
Аргументы: `event` — идентификатор события
Возвращает: ничего
Описание: ждёт активацию события
> См. также:
> WIN32: https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject
________________________________________________________________________________
+ uint32_t event_timed_wait(event_t event, uint32_t timeout);
Аргументы: `event` — идентификатор события
Аргументы: `timeout` — время ожидания (миллисекунды)
Возвращает: оставшееся время ожидания; если возврат равен 0, это указывает на превышение времени ожидания
Описание: ожидание активации события с временем ожидания; если время ожидания превышено относительно значения `timeout`, ожидание прекращается
> См. также:
> WIN32: https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject_timeoutcom/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject
## Четвертый раздел. Дополнительные возможности
### 4.1 Группы событий```c
#include "event_flags.h"
```
_____________________________________________________________________________________
+ `event_flags_t event_flags_create(void);`
**Параметры:** Нет
**Возвращаемое значение:** В случае успеха возвращает идентификатор группы событий, в противном случае — `NULL`.
**Описание:** Создает объект группы событий.
_____________________________________________________________________________________
+ `void event_flags_delete(event_flags_t event);`
**Параметры:** `event` — идентификатор группы событий.
**Возвращаемое значение:** Нет.
**Описание:** Удаляет объект группы событий и освобождает память. Удаление возможно только если нет ни одного потока, использующего этот объект; в противном случае могут возникнуть непредвиденные ошибки.
_____________________________________________________________________________________
+ `void event_flags_set(event_flags_t event, uint32_t bits);`
**Параметры:** `event` — идентификатор группы событий.
**Возвращаемое значение:** Нет.
**Описание:** Устанавливает указанные биты (`bits`) в группе событий и пробуждает все ожидающие потоки, желающие получить эти биты.
_____________________________________________________________________________________
+ `void event_flags_reset(event_flags_t event, uint32_t bits);`
**Параметры:** `event` — идентификатор группы событий.
**Возвращаемое значение:** Нет.
**Описание:** Сбрасывает указанные биты (`bits`) в группе событий. Этот метод не пробуждает никакие потоки._____________________________________________________________________________________
+ `uint32_t event_flags_wait(event_flags_t event, uint32_t bits, uint32_t ops);`
**Параметры:**
`event` — идентификатор группы событий.
`bits` — биты, которые требуется дождаться.
`ops` — поведение при ожидании битов.
> `EVENT_FLAGS_WAIT_ANY`: Функция немедленно возвращает, когда хотя бы один из битов (`bits`) становится активным;
> `EVENT_FLAGS_WAIT_ALL`: Функция возвращает, только когда все биты (`bits`) становятся активными;
> `EVENT_FLAGS_AUTO_RESET`: При успешном завершении функции автоматически сбрасываются полученные биты.
**Возвращаемое значение:** Активные состояния битов, которые были получены.
**Описание:** Ожидание одного или нескольких битов события._____________________________________________________________________________________
+ `uint32_t event_flags_timed_wait(event_flags_t event, uint32_t bits, uint32_t ops, uint32_t timeout);`
**Параметры:**
`event` — идентификатор группы событий.
`bits` — биты, которые требуется дождаться.
`ops` — поведение при ожидании битов.
`timeout` — время ожидания (миллисекунды).
Возвращает: фактическое состояние флагов
Описание: ждет одно или несколько событий флагов до истечения времени `timeout`.
### 4.2 Программные таймеры
```
#include "soft_timer.h"
```
__________________________________________________________________________
+ `soft_timer_t soft_timer_create(void (*handler)(void *), void *arg);`
Параметры:
`handler` - обратный вызов программы
`arg` - аргумент обратного вызова
Возвращаемое значение: в случае успеха возвращает идентификатор программного таймера, в случае ошибки возвращает `NULL`.
Описание: создает программный таймер.
__________________________________________________________________________
+ `void soft_timer_delete(soft_timer_t timer);`
Параметры:
`timer` - идентификатор таймера
Возвращаемое значение: отсутствует
Описание: удаляет программный таймер.
__________________________________________________________________________
+ `void soft_timer_start(soft_timer_t timer, uint32_t timeout);`
Параметры:
`timer` - идентификатор таймера
Возвращаемое значение: отсутствует
Описание: запускает программный таймер.
__________________________________________________________________________
+ `void soft_timer_stop(soft_timer_t timer);`
Параметры:
`timer` - идентификатор таймера
Возвращаемое значение: отсутствует
Описание: останавливает программный таймер.__________________________________________________________________________
+ void soft_timer_service(void);
Параметры: отсутствуют
Возвращаемое значение: эта функция обычно не возвращает управление.
Описание: обслуживает события программных таймеров.
> Для использования функциональности программных таймеров требуется создание потока пользователя, который будет вызывать эту функцию для выполнения таймеров.
> Цель этого подхода состоит в том, чтобы позволить пользователю контролировать приоритеты потоков и размеры стеков для программных таймеров.
### 4.3 Блоки памяти
```
#include "mpool.h"
```
__________________________________________________________________________
+ mpool_t mpool_create(uint32_t block_size, uint32_t block_count);
Параметры:
`block_size` - размер блока памяти
`block_count` - общее количество блоков памяти
Возвращаемое значение: в случае успеха возвращает идентификатор, в случае ошибки возвращает `NULL`.
Описание: создает буфер памяти.
__________________________________________________________________________
+ void mpool_delete(mpool_t mpool);
Параметры:
`mpool` - идентификатор
Возвращаемое значение: отсутствует
Описание: удаляет буфер памяти.
__________________________________________________________________________
+ void *mpool_alloc(mpool_t mpool);
Параметры:
`mpool` - идентификатор
##### Возврат: при успешной заявке возвращается указатель на память, при неудачной — `NULL`
##### Описание: запрос памяти из пула памяти.```markdown
+ void mpool_free(mpool_t mpool, void *block);
Arguments:
`mpool` — идентификатор пула памяти
`block` — указатель на блок памяти
Returns: nothing
Description: освобождает память, занимаемую блоком памяти в пуле памяти
```### 4.4 Данные очереди
```c
#include "queue.h"
```
```
queue_t queue_create(uint32_t item_size, uint32_t queue_depth);
Аргументы:
`item_size` — размер данных в очереди
`queue_depth` — глубина очереди
Возвращает: при успешном создании возвращается идентификатор, при неудачном — `NULL`
Описание: создаёт очередь данных.
void queue_delete(queue_t queue);
Аргументы:
`queue` — идентификатор
Возвращает: ничего
Описание: удаляет очередь данных.
void queue_clear(queue_t queue);
Аргументы:
`queue` — идентификатор
Возвращает: ничего
Описание: очищает очередь данных.
bool queue_send(queue_t queue, void *item, uint32_t timeout);
Аргументы:
`queue` — идентификатор
`item` — указатель на данные
`timeout` — время ожидания (миллисекунды)
Возвращает: при успехе возвращает `true`, при превышении времени ожидания — `false`
Описание: отправляет данные в очередь.
bool queue_recv(queue_t queue, void *item, uint32_t timeout);
Аргументы:
`queue` — идентификатор
`item` — указатель на данные
`timeout` — время ожидания (миллисекунды)
Возвращает: при успехе возвращает `true`, при превышении времени ожидания — `false`
Описание: получает данные из очереди.
``````markdown
bool queue_peek(queue_t queue, void *item, uint32_t timeout);
Аргументы:
`queue` — идентификатор очереди
`item` — указатель на данные
`timeout` — время ожидания (миллисекунды)
Возвращает: при успехе возвращает `true`, при превышении времени ожидания — `false`
Описание: просматривает данные в очереди, но не извлекает их; следующий вызов peek вернёт ту же самую информацию.
```
Пожалуйста, обратите внимание, что я сохранил исходное форматирование и разметку.### 4. 5 Сообщение почтового ящика
```Сообщения почтового ящика извлекаются в порядке FIFO. Длина извлеченного сообщения совпадает с длиной отправленного сообщения. Если длина входного буфера меньше длины сообщения, то пропускаются части сообщения, выходящие за рамки буфера.
``````markdown
```c
#include "mailbox.h"
```
______________________________________________________________________________________
**mailbox_t mailbox_create(uint32_t size)**
Параметры:
`size` - размер буфера
Возвращает: идентификатор при успешном создании, `NULL` при ошибке
Описание: создание буфера.
______________________________________________________________________________________
**void mailbox_delete(mailbox_t mbox)**
Параметры:
`mbox` - идентификатор
Возвращает: ничего
Описание: удаление буфера.
______________________________________________________________________________________
**void mailbox_clear(mailbox_t mbox)**
Параметры:
`mbox` - идентификатор
Возвращает: ничего
Описание: очистка буфера.
______________________________________________________________________________________
**uint32_t mailbox_post(mailbox_t mbox, void *buf, uint32_t len, uint32_t timeout)**
Параметры:
`mbox` - идентификатор
`buf` - указатель на данные
`len` - длина данных
`timeout` - время ожидания (миллисекунды)
Возвращает: фактическая длина записанных данных
Описание: запись данных указанной длины в буфер.
______________________________________________________________________________________
**uint32_t mailbox_wait(mailbox_t mbox, void *buf, uint32_t len, uint32_t timeout)**
Параметры:
`mbox` - идентификатор
`buf` - указатель на данные
`len` - длина данных
`timeout` - время ожидания (миллисекунды)
Возвращает: фактическая длина считанных данных
Описание: чтение данных указанной длины из буфера.
## 5. Другие функции
Другие функции не связаны непосредственно с операционной системой, но используются как общие функции в реализации.
### **5.1 Общие списки**
```markdown
```c
#include "list.h"
```
``````markdown
## 2 Общий FIFO**
```c
#include "fifo.h"
```
## 6. Программное обеспечение для аппаратуры
Код ядра KLite полностью написан на C. Из-за различий между платформами CPU некоторые функции зависят от целевой платформы CPU. Эти функции могут требовать использования ассемблерного кода для реализации. Код этих функций находится в директории `sources/cpu`.
---
+ **void cpu_sys_init(void)**
Описание: Инициализация функций, связанных с операционной системой, вызывается на этапе `kernel_init()`.
Параметры: Нет
Возвращает: Ничего
---
+ void cpu_sys_start(void);
Описание: Запускает функциональность, связанную с операционной системой, вызывается на этапе `kernel_start()`. Обычно используется для запуска таймера тика и открытия прерываний тикового таймера, использующего аппаратное прерывание таймера. Интервал прерываний обычно составляет 1 мс, но может быть любым другим значением. Внутри сервисного прерывания следует один раз вызвать `kernel_tick(1)`, где аргумент 1 представляет период тика. Если прерывание происходит каждые 10 мс, то аргумент должен быть равен 10.
Параметры: Нет
Возвращаемое значение: Нет
---
+ void cpu_sys_sleep(uint32_t time);
Описание: Предоставляет интерфейс для реализации низкоэнергетического режима сна, вызывается операционной системой при её простоях.
``` Параметры: `time` — максимальное время сна в миллисекундах.
Возвращаемое значение: Нет
________________________________________________________________________________
+ void cpu_enter_critical(void);
Описание: Предоставляет интерфейс для входа в критическую секцию операционной системы; должна поддерживать рекурсивный вызов.
Параметры: Нет
Возвращаемое значение: Нет
________________________________________________________________________________
+ void cpu_leave_critical(void);
Описание: Предоставляет интерфейс для выхода из критической секции операционной системы; должна поддерживать рекурсивный вызов.
Параметры: Нет
Возвращаемое значение: Нет
________________________________________________________________________________
+ void cpu_context_switch(void);
Описание: Предоставляет интерфейс для выполнения переключения контекста потока; должно использовать прерываемый механизм прерываний.
Параметры: Нет
Возвращаемое значение: Нет
________________________________________________________________________________
+ void *cpu_context_init(void *stack_base, uint32_t stack_size, void *entry, void *arg);
Описание: Инициализирует контекст потока.
Параметры:
`stack_base` — указатель на основание стека,
`stack_size` — размер памяти стека,
`entry` — адрес ввода функции потока,
`arg` — аргумент ввода функции потока.
Возвращает новый указатель на стек.
> Для процессора ARM используется стек типа "full descending", поэтому возвращается новый указатель на вершину стека. > В этой функции память стека инициализируется нулями (0xcc), что позволяет отслеживать использование пространства стека потока во время отладки.
> Рекомендуется установить thread_exit в регистр LR, чтобы обеспечить возможность самостоятельного завершения потока; в противном случае требуется явное вызов thread_exit при окончании цикла работы потока.
## 7. Концепция дизайна
Основная идея заключается в использовании распорядителя (sched.c) для управления тремя списками TCB (очередями):
* Список готовых задач (m_ready_list): В данной версии используется 8 списков готовых задач, каждый приоритет соответствует своему списку.
> В ранних версиях для упрощения реализации использовался один двунаправленный отсортированный список, где высокие приоритеты располагались в начале, а низкие — в конце.
> Однако такой подход увеличивает время сортировки пропорционально количеству приоритетов и потоков, что снижает его эффективность.
> Чтобы расширить применимость KLite, был выбран современный метод управления приоритетами и алгоритмы поиска с помощью битовых карт.
> Теоретически это позволяет поддерживать до 32 уровней приоритетов (готовых списков), но после многочисленных рассуждений было решено, что 8 уровней приоритетов достаточно для большинства случаев.
* Список спящих задач (m_sleep_list): Когда поток переходит в состояние сна, он добавляется в этот список.Каждый такт проверяется наличие завершившихся периодов сна и они перемещаются в список готовых задач.
* Список ожидающих задач (m_pend_list): используется для сбора потоков, находящихся в состоянии блокировки.
При необходимости смены потока выбирается поток с самым высоким приоритетом из списка готовых задач, значение sched_tcb_next обновляется новым потоком, и вызывается аппаратный интерфейс для выполнения операции контекстного переключения.
Интерфейс аппаратного переключения cpu_context_switch() приостанавливает указанное прерывание, и в сервисной процедуре этого прерывания происходит переключение потока.
Процесс переключения: текущий контекст сохраняется на стеке текущего потока, и обновляется значение sched_tcb_now->sp, затем из sched_tcb_next->sp извлекается новый контекст, и, наконец, значение sched_tcb_next присваивается sched_tcb_now.
## 8\. Заключение
KLite не предоставляет "все в одном" решение, как это делают **операционные системы Интернета вещей**; она представляет собой лишь ядро многопоточного планировщика,
однако вы можете гибко выбирать свои собственные файловые системы, сетевые протоколы, графический интерфейс и другие более сложные возможности.
Если вы заметили ошибки или у вас есть предложения по улучшению, пожалуйста, присоединяйтесь к QQ-группе (317930646) или отправьте электронное письмо на kerndev@foxmail.com.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )