# Sistema operativo real-time

Un sistema operativo real-time o in tempo reale (abbreviato in RTOS) è un sistema operativo specializzato per il supporto di applicazioni su sistemi real-time. Questi sistemi vengono utilizzati tipicamente in ambito industriale (controllo di processo, pilotaggio di robot, trasferimento dati nelle telecomunicazioni) o comunque dove sia necessario ottenere una risposta dal sistema entro un tempo prefissato.
Un sistema operativo real-time non deve essere necessariamente veloce: non è importante l'intervallo di tempo in cui il sistema operativo/applicativo deve reagire; l'importante è che risponda entro un tempo massimo pre-determinato. In altre parole il sistema deve essere prevedibile o piuttosto deterministico, nel senso che nel sistema si possa conoscere il tempismo reale (nei migliori o peggiori dei casi, termini che vengono dall'inglese best case / worst case) di un determinato processo o elaborazione.
In pratica un sistema real-time deve garantire che una elaborazione (o task) termini entro un dato vincolo temporale o scadenza (detta in gergo deadline). Per garantire questo è richiesto che la schedulazione delle operazioni sia fattibile. Il concetto di fattibilità di schedulazione è alla base della teoria dei sistemi real-time ed è quello che ci permette di dire se un insieme di task sia eseguibile o meno in funzione dei vincoli temporali dati.

## Task periodici/aperiodici e hard/soft real-time

I task di un sistema real-time possono essere:
* periodici: quando un task consiste in una sequenza di attività attivate con cadenza regolare
* aperiodici: quando un task consiste in una sequenza di attività attivate ad intervalli irregolari.
* sporadici: quando un task consiste in una sequenza di attività attivate in maniera impredicibile (tipicamente task che corrispondono a richieste di utenti)
I task di tipo periodico sono propri di un sistema di controllo tempo discreto.
Quando si ha a che fare con task di tipo periodico si parla anche di periodo di esecuzione con il quale si intende il lasso di tempo che intercorre tra due esecuzioni di un task periodico. È uso comune far coincidere la deadline con l'inverso del periodo poiché questo è il limite massimo di esecuzione di un task.
I task di un sistema real-time possono però essere:
* soft real-time: un task che non rispetta la sua scadenza (in gergo si dice sfondare la deadline) provoca un danno non irreparabile al sistema. Il superamento della deadline produce un degrado delle prestazioni proporzionale al tempo di superamento della deadline.
* hard real-time: un task che nel caso superi temporalmente la sua deadline provoca un danno irreparabile al sistema.
* "anytime" : sono tasks che elaborano iterativamente gli stessi dati per "raffinarli" sempre di più. I dati elaborati dai tasks anytime rispondono a requisiti di qualità minima e qualità massima. Sono quindi considerati "hard" fino a che i dati non raggiungono la qualità minima, diventano "soft" prima di raggiungere la qualità massima, dopodiché non verranno più eseguiti
Sostanzialmente questa distinzione si traduce nella diversa quantificazione dei costi di una possibile inesattezza temporale del sistema. Un esempio di task soft real-time può essere un riproduttore DVD, in cui il mancato rispetto dei vincoli si traduce in un degrado della qualità del filmato, ma non pregiudica il proseguimento della riproduzione; mentre un task hard real-time può essere il controllore della temperatura del nocciolo di una centrale nucleare, dove il mancato rispetto dei vincoli temporali può provocare un evidente disastro.

## Caratteristiche di un sistema real-time

Un sistema real-time dovrebbe possedere le seguenti caratteristiche:
* Schedulazione ottima: tutti i task sono noti a priori così come i vincoli temporali, dovrebbe essere possibile dunque avere uno schedulatore che implementi una schedulazione che minimizzi al massimo la funzione di costo $K_{S}$ presentata prima.
* Condivisione delle risorse: i task sono entità separate ma che concorrono ad uno stesso scopo, pertanto non è necessario avere spazi di indirizzamento separati.
* Garanzia di esecuzione: tutti i task di tipo hard real-time devono terminare entro le proprie deadline quindi, nel caso in cui arrivi un nuovo task o un task non possa completare entro la deadline, una notifica anticipata del sistema può essere utilizzata per impedire l'esecuzione del nuovo task o di recuperare l'esecuzione del task che sta per sfondare.
* Prevedibilità delle chiamate di sistema: il sistema deve essere in grado di valutare i tempi di calcolo di ogni task per determinare la schedulazione fattibile, quindi ogni chiamata di sistema deve avere un tempo di esecuzione massimo ben definito in modo da non introdurre ritardi indefiniti.

## Scheduling di sistemi Real Time

Gli algoritmi di scheduling più utilizzati per i sistemi real time sono essenzialmente tre:
* EDD (Earliest Due Date)
* EDF (Earliest Deadline First)
* RM (Rate Monotonic)
L'EDD ha le seguenti caratteristiche
* Tutti i task arrivano simultaneamente
* La priorità è statica
* Non necessita di prelazione
* Minimizza la latenza.
L'EDF ha le seguenti caratteristiche:
* I task possono arrivare in un qualsiasi istante.
* Priorità dinamica in base alla scadenza imminente.
* Utilizza la capacità dei task di fare prelazione su altri.
* Minimizza la latenza.
RM è utilizzabile solo per task periodici, ha le seguenti caratteristiche:
* Ai task viene assegnata una priorità statica proporzionale alla frequenza di arrivo.
* Un gruppo di task è schedulabile se conosciuta la funzione di utilizzazione U è U_lub<U<1
La funzione U esprime il tasso di utilizzazione del processore, la funzione risulta limitata superiormente ed è SupU=1,indicato con U_lub fattore di utilizzazione minimo. Diremo che una funzione è certamente schedulabile con Rate Monotonic se U<U_lub, risulta invece non schedulabile se U>1. Se U_lub<U<1 non abbiamo certezza sulla schedulabilità. L'algoritmo EDF in alcune circostanze risulta migliore di RM perché garantisce la schedulabilità semplicemente per U<1

## I fattori che minano la prevedibilità

I prodotti delle famiglie Windows e Unix non soddisfano le caratteristiche tipiche di un sistema real-time: ad esempio, pur gestendo l'esecuzione di più processi con pre-rilascio, non è possibile prevedere in alcun modo quale sarà il tempo di esecuzione di un singolo processo. Inoltre l'utilizzo di hard disk per la conservazione dei dati, dispositivi USB o altri dispositivi che introducono forti latenze di esecuzione da parte della CPU, rende impossibile stabilire con certezza quanto tempo sarà necessario per reperire l'informazione utile alla corretta esecuzione del codice.
Ci sono diversi fattori che causano la non prevedibilità nella risposta del sistema operativo. Tra di essi, i principali sono i seguenti:
* Il DMA: può limitare o bloccare il bus dalla CPU, ritardando l'esecuzione di un task critico. In un sistema real-time si preferisce quindi disattivarlo o usarlo in modalità timeslice dove si assegna in maniera costante e fissa il bus al DMA anche se non ci sono operazioni da fare.
* La cache: può causare non prevedibilità poiché esistono casi in cui essa fallisce e può causare ritardi nell'accesso alla memoria da parte della CPU. Dovendo considerare quindi il caso peggiore si preferisce non usarla affatto.
* Meccanismi di gestione della memoria: queste tecniche non devono introdurre ritardi non prevedibili durante l'esecuzione di task critici, ad esempio la paginazione può causare dei page fault intollerabili per un sistema hard real-time. Tipicamente si usa la segmentazione o la partizione statica della memoria.
* Le interruzioni: sono generate da dispositivi periferici quando hanno qualche informazione da scambiare con la CPU. Queste interruzioni durante l'esecuzione di un task critico generano ritardi non prevedibili e quindi si preferisce disattivarle.
* I sistemi di power management: sono meccanismi hardware che possono rallentare la CPU o far eseguire ad essa del codice utile a dissipare minor energia. È chiaro che in un sistema real-time è importante rispettare una deadline piuttosto che consumare poca energia, quindi questi meccanismi vengono disattivati.

## Scelta del sistema operativo real time

Tra gli RTOS commerciali troviamo il POSIX-conformant (ad esempio LynxOS che è Unix compatibile) e non POSIX-conformant come ad esempio VxWorks (che supporta in parte gli standard POSIX). Per quanto riguarda i sistemi Open Source è possibile l'uso di Linux, con opportune precauzioni, o di RTAI/Xenomai.

### Problemi del real-time in Linux

* Lo scheduler, che ha come obiettivo l'assegnazione della CPU ai vari processi, non può conoscere i requisiti temporali dei vari processi real-time.
* Anche se si usa la schedulazione FIFO o FIFO Round Robin che tendono ad aumentare la prevedibilità del sistema, non si hanno comunque garanzie sui ritardi introdotti dalle chiamate di sistema e dalle attività del kernel.

## Esempi di sistemi operativi RT

Alcuni sistemi operativi in grado di lavorare in real-time su adeguate architetture hardware sono:
| Nome | Licenza | Codice Sorgente | Utilizzi | Stato | Piattaforma |
| Apache Mynewt | Apache 2.0 | open source | embedded | attivo | ARM Cortex-M, MIPS32, Microchip PIC32, RISC-V |
| BeRTOS | Modified GNU GPL | open source | embedded | archiviato | ARM, Cortex-M3, ARM ARM7TDMI, Atmel AVR, PowerPC (emu), x86 (emu), x86-64 (emu) |
| ChibiOS/RT | GPL o commerciale | open source | embedded | attivo | x86, ARM7, ARM9, Cortex-M0-M3-M4, PowerPC e200z, STM8, STM32, AVR, MSP430, ColdFire, H8S |
| ChorusOS | ? | ? | ? | terminato | SPARC, x86, PowerPC |
| Contiki | BSD | open source | embedded, WSN | attivo | MSP430, AVR, ARM |
| Data General RDOS | Proprietaria | ? | general purpose | terminato | Data General Nova, Data General Eclipse |
| Deos | Proprietaria | chiusa | safety critical | attivo | x86, PowerPC, ARM, MIPS |
| DioneOS | Proprietaria | disponibile con licenza | embedded | attivo | MSP430, MSP430x |
| DNIX | Proprietaria | chiusa | general purpose | terminato | Motorola 68000 |
| GEC DOS | Proprietaria | chiusa | process control | terminato | GEC 4000 series |
| DSOS | Proprietaria | chiusa | ? | terminato | TI-980A minicomputer |
| DSP/BIOS | Proprietaria | chiusa, disponibile con licenza | general purpose | manutenzione | La maggior parte dei chip Texas Instruments C2800, C5500, C6000 e OMAP DSP cores. Sostituito da TI-RTOS, ma ancora disponibile per il download. |
| eCos | Modified GNU GPL | open source | embedded | inattivo | ARM-XScale-Cortex-M, CalmRISC, 680x0-ColdFire, fr30, FR-V, H8, IA-32, MIPS, MN10300, OpenRISC, PowerPC, SPARC, SuperH, V8xx |
| eCosPro | Modified GNU GPL | open source con parti a pagamento | embedded | attivo | ARM7-9, Cortex-A5-A9-M3-M4-M7, 680x0-ColdFire, H8-H8S, IA-32, MIPS32, MIPS64, microMIPS, NIOS II, OpenRISC, PowerPC, SPARC, SH4/4A, TILE-Gx, XScale |
| embOS | Proprietaria | chiusa, adisponibile ai clienti, parti libere per fini non commerciali. | embedded, industrial, IoT, safety critical | attivo | ARM7/9/11, ARM Cortex-A/R/M, AVR, AVR32, C16x, CR16C, ColdFire, H8, HCS12, M16C, M32C, MSP430, NIOS2, PIC18/24/32, R32C, R8C, RISC-V, RL78, RH850, RX100/200/600/700, RZ, SH2A, STM8, ST7, V850, 78K0, 8051 |
| ERIKA Enterprise | GPL e GPL linking exception | open source | embedded | attivo | ARM7, ARM Cortex-M, ARM Cortex-A, Hitachi H8, Altera Nios2, Microchip dsPIC (inclusi dsPIC30, dsPIC33 e PIC24), Microchip PIC32, ST Microelectronics ST10, Infineon C167, Infineon Tricore, Freescale PPC e200 (MPC 56xx) (inclusi PPC e200 z0, z6, z7), Freescale S12XS, EnSilica eSi-RISC, AVR, Lattice Mico32, MSP430, Renesas RX200, x86-64 |
| EROS | Modified GNU GPL | open source | experimental research use | dormant | IA-32 |
| FlexOS | Proprietaria | chiusa | general purpose, industrial, POS | terminato | 186, 286, 386, V60, V70, 68000 |
| FreeRTOS | MIT | open source | embedded | attivo | ARM, AVR, AVR32, ColdFire, ESP32, HCS12, IA-32, Cortex-M3-M4-M7, Infineon XMC4000, MicroBlaze, MSP430, PIC, PIC32, Renesas H8/S, RISC-V, RX100-200-600-700, 8052, STM32, TriCore, EFM32 |
| Fuchsia | | open source | AArch64, x86-64 | attivo |
| Keil RTX | Apache 2.0 | open source | embedded | attivo | Arm Cortex-M |
| FunkOS | Modified Sleepycat License | open source | embedded | attivo | AVR, MSP430, Cortex-M3 |
| HeartOS | Proprietaria | chiusa | safety critical | attivo | x86, PowerPC, ARM |
| Huawei LiteOS | BSD | open source | embedded | terminato | ARM (M0/3/4/7, A7/17/53, ARM9/11), x86, RISC-V |
| HarmonyOS | Proprietaria | chiusa | embedded | attivo | AArch64, x86-64, RISC-V, LingxiISA |
| IBM 4680 OS | Proprietaria | chiusa | general purpose, industrial, POS | terminato | 286 |
| IBM 4690 OS | Proprietaria | chiusa | general purpose, industrial, POS | attivo | 286, 386 |
| INTEGRITY | Proprietaria | chiusa | embedded | attivo | ARM, XScale, Blackfin, ColdFire, MIPS, PowerPC, x86 |
| INtime | Proprietaria | chiusa | embedded | attivo | x86 |
| ITRON | T-License | varia | embedded | attivo | ARM, MIPS, x86, Renesas RX100-200-600-700-altri |
| Kaspersky OS | Proprietaria | open source | safety critical, virtualization | attivo | x86, x86_64, ARMV5, ARMV7, ARMV8, MIPS32 |
| KolibriOS | GPL | open source | embeddable | attivo | x86 |
| LynxOS | Proprietaria | source available | embedded | attivo | Motorola 68010, x86/IA-32, ARM, Freescale PowerPC, PowerPC 970, LEON |
| Mbed OS | Apache 2.0 | open source | embedded | attivo | Arm Cortex-M |
| MenuetOS | GPL | open source | ? | attivo | IA-32 |
| MERT | Proprietaria | chiusa | OS for long-distance telephone switching systems | inattivo | PDP-11 |
| MicroC/OS-III | Apache 2.0 | open source | embedded | attivo | ARM7-9-11/Cortex-M1-3-4-A8/9, AVR, HC11/12/S12, ColdFire, Blackfin, MicroBlaze, NIOS, 8051, x86, Win32, H8S, M16C, M32C, MIPS, 68000, PIC24/dsPIC33/PIC32, MSP430, PowerPC, SH, StarCore, Renesas RX100-200-600-700, RL; STM32, ... |
| MontaVista Linux | GPL | open source | embedded | ? | |
| MP/M | Proprietaria | chiusa | general purpose, industrial | terminato | 8080, Z80, 8086 |
| MQX | Proprietaria | sorgente free disponibile | embedded | attivo | Freescale Power, ColdFire, Kinetis Cortex ARM |
| Multiuser DOS | Proprietaria | chiusa | general-purpose, industrial | terminato | 386 |
| Nano-RK | GPL o commerciale | open source | embedded, WSN | terminato | AVR, MSP430 |
| Neutrino | Proprietaria | some source provided | microkernel, embedded, industrial | attivo | ARM, ARM64, MIPS, PPC, SH, x86, x86-64, XScale |
| Nucleus RTOS | Proprietaria | source provided | embedded | attivo | ARM (Cortex-M3-M4-R4-R4F-A8-A9, ARM7-9-11), PowerPC, MIPS32-16e, microMIPS, ColdFire, SuperH |
| NUT | Proprietaria | open source | embedded, industrial | attivo | ARM-M0, ARM-M0+, ARM Cortex-M3, ARM9, ARM Cortex-M7, Cortex-M3 |
| Nut/OS | BSD | open source | embedded, industrial | attivo | AVR, AVR32, ARM7, ARM9, Cortex-M3 |
| NuttX | Apache 2.0 | open source | embedded | attivo | Linux user mode, ARM7-9, Cortex-A5-A8-A9-M0-M3-M4-M7, 8052, Espressif ESP32, Lattice LM32, Renesas MC16C/26/SH-1, RISC-V, Zilog Z16F, Zilog eZ80 Acclaim!, Zilog Z8Encore!, Z80, MIPS PIC32MX, PIC32MZ |
| OpenComRTOS | Proprietaria | sorgente disponibile | embedded | attivo | Freescale PowerPC, Texas Instruments C66xxx DSP, ARM, XMOS, MicroBlaze, LEON, NXP CoolFlux DSP, Melexis MLX16, Win32, Linux |
| OS2000 | Proprietaria | ? | embedded | attivo | MIPS, KOMDIV-32, KOMDIV-64, Intel BSPs (x86) |
| OS4000 | Proprietaria | chiusa | process control | maintenance only | GEC 4000 series |
| OSE | Proprietaria | disponibile ai clienti | general purpose | attivo | ARM, PowerPC, x86, TI OMAP, ... |
| OS-9 | Proprietaria | disponibile ai clienti | embedded | attivo | ARM-strongARM, MIPS, PowerPC, SuperH, x86/Pentium, XSCALE, Motorola 6809, 680x0, SPARC |
| OSEK | GPL o commerciale | specification | embedded | attivo | Engine Control Units |
| Phoenix-RTOS | BSD | open source | embedded | attivo | ARMv7 Cortex-M, ARMv7 Cortex-A, IA-32, RISC V |
| PikeOS | Proprietaria | disponibile ai clienti | certifiable safety & security, embedded virtualisation | attivo | PPC, x86, ARM, MIPS, SPARC-LEON, RISC-V |
| Protothreads | BSD | open source | general purpose | attivo | Architetture indipendenti |
| pSOS | Proprietaria | ? | ? | discontinued | 680x0 |
| PX5 RTOS | Proprietaria | royalty-free | embedded | attivo | Embedded MCU e architetture MPU. ARM Cortex-M, Cortex-R, Cortex-A, RISC-V. AMP e configurazioni SMP. |
| QNX | Proprietaria | ? | microkernel, embedded, industrial | attivo | attivo |
| QP | GPL o commerciale | dual | MCU, DSC, DSP SoC | attivo | ARM7/9, ARM Cortex-M3-M0, MSP430, TMS320C28x, AVR, AVRXmega, ColdFire, 68HC08, M16C/R8C, H8, 8051, 80251, PIC18, PIC24/dsPIC33, Nios II, PSoC1 |
| REAL/32 | Proprietaria | chiusa | general-purpose, industrial | attivo | 386 |
| Real-time Linux (PREEMPT RT) | GPL | open source | general purpose | attivo | x86, x86_64, RISC-V, ARM64 e LoongArch (ARM e POWER nel -rt branch) |
| REX OS | Proprietaria | chiusa, disponibile con licenza. | embedded | inattivo | ARM |
| RIOT | GPL | open source | embedded | attivo | ARM7, ARM Cortex M, MSP430, AVR, RISC-V, Xtensa |
| RMX | Proprietaria | chiusa | embedded | terminato | Intel 8080, 8086, 80386 |
| RODOS | BSD | sorgente disponibile | embedded | attivo | ARMv7 (M3, A8, A9), AVR32, PowerPC 405, SPARC64 Platforms: SmartFusion2, RaspberryPi, STM32 su: Linux, Windows, macOS, FreeRTOS, RTEMS |
| RSX-11 | Proprietaria | ? | ? | historic | PDP-11 |
| RT-11 | Proprietaria | ? | general purpose | terminato | PDP-11 |
| RTAI | GPL | open source | general purpose | attivo | x86 (with and without FPU and TSC), x86-64, PowerPC, ARM (StrongARM; ARM7: clps711x-family, Cirrus Logic EP7xxx, CS89712, PXA25x), m68k |
| RTEMS | BSD | open source | embedded | attivo | AArch64, ARM, Blackfin, ColdFire, TI C3x/C4x, H8/300, x86, x86_64, 68k, Microblaze, Milkymist SoC, MIPS, Nios II, PowerPC, SuperH, SPARC, ERC32, LEON, Mongoose-V |
| RTLinux | GPL | open source | general purpose | inattivo | Vedi Linux |
| RT-Thread | Apache 2.0 | open source | embedded | attivo | ARM, ARM Cortex-M0-M3-R4-M4-M7, IA-32, AVR32, Blackfin, nios, PPC, M16C, MIPS, MicroBlaze, V850, unicore32, |
| RTXC Quadros | Proprietaria | sorgente disponibile | embedded | attivo | ARM - Atmel/Freescale/NXP/ST/TI, Blackfin, 680x0-ColdFire, PowerPC, StarCore, TI-Luminary Stellaris, TI OMAP, XScale |
| RTX, RTX64 | Proprietaria | chiusa | MS Windows extension | attivo | x86, x86-64 |
| RX116 | ? | ? | embedded, industrial | terminato | NEC V20, NEC V30, NEC V40, NEC V50 |
| RX616 | ? | ? | safety critical, embedded, industrial | terminato | NEC V60, NEC V70 |
| RX-UX832 | ? | ? | embedded, industrial, general-purpose | terminato | NEC V60, NEC V70 |
| SafeRTOS | Proprietaria | codice sorgente & Design Assurance Pack disponibili | embedded, safety critical | attivo | Vedi FreeRTOS |
| SHaRK | GPL | open source | ? | inattivo | ? |
| Simulink Real-Time | Proprietaria | chiusa | real-time testing-embedded | attivo | x86 |
| SINTRAN III | Proprietaria | ? | ? | ? | Norsk Data |
| Symbian OS | Eclipse | open source | embedded | terminato | ARM |
| T-Kernel | T-License | sorgente disponibile | embedded RTOS | attivo | ARM, MIPS, SH, altri |
| THEOS | Proprietaria | ? | ? | ? | ? |
| ThreadX | MIT | open source | embedded, IoT, safety critical | attivo | ARC, ARM/Thumb, AVR32, BlackFin, 680x0-ColdFire, H8-300H, Luminary Micro Stellaris, M-CORE, MicroBlaze, PIC24-dsPIC, PIC32, MIPS, V8xx, Nios II, PowerPC, Renesas RX100, RX200, RX600, RX700, Synergy, SH, SHARC, StarCore, STM32, StrongARM, TMS320C54x, TMS320C6x, x86/x386, XScale, Xtensa/Diamond, ZSP |
| TI-RTOS Kernel (SYS/BIOS) | BSD | open source | embedded | attivo | Texas Instruments: MSP430-432, C2000-5000-6000, TI ARM (Cortex M3-4F-R4-A8-A15), SimpleLink Wireless CC2xxx-CC3xxx |
| TizenRT | Apache 2.0 | open source | embedded | attivo | |
| Transaction Processing Facility | Proprietaria | mista | general purpose | attivo | IBM Z |
| TRON project | Libera | mista | mixed | attivo | |
| UNIX-RTR | ? | ? | ? | terminato | PDP-11 |
| UNOS | ? | ? | ? | historic | 680x0 |
| μITRON | T-License | open source | embedded | attivo | ARM, MIPS, x86, Renesas RX100-200-600-700-altri |
| μ-velOSity | Proprietaria | ? | microkernel | attivo | ? |
| velOSity | Proprietaria | ? | ? | attivo | Power ISA, ARM/XScale, MIPS, x86/Pentium, ColdFire, Blackfin, OMAP, DaVinci |
| VAXELN | Proprietaria | closed source | ? | historic | VAX |
| VRTX | Proprietaria | ? | ? | superseded by Nucleus RTOS | ARM, MIPS, PowerPC, RISC |
| VxWorks | Proprietaria | ? | embedded | attivo | ARM, IA-32, Intel 64, MIPS, PowerPC, SH-4, StrongARM, xScale |
| Windows CE | Proprietaria | Microsoft Shared Source | embedded | attivo | x86, MIPS, ARM, SuperH |
| Windows 10 IoT | Proprietaria | ? | embedded | attivo | Intel Atom, Celeron, Pentium; Qualcomm Snapdragon, Broadcom, NXP i.MX |
| Xenomai | GPL | open source | general | attivo | x86, x86-64, PowerPC, ARM, Analog Devices Blackfin BF52x, BF53x, BF54x e BF56x |
| XINU | Libera | open source | embedded | attivo | x86, MIPS, ARM, AVR |
| XMK | BSD | open source | embedded | inattivo | |
| Zephyr | Apache 2.0 | open source | embedded | attivo | ARM (Cortex-M0, -M3, -M4, -M23, -M33, -R4, -R5, -A53), x86, ARC, RISC-V, Nios II, Xtensa, SPARC |