File System
File access is standard .NET (System.IO.File, Directory, Stream) on
the on-board storage, SD cards and USB drives. The Endpoint-specific
GHIElectronics.Endpoint.Devices.Storage package handles the hot-plug
events and mount folder for removable media.
- On-board storage: always mounted and available to
System.IOthe moment your program starts. The partition at/data/is where deployed applications live. - SD card: mounts at
/media/sd/when a card is present. - USB mass storage: each drive gets the next free
/media/usbN/folder, the same way Windows gives each one the next free drive letter.
SD card
Open the SD-card controller, subscribe to ConnectionChanged, and mount
the drive when it connects. Everything from System.IO then works against
the returned path.
- .NET
- Python
- C/C++
using GHIElectronics.Endpoint.Core;
using GHIElectronics.Endpoint.Devices.Storage;
var sd = StorageController.FromName(EPDomino24.StorageController.SdCard);
sd.ConnectionChanged += (sender, e) => {
if (e.DeviceStatus == DeviceConnectionStatus.Connected) {
var drive = FileSystem.Mount(e.Hdc); // "/media/sd/"
File.WriteAllText(Path.Combine(drive.Name, "log.txt"), "Hello SD");
FileSystem.Flush(e.Hdc); // write everything before unmount / pull
}
else {
Console.WriteLine("SD card removed");
}
};
sd.Enable(); // the card already in the slot is reported too
import os
from GHIElectronics.Endpoint.Core import EPDomino24, DeviceConnectionStatus
from GHIElectronics.Endpoint.Devices.Storage import FileSystem, StorageController
sd = StorageController.FromName(EPDomino24.StorageController.SdCard)
def on_changed(sender, e):
if e.DeviceStatus == DeviceConnectionStatus.Connected:
drive = FileSystem.Mount(e.Hdc) # "/media/sd/"
with open(os.path.join(drive.Name, "log.txt"), "w") as f:
f.write("Hello SD")
FileSystem.Flush(e.Hdc) # write everything before unmount / pull
else:
print("SD card removed")
sd.ConnectionChanged += on_changed
sd.Enable() # the card already in the slot is reported too
#include <cstdio>
#include <fstream>
#include <endpoint/EPDomino24.h>
#include <endpoint/Storage.h>
using namespace GHIElectronics::Endpoint::Core;
using namespace GHIElectronics::Endpoint::Devices::Storage;
auto sd = StorageController::FromName(EPDomino24::StorageController::SdCard);
sd.ConnectionChanged += [](StorageController&, const DeviceConnectionEventArgs& e) {
if (e.DeviceStatus() == DeviceConnectionStatus::Connected) {
auto drive = FileSystem::Mount(e.Hdc()); // "/media/sd/"
std::ofstream(drive.Name() + "log.txt") << "Hello SD";
FileSystem::Flush(e.Hdc()); // write everything before unmount / pull
}
else {
std::puts("SD card removed");
}
};
sd.Enable(); // the card already in the slot is reported too
USB mass storage
Same shape as above, with a different controller name. Multiple USB drives
can be plugged in at once; each one fires ConnectionChanged with its own
Hdc, and each mounts to its own /media/usbN/.
- .NET
- Python
- C/C++
using GHIElectronics.Endpoint.Core;
using GHIElectronics.Endpoint.Devices.Storage;
var usb = StorageController.FromName(EPDomino24.StorageController.UsbHostMassStorage);
usb.ConnectionChanged += (sender, e) => {
if (e.DeviceStatus == DeviceConnectionStatus.Connected) {
var drive = FileSystem.Mount(e.Hdc); // "/media/usb0/", usb1, ...
Console.WriteLine($"Mounted {drive.Name}, label '{e.VolumeLabel}'");
foreach (var file in Directory.EnumerateFiles(drive.Name))
Console.WriteLine(file);
}
else {
Console.WriteLine("USB drive removed");
}
};
usb.Enable();
import os
from GHIElectronics.Endpoint.Core import EPDomino24, DeviceConnectionStatus
from GHIElectronics.Endpoint.Devices.Storage import FileSystem, StorageController
usb = StorageController.FromName(EPDomino24.StorageController.UsbHostMassStorage)
def on_changed(sender, e):
if e.DeviceStatus == DeviceConnectionStatus.Connected:
drive = FileSystem.Mount(e.Hdc) # "/media/usb0/", usb1, ...
print(f"Mounted {drive.Name}, label {e.VolumeLabel!r}")
for name in os.listdir(drive.Name):
path = os.path.join(drive.Name, name)
if os.path.isfile(path):
print(path)
else:
print("USB drive removed")
usb.ConnectionChanged += on_changed
usb.Enable()
#include <cstdio>
#include <filesystem>
#include <endpoint/EPDomino24.h>
#include <endpoint/Storage.h>
using namespace GHIElectronics::Endpoint::Core;
using namespace GHIElectronics::Endpoint::Devices::Storage;
auto usb = StorageController::FromName(EPDomino24::StorageController::UsbHostMassStorage);
usb.ConnectionChanged += [](StorageController&, const DeviceConnectionEventArgs& e) {
if (e.DeviceStatus() == DeviceConnectionStatus::Connected) {
auto drive = FileSystem::Mount(e.Hdc()); // "/media/usb0/", usb1, ...
std::printf("Mounted %s, label '%s'\n", drive.Name().c_str(), e.VolumeLabel().c_str());
for (const auto& entry : std::filesystem::directory_iterator(drive.RootDirectory())) {
if (entry.is_regular_file())
std::puts(entry.path().string().c_str());
}
}
else {
std::puts("USB drive removed");
}
};
usb.Enable();
Always call FileSystem.Flush(e.Hdc) after writing and before the drive
is pulled out. On Endpoint, as on a PC, System.IO.DriveInfo.VolumeLabel
returns the drive's mount folder rather than its label. Use
e.VolumeLabel from the event to read the actual label.