Skip to main content

Getting Started with Endpoint

Endpoint runs full .NET, Python, and C/C++ on a circuit. All three share one set of APIs, so what you learn in one language travels with you. You deploy and debug applications over a USB cable, no SSH, with no keys, passwords, or IP addresses.

Evaluation hardware

Endpoint Domino24 is the evaluation board we built for Endpoint. We have not released SoMs or dev boards yet, because we are still shaping what the commercial product should be. Tell us what you need on the forum: what form factor, which peripherals, and whether wireless is a requirement.

Languages and tools​

LanguageVersionVS CodeVisual Studio
C#.NET 11YesYes
PythonPython 3.14YesNo
C and C++C23 and C++23, with no toolchain to installYesNo

What you'll need​

  • Endpoint Domino24
  • A USB-C cable
  • A microSD card of at least 4 GB
  • VS Code for any language, or Visual Studio for .NET

Step 1: Prepare the board​

  1. Download the latest Endpoint OS image from the Downloads page.
  2. Write the image to the microSD card with a disk imaging tool such as balenaEtcher.
  3. Insert the card into Domino24 and connect it to your PC with the USB-C cable.
  4. Wait for the USER LED to light, which shows the board has finished booting.

Step 2: Install the extension​

Visual Studio supports .NET (C#).

  1. Visual Studio 2026 (Community, Professional or Enterprise). VS 2022 17.9+ also works.
  2. The matching .NET SDK installed and on PATH (download).
  3. The Endpoint Debugger extension from the Visual Studio Marketplace. In Visual Studio, open Extensions > Manage Extensions and search for "Endpoint".

Step 3: Create a project​

Every Endpoint template is a ready-to-run blink application: it blinks the USER LED and prints a counter. Core and GPIO are referenced out of the box, so the project builds and runs without any extra setup.

  1. File > New > Project... → search "Endpoint" → choose Endpoint App (C#). Give it a name and location.

    Endpoint App (C#) template in the Visual Studio new-project dialog

Step 4: Deploy and run​

Make sure the USER LED on the board is on. A lit USER LED means the board has finished booting and is ready to accept a new program. If the LED is still off, wait a few seconds; a cold boot takes about three.

Press F5 or Ctrl+F5. Either command stops any application currently running on the board, including one set to run at boot, before deploying the new build, so you never need to disable the previous program by hand.

Press F5. Visual Studio builds the project, deploys it to the board over USB, and starts it under the debugger. Breakpoints, step, locals, and watch work as usual.

The USER LED blinks every 500 ms, and the Output window prints one counter line per blink:

Hello Endpoint. Counter: 1
Hello Endpoint. Counter: 2
Hello Endpoint. Counter: 3
...

Project settings live under the project's Endpoint property page:

Endpoint project settings in Visual Studio

  • Transport: how Visual Studio talks to the board. USB today.
  • Device: Endpoint runs the program on the board; Desktop runs it locally on the PC for quick checks.
  • Firmware: check for updates, erase the application that is set to run at boot.

Run at boot: press Ctrl+F5 instead of F5. The project is compiled with Native AOT and set to start automatically on power-on. A C# blink application goes from power-on to running in under three seconds.

Step 5: Add a package​

A new project already references Core and GPIO. Add the other Endpoint drivers (ADC, DAC, PWM, Display, Touch, Camera, Network, UI, and more) or any third-party library when you need them, and update to a newer version the same way.

From the project folder, add or update a package with dotnet add package:

dotnet add package GHIElectronics.Endpoint.Devices.Adc --prerelease

In Visual Studio, use Manage NuGet Packages... on the project and check Include prerelease during the 0.5.x preview. Every third-party NuGet package installs the same way.

Step 6: Resources​

Apps often need to ship data files: images for the UI, fonts for text, binary blobs for an attached chip, configuration text, TLS certificates. Endpoint gives you two ways to carry them with your program.

Load from file​

The portable approach: drop the file into your project folder, F5 copies it to the board alongside your program, read it at runtime from the folder next to your app. Works identically in .NET, Python, and C/C++.

using System.IO;
using GHIElectronics.Endpoint.Drawing;

var dir = AppContext.BaseDirectory;

// JPG
var imgBytes = File.ReadAllBytes(Path.Combine(dir, "resource_bg.jpg"));
var img = Image.Load(imgBytes);
canvas.DrawImage(img, 0, 0);

// Font
var fontBytes = File.ReadAllBytes(Path.Combine(dir, "Montserrat.ttf"));
using var font = Font.Load(fontBytes);
canvas.DrawText("Hello", font, 20, 60, 32, Color.White);

// Binary (push to SPI)
spi.Write(File.ReadAllBytes(Path.Combine(dir, "data.bin")));

// Text
var text = File.ReadAllText(Path.Combine(dir, "message.txt"));
Console.WriteLine(text);

Add this once to your .csproj so the files land next to the DLL:

<ItemGroup>
<Content Include="Resources\**\*" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

Everything under Resources\ is now deployed automatically.

Embedded Resource (.NET only)​

.NET lets you bake files into the compiled DLL so your app ships as a single binary. Python and C/C++ do not have this; use the file approach above.

In Visual Studio, right-click the file in Solution Explorer, Properties, Build Action = Embedded Resource. In VS Code, edit the .csproj directly:

<ItemGroup>
<EmbeddedResource Include="logo.jpg" />
<EmbeddedResource Include="Montserrat.ttf" />
<EmbeddedResource Include="data.bin" />
<EmbeddedResource Include="config.txt" />
</ItemGroup>

Tip: <EmbeddedResource Include="Resources\**\*" /> embeds everything under a Resources\ folder without listing files individually.

Read at runtime with Assembly.GetManifestResourceStream:

using System.IO;
using System.Reflection;
using System.Text;

static byte[] ReadResource(string name) {
using var s = Assembly.GetExecutingAssembly().GetManifestResourceStream(name)
?? throw new InvalidOperationException($"Resource '{name}' not found");
var buf = new byte[s.Length];
s.ReadExactly(buf);
return buf;
}

var jpg = ReadResource("MyApp.logo.jpg");
var ttf = ReadResource("MyApp.Montserrat.ttf");
var blob = ReadResource("MyApp.data.bin");
var text = Encoding.UTF8.GetString(ReadResource("MyApp.config.txt"));

The resource name is <RootNamespace>.<folder-with-dots>.<filename>. To see the exact names baked into your DLL:

foreach (var n in Assembly.GetExecutingAssembly().GetManifestResourceNames())
Console.WriteLine(n);

What's next​

  • Hardware: Domino24's pinout, displays, cameras, and expansion headers.
  • Features: GPIO, buses, displays, networking, and more.