Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
tinyos-rtos — 사물인터넷(IoT)을 위한 초경량 RTOS로, 선점형 스케줄링, TLS/DTLS, MQTT, CoAP, POSIX 호환성, MPU 기반 메모리 보호를 제공합니다. 커널 크기는 10KB 미만입니다. | Kitploit
도구/GitHubGitHub/cmc-labo/tinyos-rtos
Embedded Systems SecurityIoT SecurityNetwork SecurityHardware HackingCryptographyHardware SecurityFirmware Analysis
GitHubcmc-labo/tinyos-rtos

tinyos-rtos

사물인터넷(IoT)을 위한 초경량 RTOS로, 선점형 스케줄링, TLS/DTLS, MQTT, CoAP, POSIX 호환성, MPU 기반 메모리 보호를 제공합니다. 커널 크기는 10KB 미만입니다.

저장소 보기
23583개월 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

TinyOS — 초경량 IoT용 RTOS

리소스가 제한된 IoT 및 임베디드 장치를 위한 초경량 실시간 운영체제입니다.
커널 크기 10KB 미만, 최소 RAM 2KB, 선점형 우선순위 기반 스케줄링.


특징

카테고리세부 사항
커널선점형 우선순위 기반 스케줄링(256레벨), 동일 우선순위 내 라운드 로빈, 비트맵을 통한 O(1) 우선순위 조회, 우선순위 상속
동기화뮤텍스(우선순위 상속 포함), 세마포어, 조건 변수, 이벤트 그룹, 메시지 큐
소프트웨어 타이머원샷 및 자동 재로드, 밀리초 정밀도, 런타임 주기 변경
메모리즉시 병합 기능이 있는 최초 적합 할당자(8KB 힙, 8바이트 정렬), 스택 오버플로 감지, 작업별 최고 사용량 표시
셸VT100 대화형 셸 — 23개의 내장 명령어, 명령어 기록(↑↓), 탭 완성, 전체 줄 편집기
POSIX 호환성pthreads (create/join/detach/exit, mutex, cond var) · BSD 소켓 API (socket/bind/listen/accept/connect/send/recv, inet_pton/ntop, htons/htonl)
파일 시스템저널링 블록 장치 FS(WAL, 충돌 복구), COW 블록 공유, 원자적 스냅샷, POSIX 유사 API
네트워크이더넷, IPv4, ICMP, UDP, TCP, HTTP 클라이언트/서버, DNS
TLS / DTLSTCP를 통한 TLS 1.2/1.3, UDP를 통한 DTLS 1.2 (mbedTLS 백엔드)
MQTT완전한 MQTT 3.1.1 — 처리 중 재시도 테이블을 포함한 QoS 0/1/2, 오프라인 큐, 지수 백오프를 이용한 자동 재연결
CoAPRFC 7252 호환 클라이언트/서버, 관찰 패턴
OTAA/B 파티션 펌웨어 업데이트, CRC32 검증, 롤백
워치독하드웨어 및 소프트웨어 워치독, 작업별 타임아웃 모니터링
전원유휴/슬립/딥슬립 모드, 틱리스 유휴, CPU 주파수 조절
보안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 | Description |
|---|---|
| `build/tinyos.elf` | 디버그 심볼이 포함된 ELF 이미지 |
| `build/tinyos.bin` | 플래싱을 위한 원시 바이너리 |
| `build/tinyos.map` | 링커 맵 (심볼 크기) |

### QEMU에서 실행

TinyOS는 QEMU `mps2-an385` 대상 (ARM Cortex-M3, 4MB 플래시, 4MB RAM)에서 실행됩니다:```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)

`~/mbedtls`에 mbedTLS가 있을 경우 TLS 지원이 자동으로 활성화됩니다.
다른 경로를 사용하려면:```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`를 직접 포함 (zero-init / `PTHREAD_MUTEX_INITIALIZER` 유효) |
| `pthread_cond_t` | `cond_var_t`를 직접 포함 (zero-init / `PTHREAD_COND_INITIALIZER` 유효) |
| `pthread_join` | `pthread_exit`에 의해 게시된 스레드별 `semaphore_t`에서 대기 |

**지원되지 않음:** `pthread_cancel`, 스레드 로컬 저장소 (`pthread_key_*`), 재귀 뮤텍스 (`ENOTSUP` 반환).

**설정** (`include/tinyos/posix_threads.h`):```c
#define PTHREAD_MAX_THREADS  MAX_TASKS  /* max concurrent pthreads */

BSD Sockets (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 호출 | 매핑 대상 |
|---|---|
| `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 → ms) |
| `SO_SNDTIMEO` | 송신/연결 타임아웃 설정 |

**`close()` 리디렉션:** 헤더를 포함하기 전에 `TINYOS_POSIX_WRAP_CLOSE`를 정의하여 `close(fd)` → `posix_sock_close(fd)`로 매핑합니다.

**지원되지 않음:** `select` / `poll` / `epoll`, 비동기 모드 (`O_NONBLOCK`), IPv6 (`AF_INET6`는 `EAFNOSUPPORT` 반환)

---

### TLS / DTLS

TCP를 통한 TLS 1.2/1.3 및 UDP를 통한 DTLS 1.2는 **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

메시지별 QoS 전송 보장을 제공하는 완전한 MQTT 3.1.1.```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)

파일 시스템은 메타데이터 전용 저널링(ordered mode)을 사용합니다.
inode, bitmap 또는 디렉토리 블록이 수정되기 전에, 파티션 시작 부분의 전용 32-블록 WAL 영역에 저널 레코드가 기록됩니다.
충돌 후 다음 마운트 시, 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)

각 데이터 블록은 마운트 시 inode 테이블에서 재구성된 인메모리 참조 카운트를 가집니다.  공유된 블록(`refcount > 1`)에 쓰기 작업을 수행하면 먼저 개인 복사본을 할당합니다 — 원본 블록의 카운트는 감소하고 모든 변경 사항은 새 블록에 적용됩니다.

`fs_snapshot()`은 단일 저널 트랜잭션 내에서 소스 inode(동일한 블록 포인터, 증가된 refcount)를 복제하여 원자적인 시점 스냅샷을 생성합니다.  전체 스냅샷이 커밋되거나 아무것도 변경되지 않습니다.```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:~
### Watchdog```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는 안정적인 C 인터페이스 뒤에 모든 아키텍처별 레지스터 접근을 숨기는 일반적인 HAL을 제공합니다. 아키텍처는 ARCH Makefile 변수를 통해 컴파일 시간에 선택됩니다. 커널 코드에는 #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:~
#### 비인라인 함수들 (아키텍처별로 구현됨: `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`** — 커널 및 OS:```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

Performance

아키텍처컨텍스트 스위치
Cortex-M0~2 μs
Cortex-M4~1 μs
RISC-V~1.5 μs

시스템 요구 사항: 최소 2 KB RAM · 커널만 10 KB 미만 ROM


Changelog

v2.0.0

새로운 기능

  • 저널링 파일시스템 (src/filesystem.c) — Write-Ahead Log (WAL)는 모든 메타데이터 쓰기(inode, 비트맵, 슈퍼블록, 디렉터리)를 보호합니다.
    온디스크 포맷이 FS_VERSION 0x00020000으로 증가했습니다. 저널은 블록 2부터 시작하는 32개 블록을 차지합니다. fs_mount는 애플리케이션에 제어권을 넘기기 전에 커밋되었지만 적용되지 않은 트랜잭션을 재생합니다. 메타데이터 전용(순서화된) 저널링은 쓰기 증폭을 낮게 유지하면서 쓰기 과정 중 어떤 시점에 전원이 끊기거나 리셋되더라도 일관된 파일시스템을 보장합니다.

  • Copy-on-Write 블록 공유 (src/filesystem.c) — 모든 데이터 블록은 메모리 내 참조 카운트(마운트 시 inode 테이블에서 재구성됨)를 가집니다. 공유 블록에 쓰면 자동으로 개인 복사본이 할당되고, 공유 블록의 카운트는 감소합니다. fs_snapshot(source, name)은 단일 저널 트랜잭션 내에서 원자적 시점 스냅샷을 생성합니다. — 전체가 커밋되거나 전혀 커밋되지 않습니다. 새로운 공개 API: fs_snapshot() 및 fs_get_block_refcount() (include/tinyos.h 참조).

  • 제네릭 HAL (hal/) — 2계층 하드웨어 추상화 계층으로 커널을 ARM Cortex-M 전용 어셈블리로부터 분리합니다.

    • hal/hal.h — 아키텍처에 독립적인 인터페이스: 틱, 사이클 카운터, MPU, IRQ 저장/복원, 컨텍스트 스위치 트리거, 시스템 리셋, 폴트 캡처, 주변장치 op-table (hal_platform_t에 UART / 플래시 / GPIO / SPI / I²C / 전원 슬롯 포함).

호환성을 깨는 변경 사항

  • src/kernel.c는 더 이상 원시 SYST_*, SCB_SHPR3, SCB_AIRCR, 또는 DWT_* 레지스터 정의를 포함하지 않습니다. 이제는 HAL이 제공합니다. 이러한 매크로를 직접 참조했던 코드는 HAL API를 사용하도록 업데이트해야 합니다.
  • 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의 시간 제한 스핀 경로에서 이제 OS_ERROR_TIMEOUT을 반환하기 전에 mutex_pip_recalculate()를 호출합니다.
    이전에는 대기 중인 태스크가 포기할 때 소유자에게 적용된 우선순위 부스트가 취소되지 않아 영구적인 우선순위 인플레이션이 발생했습니다.

개선 사항

  • 메모리 할당자 재작성 (src/memory.c) — 고정 32바이트 블록 풀을 first-fit 할당자로 대체하여 다음 기능 제공:
    • 8 KB 힙 (4 KB에서 증가), 8바이트 정렬 블록
    • 주소 순서로 유지되는 자유 목록; 인접한 자유 블록은 모든 os_free() 호출 시 즉시 병합됨 (앞/뒤)
    • 할당 시 남은 공간이 유용할 만큼 충분히 큰 경우(≥ BLK_HDR + ALIGN) 블록 분할
  • os_init() 초기화 순서 — 이제 os_mem_init()과 os_power_init()이 os_timer_init()보다 먼저 호출되어, 타이머 콜백이나 태스크 코드가 실행되기 전에 힙과 전원 서브시스템이 준비됩니다.
  • 틱리스 아이들 구현 (src/kernel.c: os_kernel_tickless_sleep) — os_power_enable_tickless_idle(true)를 통해 활성화되면, 아이들 태스크가 WFI 전에 SysTick을 비활성화하고 DWT CYCCNT 사이클 카운터를 사용하여 실제 경과 시간을 측정합니다.
    깨어난 후 SysTick이 다시 시작되고, kernel.tick_count는 측정된 틱만큼 증가되며(최대 ), 이 호출되어 지연된 태스크를 즉시 해제합니다. 이전에는 플래그가 존재했지만 아이들 경로는 항상 SysTick이 실행 중인 상태로 일반 로 넘어갔습니다.

v1.1.0

새로운 기능

  • 이벤트 그룹의 EVENT_WAIT_CLEAR 플래그 — 비트가 clear (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용 메모리 레이아웃 (플래시 0x00000000 / 4 MB, RAM 0x20000000 / 4 MB).
  • 초기 태스크 스택 수정: R4–R11 저장 영역이 미리 할당되어 PendSV의 LDMIA {R4-R11}이 새로 생성된 태스크로의 첫 컨텍스트 스위치에서 올바르게 작동합니다.
  • SVC_Handler가 PSP 설정 전에 LDMIA {R4-R11}로 업데이트되어 SVC와 PendSV 경로가 대칭을 유지합니다.
  • os_mpu_configure_default()의 MPU_TYPE 검사 — MPU가 없으면 (QEMU mps2-an385) MPU 설정을 조용히 건너뜁니다.

License

MIT 라이선스 — 자세한 내용은 LICENSE를 참조하세요.

도구 다운로드
명령어설명
help [cmd]모든 명령어 나열, 또는 cmd에 대한 자세한 도움말 표시
clear터미널 화면 지우기 (VT100)
echo <text>텍스트를 터미널에 출력
history명령어 기록 보기
ps모든 작업 나열 (상태, 우선순위, CPU%, 스택 사용량)
topCPU 사용량 기준 내림차순 정렬된 작업 목록
kill <name> [suspend|resume|delete]이름으로 작업 제어
mem힙 통계 (전체 / 사용 중 / 사용 가능, 할당/해제 횟수)
verTinyOS 버전 및 형식화된 가동 시간
net네트워크 통계 (이더넷, 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시스템 가동 시간 표시 (HH:MM:SS 또는 N day(s), HH:MM:SS)
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현재 줄 취소
ComponentROMRAM
커널6 KB512 B
태스크당—~1 KB
뮤텍스—12 B
세마포어—8 B
메시지 큐 (항목 10개)—40 B + data
쉘 (내장 명령 23개)~4 KB~2.5 KB
MQTT 클라이언트 (큐 포함)~8 KB~10 KB
POSIX 스레드 계층~2 KB~PTHREAD_MAX_THREADS × (tcb_t + 32 B)
POSIX 소켓 계층~1 KB~NET_MAX_SOCKETS × 12 B
  • 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은 ARCH= (cortex-m* / riscv* / avr*)에서 HAL을 자동 선택하고 -DHAL_ARCH_*를 컴파일러에 전달합니다.
  • TICKLESS_MAX_SLEEP_TICKS
    delay_queue_tick()

    WFI
  • MAX_TASKS 증가 — 사용자 측 설정 변경 없이 더 현실적인 IoT 워크로드를 지원하기 위해 8에서 16으로 증가.
  • timer_t → os_timer_t로 이름 변경하여 POSIX <sys/types.h>와의 충돌 방지.
  • Makefile: drivers/ 포함을 위해 -I. 추가; mbedTLS가 없으면 TLS 소스 자동 제외; 잘못된 strncpy 경고를 위해 -Wno-stringop-truncation.
  • coap.c, filesystem.c, mqtt.c, ota.c, security.c, net/ip.c, net/http_dns.c에서 sign-compare, unused-function, uninitialized-variable, implicit-declaration 경고 수정.