Files

250 lines
6.5 KiB
Bash
Executable File

#!/bin/bash
# RuvLLM ESP32 - Cross-Platform Installer
# Supports: Linux, macOS, WSL
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
echo -e "${BLUE}"
echo "╔══════════════════════════════════════════════════════════╗"
echo "║ RuvLLM ESP32 - Universal Installer ║"
echo "║ Tiny LLM + RAG + Federation for Microcontrollers ║"
echo "╚══════════════════════════════════════════════════════════╝"
echo -e "${NC}"
# Detect OS
detect_os() {
case "$(uname -s)" in
Linux*) OS=linux;;
Darwin*) OS=macos;;
MINGW*|MSYS*|CYGWIN*) OS=windows;;
*) OS=unknown;;
esac
echo -e "${GREEN}Detected OS: $OS${NC}"
}
# Check dependencies
check_deps() {
echo -e "\n${YELLOW}Checking dependencies...${NC}"
# Rust
if command -v rustc &> /dev/null; then
RUST_VERSION=$(rustc --version)
echo -e "${GREEN}✓ Rust: $RUST_VERSION${NC}"
else
echo -e "${RED}✗ Rust not found${NC}"
install_rust
fi
# Cargo
if command -v cargo &> /dev/null; then
echo -e "${GREEN}✓ Cargo available${NC}"
else
echo -e "${RED}✗ Cargo not found${NC}"
exit 1
fi
}
# Install Rust
install_rust() {
echo -e "${YELLOW}Installing Rust...${NC}"
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
}
# Install ESP32 toolchain
install_esp_toolchain() {
echo -e "\n${YELLOW}Installing ESP32 toolchain...${NC}"
# Install espup
if ! command -v espup &> /dev/null; then
echo "Installing espup..."
cargo install espup
else
echo -e "${GREEN}✓ espup already installed${NC}"
fi
# Install ESP toolchain
echo "Running espup install (this may take a few minutes)..."
espup install
# Source the export file
if [ -f "$HOME/export-esp.sh" ]; then
source "$HOME/export-esp.sh"
elif [ -f "$HOME/.espressif/export-esp.sh" ]; then
source "$HOME/.espressif/export-esp.sh"
fi
# Install espflash
if ! command -v espflash &> /dev/null; then
echo "Installing espflash..."
cargo install espflash
else
echo -e "${GREEN}✓ espflash already installed${NC}"
fi
# Install ldproxy
if ! command -v ldproxy &> /dev/null; then
echo "Installing ldproxy..."
cargo install ldproxy
else
echo -e "${GREEN}✓ ldproxy already installed${NC}"
fi
}
# Build the project
build_project() {
echo -e "\n${YELLOW}Building RuvLLM ESP32...${NC}"
# Source ESP environment
if [ -f "$HOME/export-esp.sh" ]; then
source "$HOME/export-esp.sh"
fi
cargo build --release
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓ Build successful!${NC}"
else
echo -e "${RED}✗ Build failed${NC}"
exit 1
fi
}
# Flash to device
flash_device() {
local PORT="${1:-/dev/ttyUSB0}"
echo -e "\n${YELLOW}Flashing to $PORT...${NC}"
# Detect port if not specified
if [ ! -e "$PORT" ]; then
echo "Detecting ESP32 port..."
if [ "$OS" = "macos" ]; then
PORT=$(ls /dev/cu.usbserial-* 2>/dev/null | head -1)
[ -z "$PORT" ] && PORT=$(ls /dev/cu.SLAB_USBtoUART* 2>/dev/null | head -1)
else
PORT=$(ls /dev/ttyUSB* 2>/dev/null | head -1)
[ -z "$PORT" ] && PORT=$(ls /dev/ttyACM* 2>/dev/null | head -1)
fi
fi
if [ -z "$PORT" ] || [ ! -e "$PORT" ]; then
echo -e "${RED}No ESP32 device found. Please specify port:${NC}"
echo " ./install.sh flash /dev/ttyUSB0"
exit 1
fi
echo -e "${GREEN}Found device at: $PORT${NC}"
espflash flash --port "$PORT" --monitor target/xtensa-esp32-espidf/release/ruvllm-esp32-flash
}
# Print usage
usage() {
echo "Usage: ./install.sh [command] [options]"
echo ""
echo "Commands:"
echo " install Install all dependencies and build (default)"
echo " build Build the project only"
echo " flash Flash to ESP32 (optionally specify port)"
echo " deps Install dependencies only"
echo " cluster Setup cluster configuration"
echo " help Show this help"
echo ""
echo "Examples:"
echo " ./install.sh # Full install and build"
echo " ./install.sh flash /dev/ttyUSB0 # Flash to specific port"
echo " ./install.sh flash COM6 # Flash on Windows/WSL"
echo " ./install.sh cluster 5 # Setup 5-chip cluster"
}
# Cluster setup
setup_cluster() {
local NUM_CHIPS="${1:-2}"
echo -e "\n${YELLOW}Setting up $NUM_CHIPS-chip cluster...${NC}"
# Create cluster config
cat > cluster.toml << EOF
# RuvLLM ESP32 Cluster Configuration
# Generated by install.sh
[cluster]
name = "ruvllm-cluster"
chips = $NUM_CHIPS
topology = "pipeline" # pipeline, tensor, hybrid
[chips]
EOF
for i in $(seq 1 $NUM_CHIPS); do
if [ "$OS" = "macos" ]; then
DEFAULT_PORT="/dev/cu.usbserial-$i"
else
DEFAULT_PORT="/dev/ttyUSB$((i-1))"
fi
cat >> cluster.toml << EOF
[[chips.nodes]]
id = $i
role = "$([ $i -eq 1 ] && echo 'master' || echo 'worker')"
port = "$DEFAULT_PORT"
layers = [$(( (i-1) * 2 / NUM_CHIPS )), $(( i * 2 / NUM_CHIPS - 1 ))]
EOF
done
echo -e "${GREEN}✓ Created cluster.toml${NC}"
echo ""
echo "Edit cluster.toml to set correct ports, then run:"
echo " ./cluster-flash.sh"
}
# Main
main() {
detect_os
case "${1:-install}" in
install)
check_deps
install_esp_toolchain
build_project
echo -e "\n${GREEN}Installation complete!${NC}"
echo "To flash: ./install.sh flash [port]"
;;
build)
build_project
;;
flash)
flash_device "$2"
;;
deps)
check_deps
install_esp_toolchain
;;
cluster)
setup_cluster "$2"
;;
help|--help|-h)
usage
;;
*)
echo -e "${RED}Unknown command: $1${NC}"
usage
exit 1
;;
esac
}
main "$@"