This guide is designed for developers who want to build applications directly on the Debian system underlying RobustOS Pro devices. Compared to using the RobustOS Pro application framework, developing directly on Debian offers greater flexibility and broader community support.
This guide covers two primary development scenarios:
Porting Existing Applications: Migrating applications that already run on standard Linux/Debian platforms to RobustOS Pro devices.
Building New Applications: Creating custom applications from scratch specifically for RobustOS Pro devices.
| Feature | Direct Debian Development | RobustOS Pro Framework Development |
|---|---|---|
| Flexibility | Very high - full control over application behavior and dependencies | High - must follow framework conventions |
| Development Efficiency | Depends on developer experience - requires manual handling of service management and configuration | High - framework automates configuration, Web UI generation, and inter-process communication |
| System Integration | Low - requires interaction with system services via commands or APIs | High - direct access to framework-provided APIs |
| Ideal Use Cases | Porting existing apps, developing standalone services, applications requiring specific libraries or environments | Applications requiring tight system integration, rapid development of apps with Web UIs |
RobustOS Pro is built on Debian GNU/Linux, providing a standard, stable, and feature-rich Linux environment. You can add sudo users through the RobustOS web management interface, then SSH into the system to access a full shell environment.
Package Manager: apt
Service Manager: systemd
Shell Environment: bash
You can check the current system version details using cat /etc/os-release. RobustOS Pro 2.x is based on Debian 11.
Regardless of whether you're porting or developing a new application, you'll need to prepare your development environment first.
Since your development host (typically x86 architecture) differs from the target device (ARM architecture), you need an environment to generate binaries that can run on the device. You can choose one of two standard approaches:
You can install a standard cross-compilation toolchain on your development host (Debian/Ubuntu recommended).
# On your Debian/Ubuntu development host
sudo apt update
sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
After installation, you'll use aarch64-linux-gnu-gcc as your compiler.
# On your Debian/Ubuntu development host
sudo apt update
sudo apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
After installation, you'll use arm-linux-gnueabihf-gcc as your compiler.
This is a more modern approach that simplifies dependency management and ensures environment consistency. It runs an ARM architecture Docker container on an x86 host for native compilation, avoiding the complexities of cross-compilation.
# -v "$(pwd):/src" mounts the current directory to /src in the container for code sharing
docker run --rm -it --platform linux/arm64 -v "$(pwd):/src" debian:11
docker run --rm -it --platform linux/arm/v7 -v "$(pwd):/src" debian:11
# Update package lists
apt update
# Install basic build tools
apt install -y build-essential gcc make
# Optional: Install other common tools
apt install -y git cmake pkg-config
# Navigate to the mounted source directory
cd /src
# Now you can start building
make
Inside the container, after installing the build tools, you can compile directly using gcc just as you would on the target device, without configuring cross-compilation toolchains.
ssh sudouser@192.168.0.1
# Upload file from host to device
scp /path/to/local/file sudouser@192.168.0.1:/path/to/remote/
# Download file from device to host
scp sudouser@192.168.0.1:/path/to/remote/file /path/to/local/
You can use apt directly on the device to manage packages. Ensure the device has internet connectivity.
# Update package lists
apt update
# Install a new package (e.g., git)
apt install git
# Remove a package
apt remove git
# Search for packages
apt search <package-name>
This section guides you through porting an existing Linux/Debian application to RobustOS Pro devices.
First, analyze your application's runtime library dependencies.
ldd ./your-application
Install Dependencies: Log into the device and use apt install to install all required libraries. Standard libraries (such as libcurl, libssl) are typically available directly from Debian repositories.
Handle Special Libraries: If your application depends on proprietary libraries or specific versions unavailable through apt, you'll need to obtain their source code, compile them for the target platform using the cross-compilation toolchain, and then deploy the compiled library files to /usr/lib or other library paths on the device.
Next, modify your project's build system (e.g., Makefile) to use the cross-compilation toolchain.
Makefile Example:
Point the build tools to the cross-compilation toolchain.
# Original configuration
# CC = gcc
# CXX = g++
# Modified for cross-compilation toolchain
CROSS_COMPILE ?= aarch64-linux-gnu-
CC = $(CROSS_COMPILE)gcc
CXX = $(CROSS_COMPILE)g++
LD = $(CROSS_COMPILE)ld
AR = $(CROSS_COMPILE)ar
STRIP = $(CROSS_COMPILE)strip
# Compilation options
CFLAGS ?= -Wall -O2
CXXFLAGS ?= -Wall -O2
LDFLAGS ?=
# Target executable
TARGET = your-application
# Phony targets
.PHONY: all clean verify
all: $(TARGET)
$(TARGET): main.c
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
@echo "Build complete. Verifying binary..."
@file $(TARGET)
verify: $(TARGET)
@file $(TARGET)
@echo "Expected output: ELF 64-bit LSB executable, ARM aarch64"
clean:
rm -f $(TARGET) *.o
CMake Example:
Create a toolchain file (e.g., toolchain.cmake) to define the cross-compilation environment.
# toolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
When running CMake, specify this file using the -DCMAKE_TOOLCHAIN_FILE parameter.
cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake ..
Most standard Linux applications require no code modifications. However, if you encounter issues, check the following:
Hardware-Specific Code: Check for code related to specific hardware (such as particular GPIO pins or serial ports) or CPU architectures.
Hardcoded Paths: Verify that any hardcoded filesystem paths in the code are valid on the target device.
On your development host, run make (or your build command) to cross-compile the application.
After successful compilation, an ARM architecture executable will be generated. Use file to confirm.
file ./your-application
# Expected output: ... ELF 64-bit LSB executable, ARM aarch64, ...
Use scp to upload the executable and related configuration files to the device.
On the device, add execute permissions with chmod +x ./your-application, then run it for testing.
This section guides you through developing a new application for RobustOS Pro devices from scratch.
#include <stdio.h>
int main() {
printf("Hello, RobustOS Pro!\n");
return 0;
}
# Cross-compilation toolchain prefix (default aarch64, can be overridden via environment variable)
CROSS_COMPILE ?= aarch64-linux-gnu-
CC = $(CROSS_COMPILE)gcc
# Compilation options
CFLAGS = -Wall -O2
LDFLAGS =
# Target executable
TARGET = hello_world
# Phony targets
.PHONY: all clean verify
all: $(TARGET)
$(TARGET): main.c
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
@echo "Build complete. Verifying binary architecture..."
@file $(TARGET)
# Verify generated binary architecture
verify: $(TARGET)
@echo "Binary architecture:"
@file $(TARGET)
@echo "Expected: ARM aarch64 for arm64 devices"
clean:
rm -f $(TARGET)
# Build on development host
make
# Upload to device
scp ./hello_world sudouser@192.168.0.1:/home/sudouser/
# Run on device
ssh sudouser@192.168.0.1 "/home/sudouser/hello_world"
# Expected output: Hello, RobustOS Pro!
Python is an interpreted language and doesn't require cross-compilation.
#!/usr/bin/env python3
print("Hello from Python on RobustOS Pro!")
# Upload to device
scp ./hello.py sudouser@192.168.0.1:/home/sudouser/
# Run on device
ssh sudouser@192.168.0.1 "python3 /home/sudouser/hello.py"
# Expected output: Hello from Python on RobustOS Pro!
Your application may need to query device status or communicate with system services.
In Debian applications or shell scripts, the primary tools for interacting with system services are usi (for status queries) and uci (for querying or modifying configuration). You can execute these commands from your application using system() or popen().
Common usi Command Examples:
# View LAN port IP address
sudo usi get lan_links.link_status[1].ip4_addr
# Check SIM1 status
sudo usi get cellular.status[1].modem_status
# Get device model
sudo usi get system.device_model
C Language Example - Using popen() to capture command output:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
FILE *fp;
char buffer[256];
// Execute command and capture output
fp = popen("usi get system.firmware_version", "r");
if (fp == NULL) {
fprintf(stderr, "Failed to run command\n");
return 1;
}
// Read output
printf("Firmware Version:\n");
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
printf("%s", buffer);
}
// Close pipe
pclose(fp);
return 0;
}
Python Example:
import subprocess
# Execute command and capture output
result = subprocess.run(['usi', 'get', 'system.firmware_version'],
capture_output=True, text=True)
if result.returncode == 0:
print("Firmware Version:")
print(result.stdout)
else:
print(f"Error: {result.stderr}")
For easier management and distribution, we recommend packaging your application in Debian's .deb format.
myapp-pkg/
├── DEBIAN
│ └── control
└── usr
└── local
└── bin
└── myapp <-- Place your executable here
Package: myapp
Version: 1.0.0
Section: base
Priority: optional
Architecture: arm64
Maintainer: Your Name <your.email@example.com>
Description: A brief description of my application.
A longer description can go here on multiple lines,
but each subsequent line must start with a space.
Important Note: Architecture Field
The Architecture field must match your target device architecture:
For aarch64 (arm64) devices, use Architecture: arm64
For armv7 (armhf) devices, use Architecture: armhf
For architecture-independent packages (pure scripts, documentation), use Architecture: all
You can confirm the device architecture by SSH'ing into the device and running dpkg --print-architecture
dpkg-deb --build myapp-pkg
# This will generate myapp-pkg.deb
Upload the generated myapp-pkg.deb file to the device.
Use dpkg commands to install, remove, and query packages.
# Install
dpkg -i myapp-pkg.deb
# Remove
dpkg -r myapp
# Query installed packages
dpkg -l | grep myapp
To have your application automatically start when the device boots and be managed by the system, you can configure it as a systemd service.
[Unit]
Description=My Application Service
After=network.target
[Service]
ExecStart=/usr/local/bin/myapp
Restart=on-failure
# Unless the app truly requires root privileges, use a regular user
# User=myapp
# Group=myapp
User=root # Only use when hardware access is required
[Install]
WantedBy=multi-user.target
myapp-pkg/
├── DEBIAN
│ └── control
├── lib
│ └── systemd
│ └── system
│ └── myapp.service
└── usr
└── local
└── bin
└── myapp
After repackaging, installing the deb will automatically deploy the service file to the correct location.
After installing the deb package containing the service file, you can use systemctl on the device to manage your service.
# Enable service to start on boot
systemctl enable myapp.service
# Start service immediately
systemctl start myapp.service
# Check service status
systemctl status myapp.service
# Stop service
systemctl stop myapp.service
# Disable auto-start on boot
systemctl disable myapp.service
Use journalctl -u myapp.service to view standard output and error logs from your application service.
You can use gdbserver to run your program on the device, then use gdb from your development host's cross-compilation toolchain for remote debugging.
Note: If gdbserver is not installed on your device, install it first with:
sudo apt-get update
sudo apt-get install gdbserver
gdbserver :1234 ./your-application
# Start gdb client
aarch64-linux-gnu-gdb ./your-application
# Inside gdb, connect to remote gdbserver
(gdb) target remote 192.168.0.1:1234
Once connected, you can debug just as you would locally - setting breakpoints, stepping through code, etc.
systemd Service Logs: Use journalctl -u your-app.service -f to view service logs in real-time.
System Logs: Use dmesg or journalctl to view system-level logs for troubleshooting environment-related issues.
The device comes preinstalled with standard Linux diagnostic tools to help you identify issues:
top: View system resource usage and process status.
strace: Trace system calls and signals for analyzing program behavior.
netstat / ss: View network connection status.
tcpdump: Perform network packet capture and analysis.