Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
tinyos-rtos — RTOS ultra-léger pour l'Internet des objets avec ordonnancement préemptif, TLS/DTLS, MQTT, CoAP, compatibilité POSIX et protection mémoire basée sur MPU. Noyau de moins de 10 Ko. | Kitploit
Outils/GitHubGitHub/cmc-labo/tinyos-rtos
Sécurité des Systèmes EmbarquésSécurité IoTSécurité RéseauHacking MatérielCryptographieSécurité MatérielleAnalyse de Micrologiciel
GitHubcmc-labo/tinyos-rtos

tinyos-rtos

RTOS ultra-léger pour l'Internet des objets avec ordonnancement préemptif, TLS/DTLS, MQTT, CoAP, compatibilité POSIX et protection mémoire basée sur MPU. Noyau de moins de 10 Ko.

Voir le dépôt
2358il y a 3 moisVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

TinyOS — RTOS Ultra-Léger pour l'IdO

Un système d'exploitation temps réel ultra-léger pour les dispositifs IdO et embarqués contraints en ressources.
Empreinte du noyau sous 10 Ko, 2 Ko de RAM minimale, ordonnancement préemptif basé sur les priorités.


Fonctionnalités

CatégorieDétails
NoyauOrdonnancement préemptif basé sur les priorités (256 niveaux), tourniquet au sein d'une même priorité, recherche de priorité O(1) via bitmap, héritage de priorité
SynchronisationMutex (avec héritage de priorité), sémaphore, variable condition, groupes d'événements, files de messages
Minuteries logiciellesUn coup et auto-rechargement, précision milliseconde, changement de période en cours d'exécution
MémoireAllocateur first-fit avec coalescence immédiate (tas 8 Ko, aligné sur 8 octets), détection de débordement de pile, marqueur de niveau d'eau par tâche
ShellShell interactif VT100 — 23 commandes intégrées, historique des commandes (↑↓), complétion par tabulation, éditeur de ligne complet
Compatibilité POSIXpthreads (create/join/detach/exit, mutex, cond var) · API socket BSD (socket/bind/listen/accept/connect/send/recv, inet_pton/ntop, htons/htonl)
Système de fichiersFS à journalisation sur périphérique bloc (WAL, récupération après panne), partage de blocs COW, instantanés atomiques, API de type POSIX
RéseauEthernet, IPv4, ICMP, UDP, TCP, client/serveur HTTP, DNS
TLS / DTLSTLS 1.2/1.3 sur TCP, DTLS 1.2 sur UDP (backend mbedTLS)
MQTTMQTT 3.1.1 complet — QoS 0/1/2 avec table de retransmission en vol, file d'attente hors ligne, reconnexion automatique avec back-off exponentiel
CoAPClient/serveur conforme RFC 7252, motif observe
OTAMises à jour du firmware par partition A/B, vérification CRC32, retour arrière
WatchdogChien de garde matériel et logiciel, surveillance de délai par tâche
AlimentationModes Inactif / Veille / Veille profonde, idle sans tick, variation de fréquence CPU
SécuritéProtection mémoire basée sur MPU, support de démarrage sécurisé
HALCouche d'abstraction matérielle générique — ARM Cortex-M / RISC-V / AVR ; sélection d'architecture à la compilation, tables d'opérations périphériques

Matériel Supporté

ArchitectureExemples
ARM Cortex-M (M0/M0+/M3/M4/M7)STM32, nRF52, Raspberry Pi Pico
RISC-V (RV32I)ESP32-C3
AVR (expérimental)ATmega

Démarrage Rapide

Prérequis```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:~
Vérifiez l'installation:```bash
arm-none-eabi-gcc --version   # 10.x or later
qemu-system-arm --version     # 6.x or later

Compilation```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:~
Les artefacts de construction sont placés dans `build/` :

| Fichier | Description |
|---|---|
| `build/tinyos.elf` | Image ELF avec symboles de débogage |
| `build/tinyos.bin` | Binaire brut pour le flash |
| `build/tinyos.map` | Carte de l'éditeur de liens (tailles des symboles) |

### Exécution sur QEMU

TinyOS s'exécute sur la cible QEMU `mps2-an385` (ARM Cortex-M3, 4 Mo de flash, 4 Mo de 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

Résultat attendu de la trace d'interruption : des lignes successful exception return répétées confirment que le planificateur est en cours d'exécution, que SysTick émet des ticks et que les changements de contexte PendSV se terminent correctement.

Flasher sur le matériel```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:~
### Build with TLS (mbedTLS)

Le support TLS est activé automatiquement lorsque mbedTLS est présent dans `~/mbedtls`. Pour utiliser un autre chemin :```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

Exemple de tâche minimale:```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:~
---

## Aperçu de l'API

### Gestion des tâches```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)

Synchronisation```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:~
### Minuteries```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)

Shell```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:~
**Exemple de commande personnalisée**:```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");

Commandes intégrées du shell

Raccourcis clavier de l'éditeur de ligne :

Configuration du shell (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:~
### Réseau```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)

Compatibilité POSIX

TinyOS fournit deux fines couches de compatibilité qui permettent de compiler et d'exécuter du code portable standard sur TinyOS avec des modifications minimales.

pthreads (include/tinyos/posix_threads.h)

Ajoutez src/posix/posix_threads.c à votre build.```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:~
| Concept | Mappé à |
|---|---|
| `pthread_t` | Index dans un pool interne de slots `tcb_t` de TinyOS |
| `pthread_mutex_t` | Intègre directement `mutex_t` (zero-init / `PTHREAD_MUTEX_INITIALIZER` valide) |
| `pthread_cond_t` | Intègre directement `cond_var_t` (zero-init / `PTHREAD_COND_INITIALIZER` valide) |
| `pthread_join` | Attend un `semaphore_t` par thread publié par `pthread_exit` |

**Non supporté :** `pthread_cancel`, stockage local de thread (`pthread_key_*`),
mutex récursifs (retourne `ENOTSUP`).

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

Sockets BSD (include/tinyos/posix_socket.h)

Ajoutez src/posix/posix_socket.c à votre compilation.```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:~
| Appel BSD | Mappé à |
|---|---|
| `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()` |

**Options `setsockopt` prises en charge :**

| Option | Effet |
|---|---|
| `SO_REUSEADDR` | Accepté ; sans effet (toujours réutilisable dans TinyOS) |
| `SO_RCVTIMEO` | Définit le délai d'attente de réception par socket (struct timeval → ms) |
| `SO_SNDTIMEO` | Définit le délai d'attente d'envoi/connexion par socket |

**Redirection de `close()` :** définissez `TINYOS_POSIX_WRAP_CLOSE` avant d'inclure l'en-tête pour mapper `close(fd)` → `posix_sock_close(fd)`.

**Non pris en charge :** `select` / `poll` / `epoll`, mode non bloquant (`O_NONBLOCK`), IPv6 (`AF_INET6` retourne `EAFNOSUPPORT`).

---

### TLS / DTLS

TLS 1.2/1.3 sur TCP et DTLS 1.2 sur UDP reposant sur **mbedTLS**.  
Activez au moment de la compilation avec `-DTINYOS_TLS_ENABLE` et liez avec 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 complet avec garanties de livraison QoS par message.```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:~
#### Modèle de fiabilité 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

Configuration de fiabilité 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:~
### Système de fichiers```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 */

Journalisation (Write-Ahead Log)

Le système de fichiers utilise une journalisation des métadonnées uniquement (mode ordonné). Avant toute modification d'un inode, d'un bitmap ou d'un bloc de répertoire, un enregistrement de journal est écrit dans une zone WAL dédiée de 32 blocs au début de la partition. Lors du montage suivant un crash, fs_mount rejoue le journal et restaure un état cohérent.``` 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:~
#### Copie sur écriture (COW)

Chaque bloc de données possède un compteur de références en mémoire, reconstruit à partir de la table d'inodes lors du montage. L'écriture dans un bloc partagé (`refcount > 1`) alloue d'abord une copie privée — le compteur du bloc original est décrémenté et toutes les modifications s'effectuent sur le nouveau bloc.

`fs_snapshot()` crée un instantané atomique à un instant donné en dupliquant l'inode source (mêmes pointeurs de blocs, refcounts incrémentés) au sein d'une seule transaction de journal. Soit l'intégralité de l'instantané est validée, soit rien ne change.```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 */

Gestion de l'alimentation```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 (Hardware Abstraction Layer)

TinyOS fournit une HAL générique qui masque tout accès aux registres spécifiques à l'architecture derrière une interface C stable. L'architecture est sélectionnée au temps de compilation via la variable Makefile ARCH ; aucune garde #ifdef n'apparaît dans le code du noyau.

Primitives portables (déclarées static inline dans chaque en-tête d'architecture)```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:~
#### Fonctions non inline (implémentées par architecture dans `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)

Registre de plateforme au niveau de la carte

Enregistrez les périphériques de la carte une fois au démarrage ; le noyau et le gestionnaire d'alimentation interrogent la table via hal_platform_get() au lieu d'utiliser des symboles faibles.```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` fournit des emplacements pour `uart[4]`, `flash`, `gpio`, `spi[4]`,
`i2c[4]` et `power`.  Tout pointeur `NULL` signifie « non présent sur cette carte ».

#### Matrice de support d'architecture

| Architecture | Tick source | Cycle counter | MPU / PMP | Context switch trigger |
|---|---|---|---|---|
| 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 |

---

## Configuration

**`include/tinyos.h`** — noyau et 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 — shell interactif :```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 fiabilité :```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 — nécessite mbedTLS; activer avec:```makefile CFLAGS += -DTINYOS_TLS_ENABLE LDFLAGS += -lmbedtls -lmbedcrypto -lmbedx509

root@kitploit:~
## Structure du projet```
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

Performances

ArchitectureChangement de contexte
Cortex-M0~2 μs
Cortex-M4~1 μs
RISC-V~1,5 μs

Configuration système requise : 2 Ko de RAM minimum · < 10 Ko de ROM pour le noyau seul


Journal des modifications

v2.0.0

Nouvelles fonctionnalités

  • Système de fichiers journalisé (src/filesystem.c) — Le journal d’écriture anticipée (WAL) protège toutes les écritures de métadonnées (inœuds, bitmap, superbloc, répertoires).
    Le format sur disque passe à FS_VERSION 0x00020000. Le journal occupe 32 blocs à partir du bloc 2 ; fs_mount rejoue toute transaction validée mais non appliquée avant de passer la main à l’application. La journalisation ordonnée (métadonnées seulement) maintient une faible amplification d’écriture tout en garantissant un système de fichiers cohérent après une coupure d’alimentation ou une réinitialisation à tout moment pendant une écriture.

  • Partage de blocs par copie sur écriture (src/filesystem.c) — Chaque bloc de données porte un compteur de références en mémoire (reconstruit depuis la table des inœuds au montage). L’écriture dans un bloc partagé alloue silencieusement une copie privée ; le compteur du bloc partagé est décrémenté. fs_snapshot(source, nom) crée un instantané atomique ponctuel dans une seule transaction du journal — tout ou rien est validé. Nouvelle API publique : fs_snapshot() et fs_get_block_refcount() (voir include/tinyos.h).

  • HAL générique (hal/) — Une couche d’abstraction matérielle à deux niveaux découple le noyau de l’assembleur spécifique à ARM Cortex-M.

Changements cassants

  • src/kernel.c ne contient plus les définitions de registres brutes SYST_*, SCB_SHPR3, SCB_AIRCR, ou DWT_* — elles sont maintenant fournies par la HAL. Le code qui référençait directement ces macros doit être mis à jour pour utiliser l’API de la HAL.
  • Les symboles faibles de src/power.c (platform_enter_sleep_mode, etc.) délèguent maintenant à hal_platform_t->power lorsqu’une plateforme est enregistrée ; les cartes qui se reposaient sur l’ancien défaut __asm__ volatile("wfi") verront un comportement identique à moins qu’un hal_power_ops_t ne soit enregistré.
  • La version du système de fichiers sur disque est 0x00020000. Les volumes formatés avec v1.x doivent être reformatés (fs_format).

v1.2.0

Corrections de bugs

  • Table des vecteurs startup.s — MemManage_Handler, BusFault_Handler et UsageFault_Handler pointent maintenant vers les bons gestionnaires dans fault.c.
    Auparavant, les trois entrées pointaient vers Default_Handler, donc les défauts MPU, bus et usage étaient silencieusement avalés au lieu de déclencher le vidage diagnostic.
  • Double décrémentation de os_cond_wait — cond_remove_task() décrémente déjà waiting_count ; les trois sites d’appel qui le décrémentaient à nouveau ensuite ont été corrigés.
    Auparavant, une décrémentation supplémentaire intempestive pouvait faire sous-écouler le compteur et corrompre l’état de la variable condition.
  • Boost PIP du mutex non libéré sur timeout — le chemin d’attente temporisé dans os_mutex_lock appelle maintenant mutex_pip_recalculate() avant de renvoyer . Auparavant, le boost de priorité appliqué au propriétaire n’était jamais annulé lorsque la tâche en attente abandonnait, provoquant une inflation permanente de la priorité.

Améliorations

  • Réécriture de l’allocateur mémoire (src/memory.c) — remplacement du pool de blocs fixes de 32 octets par un allocateur premier ajustement offrant :
    • un tas de 8 Ko (contre 4 Ko auparavant), blocs alignés sur 8 octets
    • une liste libre maintenue dans l’ordre des adresses ; les blocs adjacents libres sont fusionnés immédiatement à chaque os_free() (avant et arrière)
    • les blocs sont divisés lors de l’allocation si le reste est assez grand pour être utile (≥ BLK_HDR + ALIGN)
  • Ordre d’initialisation de os_init() — os_mem_init() et os_power_init() sont maintenant appelées avant os_timer_init(), de sorte que le tas et le sous-système d’alimentation soient prêts avant que les callbacks de temporisateurs ou le code des tâches ne s’exécutent.
  • Veille sans tick implémentée (src/kernel.c: os_kernel_tickless_sleep) — lorsqu’elle est activée via os_power_enable_tickless_idle(true), la tâche d’inhibition supprime SysTick avant WFI et utilise le compteur de cycles DWT pour mesurer le temps réel écoulé. Après le réveil, SysTick est redémarré, est avancé du nombre de ticks mesurés (plafonné à ), et est appelée pour débloquer immédiatement les tâches en retard. Auparavant, le drapeau existait mais le chemin d’inhibition retombait toujours sur un simple avec SysTick en fonctionnement.

v1.1.0

Nouvelles fonctionnalités

  • Drapeau EVENT_WAIT_CLEAR pour les groupes d’événements — attend que les bits soient clairs (condition NON).
    EVENT_WAIT_ALL | EVENT_WAIT_CLEAR se réveille lorsque tous les bits masqués sont à 0 ; EVENT_WAIT_ANY | EVENT_WAIT_CLEAR se réveille lorsque l’un d’eux est à 0.
  • os_event_group_sync() — primitive de rendez-vous / barrière.
    Chaque tâche participante définit son propre bit d’arrivée et se bloque jusqu’à ce que l’ensemble complet soit présent ; tous se débloquent simultanément.
  • Nouvel exemple examples/event_flags_logic.c démontrant les quatre modes (ET, OU, NON, SYNC).

Correctifs de compilation et d’exécution

  • Ajout de src/startup.s : table des vecteurs, Reset_Handler (copie .data, mise à zéro .bss), squelette SysTick_Handler, HardFault_Handler.
  • Ajout de linker.ld : disposition mémoire pour mps2-an385 (Flash 0x00000000 / 4 Mo, RAM 0x20000000 / 4 Mo).
  • Correction de la pile initiale des tâches : la zone de sauvegarde R4–R11 est maintenant pré-allouée pour que LDMIA {R4-R11} de PendSV fonctionne correctement lors du premier changement de contexte vers toute tâche nouvellement créée.
  • SVC_Handler mis à jour pour exécuter LDMIA {R4-R11} avant de définir PSP, gardant ainsi les chemins SVC et PendSV symétriques.
  • Vérification de MPU_TYPE dans os_mpu_configure_default() — la configuration MPU est ignorée silencieusement lorsque aucun MPU n’est présent (QEMU ).

Licence

Licence MIT — voir LICENSE pour les détails.

Télécharger l’outil
CommandeDescription
help [cmd]Lister toutes les commandes, ou afficher une aide détaillée pour cmd
clearEffacer l'écran du terminal (VT100)
echo <text>Afficher du texte dans le terminal
historyAfficher l'historique des commandes
psLister toutes les tâches (état, priorité, % CPU, utilisation de la pile)
topListe des tâches triée par utilisation CPU, décroissante
kill <name> [suspend|resume|delete]Contrôler une tâche par son nom
memStatistiques du tas (total / utilisé / libre, compteurs alloc/libre)
verVersion de TinyOS et durée de fonctionnement formatée
netStatistiques réseau (compteurs Ethernet, IP, UDP, TCP)
ping <ip> [count]Envoyer des requêtes echo ICMP
ifconfig [ip|netmask|gw|dns <addr>]Afficher ou modifier la configuration réseau
power [active|idle|sleep|deepsleep]Statistiques d'alimentation ou changement de mode
ls [path]Lister le répertoire (défaut : /)
cat <file>Afficher le contenu d'un fichier
mkdir <path>Créer un répertoire
rm <path>Supprimer un fichier ou un répertoire vide
dfStatistiques d'utilisation du système de fichiers
touch <file>Créer un fichier vide
cp <src> <dst>Copier un fichier
uptimeAfficher la durée de fonctionnement du système (HH:MM:SS ou N jour(s), HH:MM:SS)
sleep <ms>Retarder la tâche shell de N millisecondes
rebootRedémarrer le système
ToucheAction
← / Ctrl-BDéplacer le curseur à gauche
→ / Ctrl-FDéplacer le curseur à droite
Home / Ctrl-ASauter au début de la ligne
End / Ctrl-ESauter à la fin de la ligne
↑ / ↓Naviguer dans l'historique des commandes
TabCompléter le nom de la commande
Ctrl-KSupprimer jusqu'à la fin de la ligne
Ctrl-USupprimer jusqu'au début de la ligne
Ctrl-WSupprimer le mot précédent
Ctrl-LEffacer l'écran et redessiner
Ctrl-CAnnuler la ligne en cours
ComposantROMRAM
Noyau6 Ko512 o
Par tâche—~1 Ko
Mutex—12 o
Sémaphore—8 o
File de messages (10 éléments)—40 o + données
Shell (avec 23 commandes intégrées)~4 Ko~2,5 Ko
Client MQTT (avec files)~8 Ko~10 Ko
Couche de threads POSIX~2 Ko~PTHREAD_MAX_THREADS × (tcb_t + 32 o)
Couche de sockets POSIX~1 Ko~NET_MAX_SOCKETS × 12 o
  • hal/hal.h — interface indépendante de l’architecture : tick, compteur de cycles, MPU, sauvegarde/restauration IRQ, déclencheur de changement de contexte, réinitialisation système, capture de défaut et tables d’opérations périphériques (hal_platform_t avec emplacements pour UART / flash / GPIO / SPI / I²C / alimentation).
  • hal/cortex_m/ — implémentation complète pour Cortex-M0–M7 (SysTick, DWT, AIRCR, PRIMASK, déclencheur PendSV).
  • hal/riscv/ — squelette RISC-V RV32 (tick CLINT MTIMECMP, compteur rdcycle, PMP, priorité PLIC, capture de défaut CSR).
  • hal/avr/ — squelette AVR ATmega (tick Timer0 CTC, sections critiques SREG, réinitialisation watchdog).
  • Le Makefile sélectionne automatiquement la HAL depuis ARCH= (cortex-m* / riscv* / avr*) et passe -DHAL_ARCH_* au compilateur.
OS_ERROR_TIMEOUT

CYCCNT

kernel.tick_count
TICKLESS_MAX_SLEEP_TICKS
delay_queue_tick()

WFI
  • MAX_TASKS augmenté — passé de 8 à 16 pour prendre en charge des charges de travail IoT plus réalistes sans modification de configuration côté utilisateur.
  • mps2-an385
  • Renommage de timer_t en os_timer_t pour éviter un conflit avec <sys/types.h> de POSIX.
  • Makefile : ajout de -I. pour les inclusions de drivers/ ; les sources TLS sont exclues automatiquement lorsque mbedTLS est absent ; -Wno-stringop-truncation pour les faux positifs d’avertissements strncpy.
  • Correction des avertissements sign-compare, unused-function, uninitialized-variable et implicit-declaration dans coap.c, filesystem.c, mqtt.c, ota.c, security.c, net/ip.c, net/http_dns.c.