Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
tinyos-rtos — Ультралегковесная ОСРВ для Интернета вещей с вытесняющим планированием, поддержкой TLS/DTLS, MQTT, CoAP, совместимостью с POSIX и защитой памяти на основе MPU. Ядро — менее 10 КБ. | Kitploit
Инструменты/GitHubGitHub/cmc-labo/tinyos-rtos
Безопасность встроенных системБезопасность IoTСетевая безопасностьАппаратный ХакингКриптографияАппаратная БезопасностьАнализ Прошивок
GitHubcmc-labo/tinyos-rtos

tinyos-rtos

Ультралегковесная ОСРВ для Интернета вещей с вытесняющим планированием, поддержкой TLS/DTLS, MQTT, CoAP, совместимостью с POSIX и защитой памяти на основе MPU. Ядро — менее 10 КБ.

Репозиторий
23583 месяцев назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

TinyOS — сверхлегкая ОСРВ для Интернета вещей

Сверхлегкая операционная система реального времени для устройств Интернета вещей и встраиваемых систем с ограниченными ресурсами.
Размер ядра менее 10 КБ, минимум 2 КБ ОЗУ, вытесняющее планирование на основе приоритетов.


Возможности

КатегорияДетали
ЯдроВытесняющее планирование на основе приоритетов (256 уровней), циклическое планирование для одного приоритета, поиск приоритета O(1) через битовую маску, наследование приоритета
СинхронизацияМьютекс (с наследованием приоритета), семафор, условная переменная, группы событий, очереди сообщений
Программные таймерыОдноразовые и с автоперезагрузкой, точность до миллисекунды, изменение периода во время выполнения
ПамятьАллокатор first-fit с немедленной коалесценцией (8 КБ кучи, выравнивание по 8 байт), обнаружение переполнения стека, метка максимального использования для каждой задачи
ОболочкаИнтерактивная оболочка VT100 — 23 встроенные команды, история команд (↑↓), автодополнение по табуляции, полноценный редактор строки
Совместимость с POSIXpthreads (create/join/detach/exit, мьютекс, условная переменная) · BSD socket API (socket/bind/listen/accept/connect/send/recv, inet_pton/ntop, htons/htonl)
Файловая системаЖурналируемая ФС на блочных устройствах (WAL, восстановление после сбоя), совместное использование блоков COW, атомарные снимки, API, подобный POSIX
СетьEthernet, IPv4, ICMP, UDP, TCP, HTTP клиент/сервер, DNS
TLS / DTLSTLS 1.2/1.3 через TCP, DTLS 1.2 через UDP (бэкенд mbedTLS)
MQTTПолный MQTT 3.1.1 — QoS 0/1/2 с таблицей повторных попыток в полёте, офлайн-очередь, автоматическое переподключение с экспоненциальной отсрочкой
CoAPКлиент/сервер, совместимый с RFC 7252, шаблон observe
OTAОбновления прошивки с разделами A/B, проверка CRC32, откат
Сторожевой таймерАппаратный и программный сторожевой таймер, мониторинг тайм-аута для каждой задачи
ЭнергопитаниеРежимы бездействия / сна / глубокого сна, безтиковое бездействие, масштабирование частоты ЦП
БезопасностьЗащита памяти на основе MPU, поддержка безопасной загрузки
HALУниверсальный уровень аппаратной абстракции — ARM Cortex-M / RISC-V / AVR; выбор архитектуры на этапе компиляции, таблицы операций периферии

Поддерживаемое оборудование

АрхитектураПримеры
ARM Cortex-M (M0/M0+/M3/M4/M7)STM32, nRF52, Raspberry Pi Pico
RISC-V (RV32I)ESP32-C3
AVR (экспериментально)ATmega

Быстрый старт

Предварительные требования```bash

ARM cross-compiler (required)

sudo apt-get install -y gcc-arm-none-eabi binutils-arm-none-eabi

QEMU ARM emulator (optional — for running without hardware)

sudo apt-get install -y qemu-system

root@kitploit:~
Проверьте установку:```bash
arm-none-eabi-gcc --version   # 10.x or later
qemu-system-arm --version     # 6.x or later

Сборка```bash

Default example (blink_led) — ARM Cortex-M4

make

Target a different architecture (auto-selects toolchain and HAL)

make ARCH=cortex-m0 # Cortex-M0/M0+ make ARCH=cortex-m7 # Cortex-M7 make ARCH=riscv32 # RISC-V RV32I (uses riscv32-unknown-elf-gcc) make ARCH=avr5 # AVR ATmega (uses avr-gcc)

Specific example

make EXAMPLE=blink_led # LED blink + task scheduler demo make EXAMPLE=event_groups # Event group AND/OR/NOT/SYNC demo make EXAMPLE=iot_sensor # Multi-sensor IoT node make EXAMPLE=shell_demo # Interactive UART shell make EXAMPLE=mqtt_demo # MQTT publish/subscribe make EXAMPLE=condition_variable # Producer/consumer

Convenience aliases

make example-blink make example-events make example-shell make example-mqtt make example-iot

Build output

make size # Print ROM/RAM usage

root@kitploit:~
Build artifacts are placed in `build/`:

| File | Описание |
|---|---|
| `build/tinyos.elf` | ELF-образ с отладочными символами |
| `build/tinyos.bin` | Сырой бинарный файл для прошивки |
| `build/tinyos.map` | Карта компоновщика (размеры символов) |

### Запуск на QEMU

TinyOS работает на QEMU-цели `mps2-an385` (ARM Cortex-M3, 4 МБ флеш-памяти, 4 МБ ОЗУ):```bash
# Run indefinitely (Ctrl-A X to quit)
qemu-system-arm \
    -machine mps2-an385 \
    -cpu cortex-m3 \
    -nographic \
    -kernel build/tinyos.elf

# Run for a fixed duration (e.g. 10 seconds)
timeout 10 qemu-system-arm \
    -machine mps2-an385 \
    -cpu cortex-m3 \
    -nographic \
    -kernel build/tinyos.elf

# Debug: trace interrupts
qemu-system-arm \
    -machine mps2-an385 \
    -cpu cortex-m3 \
    -nographic \
    -d int \
    -kernel build/tinyos.elf

Ожидаемый вывод из трассировки прерываний: повторяющиеся строки successful exception return подтверждают, что планировщик работает, SysTick тикает, и переключения контекста PendSV выполняются корректно.

Прошивка на устройство```bash

OpenOCD (STM32 example)

openocd -f interface/stlink.cfg -f target/stm32f4x.cfg
-c "program build/tinyos.bin verify reset exit 0x08000000"

pyOCD (generic ARM Cortex-M)

pyocd flash --target cortex_m build/tinyos.bin

root@kitploit:~
### Сборка с TLS (mbedTLS)

Поддержка TLS включается автоматически, когда mbedTLS находится в `~/mbedtls`.
Чтобы использовать другой путь:```bash
# Clone and build mbedTLS
git clone https://github.com/Mbed-TLS/mbedtls ~/mbedtls
make -C ~/mbedtls

# Build TinyOS with TLS
make MBEDTLS_DIR=~/mbedtls

Минимальный пример задачи:```c #include "tinyos.h"

void my_task(void param) { while (1) { / work */ os_task_delay_ms(100); } }

int main(void) { tcb_t task; os_init(); os_task_create(&task, "my_task", my_task, NULL, PRIORITY_NORMAL); os_start(); }

root@kitploit:~
---

## Обзор API

### Управление задачами```c
os_task_create(tcb, name, entry, param, priority)
os_task_delete(task)
os_task_suspend(task) / os_task_resume(task)
os_task_delay(ticks) / os_task_delay_ms(ms)
os_task_set_priority(task, priority)
os_task_get_stats(task, stats)
os_task_get_stats_by_index(index, stats)   /* iterate all tasks by index */
os_task_find_by_name(name)                 /* returns tcb_t*, NULL if not found */
os_get_system_stats(stats)
os_get_memory_stats(&free, &used, &allocs, &frees)

Синхронизация```c

os_mutex_init(mutex) / os_mutex_lock(mutex, timeout) / os_mutex_unlock(mutex) os_semaphore_init(sem, count) / os_semaphore_wait(sem, timeout) / os_semaphore_post(sem) os_cond_init(cond) / os_cond_wait(cond, mutex, timeout) os_cond_signal(cond) / os_cond_broadcast(cond) os_event_group_set_bits(eg, bits) / os_event_group_wait_bits(eg, bits, opts, out, timeout) os_queue_init(q, buf, item_size, max) / os_queue_send(q, item, timeout) os_queue_receive(q, item, timeout) / os_queue_peek(q, item, timeout)

root@kitploit:~
### Таймеры```c
os_timer_create(timer, name, type, period_ms, callback, param)
os_timer_start(timer) / os_timer_stop(timer) / os_timer_reset(timer)
os_timer_change_period(timer, ms) / os_timer_get_remaining_ms(timer)

Оболочка```c

/* Register custom commands before calling shell_start() */ shell_register_cmd(name, handler_fn, help_text)

/* Provide UART I/O callbacks and start the shell task */ shell_io_t io = { .getc = uart_getc, .puts = uart_puts }; shell_start(&io)

/* Change the prompt at any time */ shell_set_prompt("mydevice> ")

/* Execute a single line programmatically */ shell_exec(line)

root@kitploit:~
**Пример пользовательской команды:**```c
static int cmd_led(int argc, char *argv[]) {
    if (argc < 2) return 1;  /* non-zero → prints usage */
    bool on = (strcmp(argv[1], "on") == 0);
    gpio_write(LED_PIN, on);
    return 0;
}

/* In main(), before shell_start(): */
shell_register_cmd("led", cmd_led, "led <on|off>  Toggle LED");

Встроенные команды оболочки

Привязки клавиш редактора строки:

Конфигурация оболочки (include/tinyos/shell.h):```c #define SHELL_MAX_COMMANDS 32 /* max registered commands / #define SHELL_LINE_MAX 128 / max input line length (bytes) / #define SHELL_ARGV_MAX 16 / max arguments per command / #define SHELL_HISTORY_DEPTH 8 / command history entries */

root@kitploit:~
### Сеть```c
net_init(driver, config) / net_start()
net_socket(type) / net_bind(sock, addr) / net_connect(sock, addr, timeout_ms)
net_send(sock, data, len, timeout_ms) / net_recv(sock, buf, len, timeout_ms)
net_sendto(sock, data, len, addr) / net_recvfrom(sock, buf, len, addr)
net_close(sock)
net_ping(dest_ip, timeout_ms, rtt)
net_dns_resolve(hostname, ip, timeout_ms)
net_http_get(url, response, timeout_ms)
net_http_post(url, content_type, body, len, response, timeout_ms)

Совместимость с POSIX

TinyOS предоставляет два тонких уровня совместимости, которые позволяют компилировать и запускать стандартный переносимый код на TinyOS с минимальными изменениями.

pthreads (include/tinyos/posix_threads.h)

Добавьте src/posix/posix_threads.c в свою сборку.```c #include "tinyos/posix_threads.h"

/* ── Thread ── / pthread_t tid; pthread_attr_t attr; pthread_attr_init(&attr); tinyos_pthread_attr_setpriority(&attr, PRIORITY_NORMAL); / TinyOS extension / pthread_create(&tid, &attr, my_fn, arg); pthread_join(tid, &retval); pthread_detach(tid); / free resources automatically on exit / pthread_exit(retval); / terminate calling thread / pthread_self(); / handle of calling thread */

/* ── Mutex ── / pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&mtx); pthread_mutex_trylock(&mtx); / returns EBUSY if already locked */ pthread_mutex_unlock(&mtx);

/* ── Condition variable ── / pthread_cond_t cond = PTHREAD_COND_INITIALIZER; pthread_cond_wait(&cond, &mtx); pthread_cond_timedwait(&cond, &mtx, &abstime); / abstime relative to boot */ pthread_cond_signal(&cond); pthread_cond_broadcast(&cond);

root@kitploit:~
| Понятие | Сопоставляется с |
|---|---|
| `pthread_t` | Индекс во внутреннем пуле слотов TinyOS `tcb_t` |
| `pthread_mutex_t` | Встраивает `mutex_t` напрямую (валидна инициализация нулём / `PTHREAD_MUTEX_INITIALIZER`) |
| `pthread_cond_t` | Встраивает `cond_var_t` напрямую (валидна инициализация нулём / `PTHREAD_COND_INITIALIZER`) |
| `pthread_join` | Ожидает поточный `semaphore_t`, установленный `pthread_exit` |

**Не поддерживается:** `pthread_cancel`, поточно-локальное хранилище (`pthread_key_*`),
рекурсивные мьютексы (возвращает `ENOTSUP`).

**Конфигурация** (`include/tinyos/posix_threads.h`):```c
#define PTHREAD_MAX_THREADS  MAX_TASKS  /* max concurrent pthreads */

Сокеты BSD (include/tinyos/posix_socket.h)

Добавьте src/posix/posix_socket.c в вашу сборку.```c #include "tinyos/posix_socket.h"

/* ── TCP server ── */ int srv = socket(AF_INET, SOCK_STREAM, 0);

int reuse = 1; setsockopt(srv, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));

struct sockaddr_in addr = { .sin_family = AF_INET, .sin_port = htons(8080), .sin_addr = { htonl(INADDR_ANY) }, }; bind(srv, (struct sockaddr *)&addr, sizeof(addr)); listen(srv, 4);

struct sockaddr_in peer; socklen_t plen = sizeof(peer); int client = accept(srv, (struct sockaddr )&peer, &plen); recv(client, buf, sizeof(buf), 0); send(client, response, response_len, 0); posix_sock_close(client); / or define TINYOS_POSIX_WRAP_CLOSE to use close() */ posix_sock_close(srv);

/* ── TCP client ── */ int fd = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in dest = { .sin_family = AF_INET, .sin_port = htons(80), .sin_addr = { inet_addr("192.168.1.1") }, }; connect(fd, (struct sockaddr *)&dest, sizeof(dest)); send(fd, request, request_len, 0); recv(fd, buf, sizeof(buf), 0); posix_sock_close(fd);

/* ── UDP ── */ int udp = socket(AF_INET, SOCK_DGRAM, 0); sendto(udp, data, len, 0, (struct sockaddr *)&dest, sizeof(dest)); recvfrom(udp, buf, sizeof(buf), 0, (struct sockaddr *)&src, &srclen); posix_sock_close(udp);

/* ── Address utilities ── / htons(port) / htonl(addr) / ntohs(n) / ntohl(n) inet_addr("192.168.1.1") / → in_addr_t, network byte order / inet_ntoa(in) / → "192.168.1.1" (static buffer) */ inet_pton(AF_INET, "192.168.1.1", &in_addr) inet_ntop(AF_INET, &in_addr, buf, sizeof(buf))

root@kitploit:~
| BSD call | Mapped to |
|---|---|
| `socket()` | `net_socket()` |
| `bind()` | `net_bind()` |
| `listen()` | `net_listen()` |
| `accept()` | `net_accept()` |
| `connect()` | `net_connect()` |
| `send()` / `recv()` | `net_send()` / `net_recv()` |
| `sendto()` / `recvfrom()` | `net_sendto()` / `net_recvfrom()` |
| `posix_sock_close()` | `net_close()` |

**Поддерживаемые опции `setsockopt`:**

| Опция | Эффект |
|---|---|
| `SO_REUSEADDR` | Принято; бездействие (всегда повторно используемо в TinyOS) |
| `SO_RCVTIMEO` | Устанавливает таймаут приема на сокет (struct timeval → мс) |
| `SO_SNDTIMEO` | Устанавливает таймаут отправки/подключения на сокет |

**Перенаправление `close()`:** определите `TINYOS_POSIX_WRAP_CLOSE` перед включением заголовка для сопоставления `close(fd)` → `posix_sock_close(fd)`.

**Не поддерживается:** `select` / `poll` / `epoll`, неблокирующий режим (`O_NONBLOCK`), IPv6 (`AF_INET6` возвращает `EAFNOSUPPORT`).

---

### TLS / DTLS

TLS 1.2/1.3 через TCP и DTLS 1.2 через UDP на базе **mbedTLS**.  
Включите во время сборки с помощью `-DTINYOS_TLS_ENABLE` и слинкуйтесь с mbedTLS.```c
/* Client (TLS over TCP) */
tls_context_t tls;
tls_config_t  cfg = TLS_CONFIG_DEFAULT_CLIENT;
cfg.ca_cert     = ca_cert_pem;
cfg.ca_cert_len = sizeof(ca_cert_pem);
tls_init(&tls, &cfg);

net_socket_t sock = net_socket(SOCK_STREAM);
net_connect(sock, &broker_addr, 5000);
tls_connect(&tls, sock, "example.com", 5000);

tls_send(&tls, data, len);
tls_recv(&tls, buf, sizeof(buf), 5000);
tls_close(&tls);

/* Server (TLS accept) */
tls_config_t srv_cfg = TLS_CONFIG_DEFAULT_SERVER;
srv_cfg.cert     = server_cert_pem;
srv_cfg.cert_len = sizeof(server_cert_pem);
srv_cfg.key      = server_key_pem;
srv_cfg.key_len  = sizeof(server_key_pem);
tls_init(&tls, &srv_cfg);
tls_accept(&tls, client_sock, 5000);

/* DTLS over UDP */
tls_config_t dtls_cfg = TLS_CONFIG_DEFAULT_DTLS_CLIENT;
net_socket_t usock = net_socket(SOCK_DGRAM);
tls_connect_dtls(&tls, usock, "example.com", 5000);

MQTT

Полный MQTT 3.1.1 с гарантиями доставки QoS для каждого сообщения.```c mqtt_config_t cfg = { .broker_host = "mqtt.example.com", .client_id = "tinyos-01", .keepalive_sec = 60, .clean_session = true, .auto_reconnect = true, .reconnect_interval_ms = 3000, /* base; doubles each attempt (max 60 s) */ }; mqtt_client_t client; mqtt_client_init(&client, &cfg); mqtt_set_connection_callback(&client, on_connect, NULL); mqtt_set_message_callback(&client, on_message, NULL); mqtt_connect(&client);

/* Publish — QoS1/2 are buffered offline if disconnected */ mqtt_publish(&client, "sensors/temp", "23.5", 4, MQTT_QOS_1, false);

/* Inspect reliability queues / uint8_t in_flight = mqtt_get_inflight_count(&client); / sent, awaiting ACK / uint8_t pending = mqtt_get_pending_count(&client); / queued while offline */

mqtt_subscribe(&client, "cmd/#", MQTT_QOS_1); mqtt_flush_pending(&client); /* discard offline queue */ mqtt_disconnect(&client);

root@kitploit:~
#### Модель надежности MQTT```
QoS 0  ─── fire-and-forget; dropped if disconnected
QoS 1  ─── in-flight table tracks each PUBLISH until PUBACK
              ↳ retransmits with DUP=1 every 5 s, up to 5 times
              ↳ if offline → offline queue (up to 8 messages)
QoS 2  ─── full PUBLISH → PUBREC → PUBREL → PUBCOMP handshake
              ↳ each step is retried independently on timeout

Auto-reconnect back-off: 3 s → 6 s → 12 s → … → 60 s (cap)
On reconnect: re-subscribes all topics, flushes offline queue

Конфигурация надежности MQTT (include/tinyos/mqtt.h):```c #define MQTT_MAX_INFLIGHT 8 /* in-flight slots / #define MQTT_MAX_PENDING 8 / offline queue slots / #define MQTT_MAX_PAYLOAD_SIZE 512 / bytes per queued msg / #define MQTT_RETRY_INTERVAL_MS 5000 / retry after (ms) / #define MQTT_MAX_RETRY_COUNT 5 / retries before drop / #define MQTT_RECONNECT_BASE_MS 3000 / first reconnect delay / #define MQTT_RECONNECT_MAX_MS 60000 / backoff ceiling */

root@kitploit:~
### CoAP```c
coap_init(ctx, config, is_server) / coap_start(ctx) / coap_stop(ctx)
coap_get(ctx, ip, port, path, response, timeout_ms)
coap_post(ctx, ip, port, path, format, payload, len, response, timeout_ms)
coap_resource_create(ctx, path, handler, user_data)
coap_process(ctx, timeout_ms)

OTA```c

ota_init(config) ota_start_update(url, callback, user_data) ota_write_chunk(data, size, offset) / ota_finalize_update() ota_confirm_boot() / ota_rollback() ota_verify_partition(type)

root@kitploit:~
### Файловая система```c
fs_format(device) / fs_mount(device) / fs_unmount()
fs_open(path, flags) / fs_close(fd)
fs_read(fd, buf, size) / fs_write(fd, buf, size)
fs_seek(fd, offset, whence) / fs_tell(fd)
fs_mkdir(path) / fs_remove(path) / fs_rmdir(path)
fs_stat(path, stat)
fs_opendir(path) / fs_readdir(dir, entry) / fs_closedir(dir)
fs_get_stats(stats) / fs_get_free_space() / fs_is_mounted()

/* Copy-on-Write snapshots */
fs_snapshot(source_path, snapshot_name)   /* atomic COW snapshot of a file */
fs_get_block_refcount(block_nr)           /* reference count of a data block */

Журналирование (Write-Ahead Log)

Файловая система использует журналирование только метаданных (упорядоченный режим). Перед изменением любого inode, битовой карты или блока каталога запись журнала записывается в выделенную область WAL размером 32 блока в начале раздела. При следующем монтировании после сбоя fs_mount воспроизводит журнал и восстанавливает согласованное состояние.``` Disk layout (FS_BLOCK_SIZE = 512 bytes) Block 0 Superblock (version 0x00020000 — v2 with journaling) Block 1 Block bitmap Block 2 Journal header Blocks 3-33 Journal data (31 slots) Blocks 34-41 Inode table (8 blocks, 128 inodes) Block 42+ Data blocks

root@kitploit:~
#### Copy-on-Write (COW)

Каждый блок данных содержит in-memory счетчик ссылок, восстанавливаемый из inode-таблицы при монтировании. Запись в блок, который является общим (`refcount > 1`), сначала выделяет приватную копию — счетчик исходного блока уменьшается, и все изменения происходят в новом блоке.

`fs_snapshot()` создает атомарный мгновенный снимок (snapshot) путем дублирования исходного inode (те же указатели на блоки, увеличенные счетчики ссылок) в рамках одной журнальной транзакции. Либо полный снимок фиксируется, либо ничего не меняется.```c
/* Create a snapshot of /data/config → /snapshots/config-20260101 */
fs_snapshot("/data/config", "/snapshots/config-20260101");

/* Inspect sharing */
uint8_t rc = fs_get_block_refcount(42);   /* 1 = private, >1 = shared */

Управление питанием```c

os_power_init() os_power_set_mode(mode) /* ACTIVE / IDLE / SLEEP / DEEP_SLEEP */ os_power_get_mode() os_power_enter_sleep(duration_ms) os_power_enter_deep_sleep(duration_ms) os_power_enable_tickless_idle(enable) os_power_set_cpu_frequency(freq_hz) os_power_configure_wakeup(source, enable) os_power_get_stats(stats) os_power_get_consumption_mw() os_power_estimate_battery_life_hours()

root@kitploit:~
### Сторожевой таймер```c
wdt_init(config) / wdt_start() / wdt_stop()
wdt_feed() / wdt_set_timeout(ms)
wdt_register_task(task, timeout_ms) / wdt_feed_task(task)

HAL (Уровень аппаратной абстракции)

TinyOS предоставляет общий уровень HAL, который скрывает весь доступ к регистрам, специфичным для архитектуры, за стабильным интерфейсом на C. Архитектура выбирается на этапе компиляции с помощью переменной Makefile ARCH; в коде ядра не встречаются ограждения #ifdef.

Переносимые примитивы (объявлены static inline в каждом заголовочном файле архитектуры)```c

uint32_t hal_irq_save(void) /* disable IRQs, return saved state / void hal_irq_restore(uint32_t s) / restore IRQ state / void hal_context_switch_trigger() / pend PendSV / raise MSIP / Timer0 / void hal_cpu_wait_for_interrupt() / WFI / wfi / sleep instruction / void hal_cpu_dsb(void) / data synchronization barrier / void hal_cpu_isb(void) / instruction synchronization barrier */

root@kitploit:~
#### Non-inline функции (реализованы для каждой архитектуры в `hal/<arch>/hal_<arch>.c`)```c
void     hal_init(void)
void     hal_tick_init(uint32_t core_clock_hz, uint32_t tick_rate_hz)
void     hal_tick_suppress(uint32_t max_ticks)
uint32_t hal_tick_unsuppress(void)
uint32_t hal_core_clock_hz(void)

bool     hal_cycle_counter_init(void)
void     hal_cycle_counter_reset(void)
uint32_t hal_cycle_counter_read(void)

bool     hal_mpu_init(uint8_t *region_count)
int      hal_mpu_configure_region(uint8_t region, uint32_t base,
                                   uint32_t size, uint32_t attrs)
void     hal_mpu_enable(bool allow_privileged_default)
void     hal_mpu_disable(void)

void     hal_irq_set_priority(int irq_num, uint8_t priority)
void     hal_system_reset(void)          /* does not return */
void     hal_fault_capture(const uint32_t *frame, hal_fault_info_t *info)

Реестр платформы на уровне платы

Регистрируйте периферийные устройства платы один раз при запуске; ядро и менеджер питания запрашивают таблицу через hal_platform_get() вместо использования слабых символов.```c static const hal_uart_ops_t my_uart = { .init = ..., .putc = ... }; static const hal_power_ops_t my_power = { .enter_sleep = ..., .set_clock_hz = ... };

static const hal_platform_t board = { .uart[0] = &my_uart, .power = &my_power, };

hal_platform_register(&board); /* call before os_start() */

root@kitploit:~
`hal_platform_t` предоставляет слоты для `uart[4]`, `flash`, `gpio`, `spi[4]`,
`i2c[4]`, и `power`.  Любой указатель `NULL` означает "не присутствует на этой плате".

#### Матрица поддержки архитектур

| Архитектура | Источник тактов | Счётчик циклов | MPU / PMP | Триггер переключения контекста |
|---|---|---|---|---|
| Cortex-M0/M0+/M3/M4/M7 | SysTick | DWT CYCCNT (M3+) | MPU | PendSV via ICSR |
| RISC-V RV32I/IM | CLINT MTIMECMP | `rdcycle` CSR | PMP (4 regions) | MSIP software interrupt |
| AVR ATmega/ATtiny | Timer0 CTC | — (returns 0) | — | Timer0 overflow |

---

## Конфигурация

**`include/tinyos.h`** — ядро и ОС:```c
#define MAX_TASKS              16     /* max concurrent tasks                    */
#define STACK_SIZE             256    /* stack size per task (words)             */
#define TICK_RATE_HZ           1000   /* scheduler tick frequency (Hz)           */
#define TIME_SLICE_MS          10     /* round-robin time slice (ms)             */
#define TICKLESS_MAX_SLEEP_TICKS 100U /* tickless idle: max ticks per WFI sleep  */

include/tinyos/shell.h — интерактивная оболочка:```c #define SHELL_MAX_COMMANDS 32 /* max registered commands / #define SHELL_LINE_MAX 128 / max input line length (bytes) / #define SHELL_ARGV_MAX 16 / max arguments per command / #define SHELL_HISTORY_DEPTH 8 / command history ring buffer */

root@kitploit:~
**`include/tinyos/mqtt.h`** — надежность MQTT:```c
#define MQTT_MAX_INFLIGHT        8      /* in-flight QoS1/2 slots    */
#define MQTT_MAX_PENDING         8      /* offline queue slots       */
#define MQTT_MAX_PAYLOAD_SIZE    512    /* max queued payload bytes  */
#define MQTT_RETRY_INTERVAL_MS   5000   /* unACKed retry interval    */
#define MQTT_MAX_RETRY_COUNT     5      /* retries before discard    */
#define MQTT_RECONNECT_BASE_MS   3000   /* initial reconnect delay   */
#define MQTT_RECONNECT_MAX_MS    60000  /* back-off ceiling          */

TLS — требуется mbedTLS; включите с помощью:```makefile CFLAGS += -DTINYOS_TLS_ENABLE LDFLAGS += -lmbedtls -lmbedcrypto -lmbedx509

root@kitploit:~
## Структура проекта```
tinyos-rtos/
├── include/
│   ├── tinyos.h              # Core API (tasks, sync, timers, memory, FS, power)
│   └── tinyos/
│       ├── shell.h           # Interactive shell API & configuration
│       ├── net.h             # Network stack
│       ├── tls.h             # TLS 1.2/1.3 + DTLS 1.2 (mbedTLS)
│       ├── mqtt.h            # MQTT 3.1.1 client
│       ├── coap.h            # CoAP RFC 7252
│       ├── ota.h             # OTA firmware updates
│       ├── watchdog.h        # Watchdog timer
│       ├── posix_threads.h   # POSIX pthreads compatibility layer
│       └── posix_socket.h    # BSD socket compatibility layer
├── src/
│   ├── startup.s             # Vector table, Reset_Handler, SysTick/SVC/PendSV stubs
│   ├── context_switch.s      # Thumb-2: PendSV_Handler, SVC_Handler, os_pend_sv
│   ├── kernel.c              # Preemptive scheduler & task management
│   ├── sync.c                # Mutex, semaphore, queue, condition var, event groups
│   ├── timer.c               # Software timers
│   ├── memory.c              # Heap allocator
│   ├── shell.c               # Interactive shell (VT100, history, tab completion)
│   ├── filesystem.c          # Block-device file system
│   ├── security.c            # MPU memory protection
│   ├── power.c               # Power management & CPU frequency scaling
│   ├── watchdog.c            # Watchdog (HW + SW, per-task monitoring)
│   ├── bootloader.c          # Secure bootloader
│   ├── ota.c                 # OTA A/B partition updates
│   ├── mqtt.c                # MQTT client (in-flight table, offline queue)
│   ├── coap.c                # CoAP client/server
│   ├── net/
│   │   ├── network.c         # Core & buffer management
│   │   ├── ethernet.c        # Ethernet / ARP
│   │   ├── ip.c              # IPv4 / ICMP
│   │   ├── socket.c          # UDP / TCP socket API
│   │   ├── http_dns.c        # HTTP client & DNS resolver
│   │   └── tls.c             # TLS/DTLS (mbedTLS wrapper, excluded when mbedTLS absent)
│   └── posix/
│       ├── posix_threads.c   # pthreads → TinyOS task/sync wrapper
│       └── posix_socket.c    # BSD socket → net_* wrapper
├── hal/
│   ├── hal.h                 # Portable HAL interface (arch-agnostic API + peripheral op-tables)
│   ├── cortex_m/
│   │   ├── hal_cortex_m.h    # Register defines + static inline primitives (irq_save, WFI, DSB …)
│   │   └── hal_cortex_m.c    # SysTick, DWT, MPU, AIRCR reset, fault capture
│   ├── riscv/
│   │   ├── hal_riscv.h       # csrrci/csrw inline primitives, CLINT defines
│   │   └── hal_riscv.c       # CLINT tick, rdcycle counter, PMP, PLIC priority, CSR fault capture
│   └── avr/
│       ├── hal_avr.h         # SREG-based irq_save, Timer0 context-switch trigger
│       └── hal_avr.c         # Timer0 CTC tick, watchdog reset, stub MPU/cycle-counter
├── drivers/
│   ├── flash.c / flash.h     # Flash memory driver
│   ├── ramdisk.c / ramdisk.h # RAM disk (testing)
│   └── loopback_net.c        # Loopback network driver (testing)
├── linker.ld                 # Linker script (mps2-an385: Flash 0x0/4MB, RAM 0x20000000/4MB)
└── examples/
    ├── blink_led.c           # GPIO blink
    ├── iot_sensor.c          # Multi-task sensor node
    ├── shell_demo.c          # Custom shell commands over UART
    ├── network_demo.c        # TCP/UDP/HTTP/ping
    ├── tls_demo.c            # TLS client/server
    ├── mqtt_demo.c           # MQTT publish/subscribe (QoS 1/2)
    ├── coap_demo.c           # CoAP client/server
    ├── ota_demo.c            # Firmware update flow
    ├── filesystem_demo.c     # File I/O
    ├── watchdog_demo.c       # Watchdog configuration
    ├── low_power.c           # Power mode transitions
    ├── software_timers.c     # Timer creation and callbacks
    ├── event_groups.c        # Event synchronisation
    ├── event_flags_logic.c   # AND / OR / NOT(CLEAR) / SYNC(barrier) patterns
    ├── condition_variable.c  # Producer/consumer
    ├── priority_adjustment.c # Dynamic priority
    ├── task_statistics.c     # CPU and stack monitoring
    └── posix_compat_demo.c   # POSIX pthreads + socket usage examples

Производительность

АрхитектураПереключение контекста
Cortex-M0~2 мкс
Cortex-M4~1 мкс
RISC-V~1.5 мкс

Системные требования: минимум 2 КБ ОЗУ · < 10 КБ ПЗУ для одного ядра


Список изменений

v2.0.0

Новые возможности

  • Журналируемая файловая система (src/filesystem.c) — журнал упреждающей записи (WAL) защищает все записи метаданных (inodes, битовая карта, суперблок, каталоги).
    Формат на диске увеличен до FS_VERSION 0x00020000. Журнал занимает 32 блока, начиная с блока 2; fs_mount воспроизводит все зафиксированные, но не применённые транзакции, прежде чем передать управление приложению. Журналирование только метаданных (упорядоченное) обеспечивает низкую амплитуду записи, гарантируя согласованность файловой системы после сбоя питания или сброса в любой момент записи.

  • Совместное использование блоков с копированием при записи (src/filesystem.c) — каждый блок данных содержит счётчик ссылок в памяти (восстанавливается из таблицы inodes при монтировании). Запись в совместно используемый блок незаметно выделяет приватную копию; счётчик ссылок исходного блока уменьшается. fs_snapshot(source, name) создаёт атомарный снимок на момент времени в рамках одной транзакции журнала — либо всё, либо ничего фиксируется. Новый публичный API: fs_snapshot() и fs_get_block_refcount() (см. include/tinyos.h).

  • Универсальный уровень аппаратной абстракции (HAL) (hal/) — двухуровневый слой HAL отделяет ядро от специфики ARM Cortex-M.

Критические изменения

  • src/kernel.c больше не содержит голых определений регистров SYST_*, SCB_SHPR3, SCB_AIRCR или DWT_* — теперь они предоставляются HAL. Код, напрямую ссылавшийся на эти макросы, необходимо обновить для использования API HAL.
  • Слабые символы src/power.c (platform_enter_sleep_mode и т.д.) теперь делегируют вызов hal_platform_t->power, когда платформа зарегистрирована; платы, полагавшиеся на стандартное __asm__ volatile("wfi"), увидят идентичное поведение, если не зарегистрирован hal_power_ops_t.
  • Версия файловой системы на диске — 0x00020000. Тома, отформатированные в v1.x, необходимо переформатировать (fs_format).

v1.2.0

Исправления ошибок

  • Таблица векторов startup.s — MemManage_Handler, BusFault_Handler и UsageFault_Handler теперь указывают на корректные обработчики в fault.c.
    Ранее все три записи разрешались в Default_Handler, поэтому ошибки MPU, шины и использования беззвучно проглатывались вместо запуска диагностического дампа.
  • Двойное уменьшение в os_cond_wait — cond_remove_task() уже уменьшает waiting_count; три места вызова, которые уменьшали его повторно, исправлены.
    Ранее лишнее дополнительное уменьшение могло вызвать переполнение счётчика и повредить состояние условной переменной.
  • Буст PIP мьютекса не сбрасывался по таймауту — путь с таймированным ожиданием в os_mutex_lock теперь вызывает mutex_pip_recalculate() перед возвратом OS_ERROR_TIMEOUT. Ранее буст приоритета, применённый к владельцу, никогда не отменялся, когда ожидающая задача отказывалась от ожидания, что приводило к постоянному повышению приоритета.

Улучшения

  • Переработка аллокатора памяти (src/memory.c) — фиксированный пул блоков по 32 байта заменён на аллокатор first-fit со следующими особенностями:
    • 8 КБ кучи (вместо 4 КБ), блоки выровнены по 8 байт
    • Список свободных блоков упорядочен по адресам; смежные свободные блоки объединяются сразу при каждом os_free() (вперёд и назад)
    • Блоки разделяются при выделении, если остаток достаточно велик для использования (≥ BLK_HDR + ALIGN)
  • Порядок инициализации os_init() — os_mem_init() и os_power_init() теперь вызываются до os_timer_init(), чтобы куча и подсистема питания были готовы до выполнения любых callback-ов таймера или кода задач.
  • Реализован безтиковый режим простоя (src/kernel.c: os_kernel_tickless_sleep) — при включении через os_power_enable_tickless_idle(true) задача простоя отключает SysTick перед WFI и использует счётчик циклов DWT CYCCNT для измерения фактического прошедшего времени. После пробуждения SysTick перезапускается, увеличивается на измеренные тики (с ограничением ), и вызывается для немедленного разблокирования просроченных задач. Ранее флаг существовал, но путь простоя всегда выполнял простой с работающим SysTick.

v1.1.0

Новые возможности

  • Флаг EVENT_WAIT_CLEAR для групп событий — ожидание, пока биты станут равны 0 (условие NOT).
    EVENT_WAIT_ALL | EVENT_WAIT_CLEAR пробуждается, когда все маскированные биты равны 0; EVENT_WAIT_ANY | EVENT_WAIT_CLEAR — когда любой из них равен 0.
  • os_event_group_sync() — примитив рандеву / барьер.
    Каждая участвующая задача устанавливает свой бит прибытия и блокируется, пока не появятся все биты; все разблокируются одновременно.
  • Новый пример examples/event_flags_logic.c, демонстрирующий все четыре режима (AND, OR, NOT, SYNC).

Исправления сборки и времени выполнения

  • Добавлен src/startup.s: таблица векторов, Reset_Handler (копирование .data, обнуление .bss), заглушка SysTick_Handler, HardFault_Handler.
  • Добавлен linker.ld: расположение памяти для mps2-an385 (Flash 0x00000000 / 4 МБ, RAM 0x20000000 / 4 МБ).
  • Исправлен начальный стек задач: область сохранения R4–R11 теперь предварительно выделяется, чтобы LDMIA {R4-R11} в PendSV корректно работал при первом переключении контекста на любую вновь созданную задачу.
  • SVC_Handler обновлён на использование LDMIA {R4-R11} перед установкой PSP, что делает пути SVC и PendSV симметричными.
  • Проверка MPU_TYPE в os_mpu_configure_default() — настройка MPU беззвучно пропускается, если MPU отсутствует (QEMU ).

Лицензия

Лицензия MIT — подробности см. в файле LICENSE.

Скачать инструмент
КомандаОписание
help [cmd]Вывести список всех команд или подробную справку по cmd
clearОчистить экран терминала (VT100)
echo <text>Вывести текст на терминал
historyПоказать историю команд
psСписок всех задач (состояние, приоритет, загрузка ЦП, использование стека)
topСписок задач, отсортированный по загрузке ЦП, по убыванию
kill <name> [suspend|resume|delete]Управление задачей по имени
memСтатистика кучи (всего / использовано / свободно, количество выделений/освобождений)
verВерсия TinyOS и отформатированное время работы
netСетевая статистика (счётчики Ethernet, IP, UDP, TCP)
ping <ip> [count]Отправить ICMP-запросы эхо
ifconfig [ip|netmask|gw|dns <addr>]Показать или изменить сетевую конфигурацию
power [active|idle|sleep|deepsleep]Статистика энергопотребления или смена режима
ls [path]Вывести содержимое каталога (по умолчанию: /)
cat <file>Вывести содержимое файла
mkdir <path>Создать каталог
rm <path>Удалить файл или пустой каталог
dfСтатистика использования файловой системы
touch <file>Создать пустой файл
cp <src> <dst>Копировать файл
uptimeПоказать время работы системы (ЧЧ:ММ:СС или N дн., ЧЧ:ММ:СС)
sleep <ms>Задержка задачи оболочки на N миллисекунд
rebootПерезагрузить систему
КлавишаДействие
← / Ctrl-BПереместить курсор влево
→ / Ctrl-FПереместить курсор вправо
Home / Ctrl-AПерейти к началу строки
End / Ctrl-EПерейти в конец строки
↑ / ↓Навигация по истории команд
TabДополнить имя команды
Ctrl-KУдалить до конца строки
Ctrl-UУдалить до начала строки
Ctrl-WУдалить предыдущее слово
Ctrl-LОчистить экран и перерисовать
Ctrl-CОтменить текущую строку
КомпонентПЗУОЗУ
Ядро6 КБ512 Б
На задачу—~1 КБ
Мьютекс—12 Б
Семафор—8 Б
Очередь сообщений (10 элементов)—40 Б + данные
Оболочка (с 23 встроенными командами)~4 КБ~2.5 КБ
MQTT-клиент (с очередями)~8 КБ~10 КБ
Слой POSIX-потоков~2 КБ~PTHREAD_MAX_THREADS × (tcb_t + 32 Б)
Слой POSIX-сокетов~1 КБ~NET_MAX_SOCKETS × 12 Б
  • hal/hal.h — архитектурно-независимый интерфейс: тик, счётчик циклов, MPU, сохранение/восстановление IRQ, триггер переключения контекста, сброс системы, захват ошибок и таблицы операций периферии (hal_platform_t с прорезями для UART / flash / GPIO / SPI / I²C / питания).
  • hal/cortex_m/ — полноценная реализация для Cortex-M0–M7 (SysTick, DWT, AIRCR, PRIMASK, PendSV).
  • hal/riscv/ — заглушка для RISC-V RV32 (тик CLINT MTIMECMP, счётчик rdcycle, PMP, приоритет PLIC, захват ошибок CSR).
  • hal/avr/ — заглушка для AVR ATmega (тик Timer0 CTC, критические секции SREG, сброс сторожевого таймера).
  • Makefile автоматически выбирает HAL на основе ARCH= (cortex-m* / riscv* / avr*) и передаёт -DHAL_ARCH_* компилятору.


kernel.tick_count
TICKLESS_MAX_SLEEP_TICKS
delay_queue_tick()

WFI
  • Увеличено MAX_TASKS — поднято с 8 до 16 для поддержки более реалистичных нагрузок IoT без модификации конфигурации пользователем.
  • mps2-an385
  • Переименован timer_t → os_timer_t во избежание конфликта с POSIX <sys/types.h>.
  • Makefile: добавлен -I. для включений из drivers/; источники TLS автоматически исключаются при отсутствии mbedTLS; добавлен -Wno-stringop-truncation для ложных предупреждений strncpy.
  • Исправлены предупреждения о сравнении знаков, неиспользуемых функциях, неинициализированных переменных и неявных объявлениях в coap.c, filesystem.c, mqtt.c, ota.c, security.c, net/ip.c, net/http_dns.c.