Getting Started - amir1387aht/MicroCS GitHub Wiki
Getting started
This guide takes you from a fresh clone to a C# script running inside your own firmware.
1. Build the host tools
git clone https://github.com/amir1387aht/MicroCS && cd MicroCS
make # ā ./mcs (needs any C99 compiler; no other dependencies)
make test # optional: full test suite
./mcs is the compiler, the VM, a REPL and the standalone runtime in one binary.
2. Run your first script
// hello.cs
using System;
using System.Linq;
var squares = Enumerable.Range(1, 5).Select(i => i * i).ToList();
Console.WriteLine($"squares: {string.Join(", ", squares)}");
var (min, max) = (squares.Min(), squares.Max());
Console.WriteLine($"range {min}..{max}, last = {squares[^1]}");
./mcs hello.cs
# squares: 1, 4, 9, 16, 25
# range 1..25, last = 25
./mcs --repl --sim # the device REPL, with a simulated board
3. Talk to (simulated) hardware
The --sim flag gives scripts a virtual board with every peripheral (GPIO with interrupts,
UART, I²C sensors, SPI, ADC, DAC, PWM, timers, I²S, QSPI flash, CAN, watchdog, RTC), and
--run-for lets the job scheduler run for a while:
./mcs --sim examples/hardware/01_blink.cs
./mcs --sim examples/hardware/05_i2c_temperature.cs
./mcs --sim --ramfs 16384 --run-for 1200 examples/hardware/16_data_logger.cs
./mcs --sim --sim-log tests/t08_hal.cs # trace every peripheral access
All 16 hardware examples are listed in examples/README.md. The peripheral API is documented in HAL.md, the scheduler in SCHEDULER.md, files in FILESYSTEM.md.
4. Precompile for a device
On small parts, compile on the PC and ship only the VM:
./mcs -c app.cs -o app.mcsb # image file (copy to the device FS)
./mcs -C app.cs -n app_image -o app_image.h -s # const array to link into flash
./mcs -d app.mcsb # check what is inside
./mcs --xip app.mcsb # run it the way mcs_exec_image_xip() does on flash
A runtime-only build (-DMCS_ENABLE_COMPILER=0) saves ~44 KB of flash and the compiler's
RAM. Images are portable between 32- and 64-bit hosts. Format: BYTECODE.md.
For 32ā64 KB RAM parts see LOW_RESOURCE.md.
5. Embed the VM in firmware (Option 1)
- Add MicroCS to your build ā
include microcs.mk,add_subdirectory(MicroCS), an ESP-IDF component, a Zephyr module, a PlatformIO/Arduino library, or just the.cfiles in your IDE. Every variant is in PORTING.md. - Optional: configure it. Copy
config/mcs_user_config.hinto your project asmcs_user_config.hā it holds every option with its default value ā and edit the values you change. For another profile's defaults generate it:python3 tools/gen_config.py --profile embedded -o mcs_user_config.h(auto,min,tiny,mcu,lowram,embedded,linuxā seeinclude/profiles/).-Dā¦options work too and win over the header. Details: CONFIGURATION.md. - Create a VM on a static pool and run a script (a runnable version is
examples/quickstart_embed.c,make quickstart):
#include "mcs.h"
#include "app_image.h" /* generated by: ./mcs -C app.cs -n app_image -o app_image.h */
static uint8_t heap[128 * 1024];
static mcs_pool_t pool;
void scripts_main(void) {
mcs_config_t cfg; mcs_config_default(&cfg);
mcs_pool_init(&pool, heap, sizeof heap);
cfg.realloc_fn = mcs_pool_realloc; cfg.alloc_ud = &pool;
cfg.heap_limit = sizeof heap - 2048;
cfg.write_fn = my_uart_write; /* Console.Write* */
cfg.ticks_fn = my_millis; /* time, limits, scheduler */
mcs_vm_t* vm = mcs_new(&cfg);
if (mcs_exec_image(vm, app_image, app_image_len) != MCS_OK)
my_log("script failed: %s", mcs_last_error(vm));
mcs_free(vm);
}
To let C# use the board's peripherals, add a port and one line:
mcs_stm32_hal_init(&hal, &board); mcs_hal_open_lib(vm, &hal); (or mcs_esp32_ā¦,
mcs_rp2_ā¦, mcs_zephyr_ā¦, mcs_arduino_ā¦). Full walkthrough with C bindings, calling
script functions from C, limits and the GC contract: EMBEDDING.md.
6. A complete C# firmware with a REPL (Option 2)
mcs_runtime_run() turns the board into a C# device: REPL on the console, /boot.cs and
/main.cs from the filesystem, jobs, interrupt callbacks and an upload protocol. Start from
a ready-made project ā Pico, ESP32,
STM32 CubeMX, Zephyr,
Arduino ā then upload programs from the PC:
./mcs --shell --fs device_root # try the protocol on the host first
python3 tools/mcs_remote.py --exec "./mcs --shell --fs device_root" put app.cs /main.cs + run /main.cs
python3 tools/mcs_remote.py --port /dev/ttyACM0 repl # on a real board
Details: STANDALONE.md.
Where next?
- What C# works ā LANGUAGE.md Ā· what you can call ā STDLIB.md
- How it works inside ā ARCHITECTURE.md
- Numbers ā PERFORMANCE.md Ā· safety model ā SECURITY.md