GARYCLI(1)

NAME

garycliThe Spear Carrier. AI-native CLI agent for STM32 embedded development and automated debugging. (Gary:专为 STM32 打造的 AI…

SYNOPSIS

INFO

95 stars
5 forks
0 views
PythonAI & LLM

DESCRIPTION

The Spear Carrier. AI-native CLI agent for STM32 embedded development and automated debugging. (Gary:专为 STM32 打造的 AI 原生命令行开发与调试智能体。)

README

🗡️ GARY CLI: The Spear Carrier

Piercing the Silicon with AI. An AI-native command-line development and debugging agent for STM32, RP2040 / Pico, and ESP32 / ESP8266 boards

License Python Boards Website


   ██████╗  █████╗ ██████╗ ██╗   ██╗
  ██╔════╝ ██╔══██╗██╔══██╗╚██╗ ██╔╝
  ██║  ███╗███████║██████╔╝ ╚████╔╝
  ██║   ██║██╔══██║██╔══██╗  ╚██╔╝
  ╚██████╔╝██║  ██║██║  ██║   ██║
   ╚═════╝ ╚═╝  ╚═╝╚═╝  ╚═╝   ╚═╝

Talk to it in natural language, and let AI directly participate in development, deployment, and debugging for STM32, RP2040 / Pico, and ESP32 / ESP8266 boards.

中文

Quick Start · Core Features · Usage Guide · Command Reference · Skill System · FAQ

Manual installation

# 1. Clone the repository
git clone https://github.com/garycli/garycli.git
cd garycli

2. Run environment install

python3 setup.py --auto

3. Run environment diagnostics

python3 stm32_agent.py --doctor

First-time configuration

gary config

Follow the prompts to configure:

  • API Key
  • Base URL
  • Model
  • Default chip model
  • Default serial parameters (optional)

Environment diagnostics

gary doctor

Example output:

■ AI Interface
  ✓ API Key   sk-abc...xyz
  ✓ Base URL  https://api.deepseek.com/v1
  ✓ Model     deepseek-chat
  ✓ API connectivity  OK

■ Compilation Toolchain ✓ arm-none-eabi-gcc arm-none-eabi-gcc (15.1.0) ✓ HAL resources STM32F0xx, STM32F1xx, STM32F3xx, STM32F4xx ✓ CMSIS Core

■ Python Dependencies ✓ openai ✓ rich ✓ prompt_toolkit ✓ pyserial (optional) ✓ pyocd (optional) ✓ stm32loader (optional)

■ Hardware Probes ✓ ST-Link V2 ✓ Serial port /dev/ttyUSB0

✅ All core components are ready. Gary is good to go.


⚡ What is Gary?

In traditional embedded development, the real time sink is usually not just “writing a few lines of C code,” but this full chain:

Requirement understanding → Peripheral configuration → Code generation → Cross-compilation → Firmware flashing → Serial verification → Register inspection → Fault fixing → Reflashing

Gary (The Spear Carrier) is not just another chat tool that can only “generate code.” It is an AI execution agent for embedded boards across multiple workflows: you describe the goal, and it generates code, invokes toolchains, connects to hardware, collects runtime feedback, and keeps fixing issues when the results are verifiable.

You say:
  “Help me build an OLED temperature and humidity display using an AHT20 sensor.”

Gary automatically executes: ✓ Generates a complete main.c (HAL + I2C + AHT20 + SSD1306) ✓ Cross-compiles with arm-none-eabi-gcc ✓ Flashes the STM32 via SWD or UART ISP ✓ Monitors serial output to verify that the program really started ✓ Reads registers to inspect peripheral state ✗ Detects no I2C response → analyzes cause → patches code → reflashes ✓ Second run succeeds

In one sentence:

Gary is not just trying to “write MCU code for you” — it is trying to complete a real, verifiable embedded-development loop for you.


🎯 Core Features

🗣️ Natural language → compilable STM32 HAL project code

Describe the target behavior directly, and Gary generates complete STM32 HAL C code that can be cross-compiled.

gary do "PA0 has an LED connected. Make a breathing light with 1kHz PWM"
gary do "Read MPU6050 acceleration data over I2C1 and print it over UART"
gary do "Configure TIM2 in encoder mode to read motor speed"

Typical use cases:

  • GPIO / PWM / ADC / EXTI
  • UART / I2C / SPI / timers
  • OLED / sensors / seven-segment displays / buzzers
  • PID control / encoder feedback / motor control
  • Rapid bare-metal prototyping

🔄 Automatic closed-loop debugging

Gary’s priority is not “getting it right on the first try,” but this:

Generate code → Compile → Flash → Verify over serial → Read registers → Analyze issue → Patch code → Recompile and reflash

It tries to continue based on real feedback instead of stopping at “you may want to change this.”

Typical diagnostics include:

  • Compilation failures: reads GCC errors and fixes syntax, symbol, or initialization problems
  • No program output: checks startup path, SysTick, clock configuration, and UART init sequence
  • HardFault: inspects SCB-related registers to help locate the fault type
  • I2C failures: checks device address, bus lockup, init order, NACK/ARLO, and similar conditions
  • Multiple automatic repair rounds: if it still cannot fix the issue, it tries to narrow it down clearly to either a code problem or a hardware problem

⚡ Consistent flashing and debugging strategy

Gary uses a clear and consistent hardware strategy:

  • SWD by default: best for stable flashing, register access, fault analysis, and debug loops
  • UART ISP optional: can be used when no debugger is available
  • Serial monitoring stays separate: whether you flash over SWD or UART ISP, UART is still used to observe real runtime behavior

That means:

  • SWD handles “flashing + debugging”
  • UART handles “logs + runtime verification”

This is more stable than mixing flashing and runtime feedback together, and better matches real embedded workflows.

🧰 Built-in tools

ToolPurpose
PID Auto TuningAnalyzes overshoot, oscillation, and steady-state error, then recommends Kp/Ki/Kd
I2C Bus ScanScans device addresses and helps identify common chips
Pin Conflict DetectionDetects GPIO mux conflicts, SWD pin misuse, and similar issues
PWM Parameter CalculatorComputes PSC/ARR automatically and quickly validates target frequencies
Servo CalibrationGenerates angle sweep logic and maps pulse width to angle
Signal Capture AnalysisAnalyzes ADC/sensor waveform fluctuation, noise, and frequency characteristics
Peripheral Smoke TestsOne-click minimal test code for GPIO/UART/I2C/SPI/ADC
Flash/RAM AnalysisShows memory usage and warns about capacity issues
Power EstimationEstimates power consumption from enabled peripherals
Font GeneratorConverts Chinese/English text into OLED bitmap arrays

🔌 Bring Your Own Key

Gary is not tied to a single AI provider. You can switch backends freely:

ProviderModelNotes
DeepSeekdeepseek-chatCost-effective
Kimi / Moonshotkimi-k2.5Strong Chinese capability
OpenAIgpt-4oStrong overall performance
Google Geminigemini-2.0-flashFast response
Tongyi Qianwenqwen-plusAlibaba Cloud
Zhipu GLMglm-4-flashEasy to integrate
Ollamaqwen2.5-coder:14bLocal offline, fully private

🧩 Skill System (Skills)

Gary supports pluggable skill packs to extend its capabilities.

/skill install pid_tuner.py
/skill install ~/Downloads/skill.zip
/skill install https://github.com/xxx/skill.git
/skill list
/skill create my_tool "My tool"
/skill export my_tool

Each Skill can include:

  • Python tool functions
  • OpenAI Function Calling schemas
  • Prompt instructions
  • Dependency files

Once installed, skills can be hot-loaded without restarting.


🚀 Quick Start

One-line install

Linux / macOS / WSL:

curl -fsSL https://www.garycli.com/install.sh | bash

Windows (PowerShell):

irm https://www.garycli.com/install.ps1 | iex

The install script will attempt to complete:

  • Python environment check
  • arm-none-eabi-gcc installation or detection
  • HAL / CMSIS resource setup
  • Python dependency installation
  • Serial and debug tool installation
  • CLI launcher command setup

📖 Usage Guide

Mode 1: One-shot task (gary do)

Best for quickly validating a single requirement:

# Generate + compile only (no hardware connection)
gary do "Write a WS2812 driver for 8 LEDs with a rainbow animation"

Generate + compile + connect to hardware

gary do "Blink an LED on PA0 with a 500ms interval" --connect

Specify chip model

gary do "Read ADC voltage and print it over UART" --chip STM32F407VET6 --connect

Mode 2: Interactive conversation (gary)

Best for iterative, multi-turn development:

gary
gary --connect
gary --chip STM32F407VET6
gary --connect --chip STM32F103C8T6

Example:

Gary > Help me build an OLED clock on I2C1 with SSD1306, showing HH:MM:SS

🔧 stm32_reset_debug_attempts → counter reset 🔧 stm32_hardware_status → chip: STM32F103C8T6, hw_connected: true 🔧 stm32_generate_font → generated bitmap for "0123456789:" 🔧 stm32_auto_flash_cycle → compile success 8.2KB, flash success Serial output: Gary:BOOT → OLED Init OK → 12:34:56

✓ OLED is now displaying the time correctly

Mode 3: Incremental modifications

Gary tries to continue from the current project instead of rewriting everything from scratch each time:

Gary > The LED is blinking too fast, change it to 1 second
Gary > Change it to common-anode seven-segment
Gary > Add a buzzer that sounds on alarm
Gary > Change the I2C address from 0x3C to 0x3D

This works well for continuous iteration on the same project.


📋 Command Reference

Terminal commands

CommandDescription
garyLaunch interactive conversation mode
gary do "task description"One-shot task mode
gary do "task" --connectOne-shot task + auto-connect hardware
gary --chip STM32F407VET6Specify chip model
gary --connectLaunch and connect hardware
gary configConfigure AI backend
gary doctorRun environment diagnostics

Interactive commands (inside Gary >)

CommandDescription
/connect [chip]Connect debugger or initialize hardware context
/disconnectDisconnect hardware
/serial [port] [baudrate]Connect serial port
/serial listList available serial ports
/chip [model]Show or switch chip model
/flash [swd|uart|auto]Set flashing method
/flash statusShow flashing tool status
/probesList debug probes
/statusShow full hardware status
/configReconfigure AI backend
/projectsShow project history
/skill listList installed skills
/skill install <source>Install a skill pack
/skill create <name>Create a skill template
/clearClear conversation history
/exitExit

🔌 Hardware Connection Recommendations

Recommended setup: SWD + serial logging

This is the most stable combination:

  • SWD: flashing, register inspection, fault debugging
  • UART: serial monitoring and startup verification
ST-Link / J-Link      STM32
  SWDIO   ─────────── PA13
  SWCLK   ─────────── PA14
  GND     ─────────── GND
  3.3V    ─────────── 3.3V

USB-TTL STM32 TX ──────────→ PA10 RX ←────────── PA9 GND ─────────── GND

Pure serial setup (no debugger)

If you do not have an ST-Link, you can also use only a USB-TTL adapter and flash over UART ISP, but capability will be limited:

  • Flashing is possible
  • Serial output is visible
  • Register reads and fault analysis are not as convenient as with SWD

So SWD is still strongly recommended when available.


🧩 Skill System (Skills)

Gary supports capability extensions through skill packs. A standard Skill directory looks like this:

~/.gary/skills/
├── pid_tuner/
│   ├── skill.json
│   ├── tools.py
│   ├── schemas.json
│   ├── prompt.md
│   └── requirements.txt
├── uart_flash/
└── _disabled/

Install a skill

/skill install stm32_extra_tools.py
/skill install ~/Downloads/gary_skill_pid_tuner.zip
/skill install https://github.com/someone/gary-skill-motor.git
/skill install ~/my_skills/sensor_kit/

Manage skills

/skill list
/skill info pid_tuner
/skill disable pid_tuner
/skill enable pid_tuner
/skill uninstall pid_tuner
/skill reload

Build your own Skill

# 1. Create a template
/skill create motor_driver "DC motor PID control tool"

2. Edit the generated files

~/.gary/skills/motor_driver/tools.py

~/.gary/skills/motor_driver/schemas.json

~/.gary/skills/motor_driver/prompt.md

3. Hot reload

/skill reload

4. Export for sharing

/skill export motor_driver

Skill development spec

tools.py:

def motor_set_speed(rpm: int) -> dict:
    """Set motor speed"""
    return {"success": True, "message": f"Target speed: {rpm} RPM"}

TOOLS_MAP = { "motor_set_speed": motor_set_speed, }

schemas.json:

[
  {
    "type": "function",
    "function": {
      "name": "motor_set_speed",
      "description": "Set the target speed of a DC motor",
      "parameters": {
        "type": "object",
        "properties": {
          "rpm": {
            "type": "integer",
            "description": "Target speed in RPM"
          }
        },
        "required": ["rpm"]
      }
    }
  }
]

prompt.md:

## Motor Control
When the user wants to control a motor, call motor_set_speed to set the target RPM.

🏗️ Architecture

┌──────────────────────────────────────────────────────┐
│                    Gary CLI (TUI)                    │
│              rich + prompt_toolkit                   │
├──────────────────────────────────────────────────────┤
│                   AI Conversation Engine             │
│         Streaming dialogue + Function Calling        │
│   DeepSeek │ Kimi │ GPT │ Gemini │ Ollama │ ...     │
├──────────────┬──────────────┬────────────────────────┤
│  Code Gen     │   Compiler    │   Hardware Backend    │
│  HAL templates │  GCC Cross   │  ┌─────────────────┐  │
│  Project reuse │  Compiler    │  │ SWD (default)   │  │
│  Template base │              │  │ pyocd           │  │
│                │              │  ├─────────────────┤  │
│                │              │  │ UART ISP opt.   │  │
│                │              │  │ stm32loader     │  │
│                │              │  ├─────────────────┤  │
│                │              │  │ Serial monitor  │  │
│                │              │  │ pyserial        │  │
│                │              │  └─────────────────┘  │
├──────────────┴──────────────┴────────────────────────┤
│                   Skill System (Skills)              │
│   PID tuning │ I2C scan │ PWM tools │ Font gen │ ... │
└──────────────────────────────────────────────────────┘

📟 Supported Chips

Gary currently supports the following boards and workflows:

PlatformTypical chips / boardsCurrent workflow
STM32F0 / F1 / F3 / F4F030F4, F103C8T6, F303RCT6, F407VET6, F411CEU6HAL C code generation, GCC compilation, pyOCD / SWD flashing, register-level debugging
RP2040RP2040, Pico, Pico WMicroPython main.py syntax validation, USB serial raw REPL sync, boot-log / traceback debugging
ESP32 familyESP32, ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C6, LOLIN32, NodeMCU-32SMicroPython main.py syntax validation, USB serial raw REPL sync, boot-log / traceback debugging
ESP8266 familyESP8266, NodeMCU, D1 Mini, ESP-01MicroPython main.py syntax validation, USB serial raw REPL sync, boot-log / traceback debugging

STM32 uses the HAL / GCC / SWD workflow, while RP2040 and ESP targets use the MicroPython main.py + USB serial workflow.


💡 Practical Examples

🔰 LED blink

Gary > Help me make an LED blink on PA0 with a 500ms interval

🔢 Seven-segment display

Gary > A 4-digit common-anode seven-segment display, PA0-PA7 for segment select, PB0-PB3 for digit select, show a counter

📡 Sensor reading

Gary > Connect an AHT20 temperature and humidity sensor to I2C1 and print temperature and humidity over UART
Gary > Now add an SSD1306 OLED to display the temperature too

🎛️ PID motor speed control

Gary > DC motor PID speed control: TIM2 CH1 outputs PWM, TIM3 encoder reads feedback, target 500rpm

🔍 I2C troubleshooting

Gary > I connected several I2C devices but I’m not sure about the addresses, help me scan them

🎵 Buzzer music

Gary > A passive buzzer is connected to PA1. Help me play Twinkle Twinkle Little Star

🖥️ Chinese text on OLED

Gary > Display the Chinese text “你好世界” on the OLED with a 16x16 font

📁 Project Structure

This layout is closer to the repository’s current structure:

garycli/
├── stm32_agent.py          # Main program: TUI + AI dialogue + tool orchestration
├── compiler.py             # GCC cross-compilation wrapper
├── config.py               # Config files and path management
├── setup.py                # Installation and initialization script
├── stm32_extra_tools.py    # Extra tool collection
├── gary_skills.py          # Skill system manager
├── requirements.txt        # Python dependencies
├── install.sh              # Linux / macOS / WSL install script
├── install.ps1             # Windows install script
└── ~/.gary/                # User data directory
    ├── skills/             # Installed skills
    ├── projects/           # Historical project archives
    ├── templates/          # Template library
    └── member.md           # Knowledge / memory base

❓ FAQ

Installation

Q: I installed arm-none-eabi-gcc, but it still cannot be found.

Confirm it is in your PATH:

which arm-none-eabi-gcc

If nothing is returned, add it to PATH manually or run gary doctor for diagnosis.

Q: HAL resource download failed.
python3 setup.py --hal
# Or specify families
python3 setup.py --hal f1 f4
Q: Serial port permissions or drivers are broken on Windows.

Make sure the CH340 / CP2102 driver is installed and that the corresponding COM port appears in Device Manager.

Q: On Linux, opening the serial port returns Permission denied.
sudo usermod -aG dialout $USER
newgrp dialout

Usage

Q: UART flashing does not respond.

Check the following:

  1. Whether BOOT0 is pulled high for download mode
  2. Whether the board has been reset
  3. Whether TX / RX are cross-connected
  4. Whether the port and baudrate are correct
Q: Compilation fails with undefined reference to _sbrk.

This usually means the code pulls in symbols that depend on heap support, such as printf, sprintf, or malloc. For minimal bare-metal projects, it is better to avoid these directly.

Q: How do I debug a HardFault?

SWD is recommended. Gary can use register information to help classify the issue:

  • PRECISERR: often caused by accessing a peripheral before it is ready
  • UNDEFINSTR: may indicate stack corruption, bad branching, or invalid instructions
  • IACCVIOL: may indicate access to an illegal code region
Q: Can I use a local model through Ollama?

Yes. Run gary config and select Ollama. Models with more stable function-calling behavior are recommended.

Q: Does it support Arduino or ESP32?

Yes. Gary now supports STM32, RP2040 / Pico / Pico W, and ESP32 / ESP8266 boards.


🗺️ Roadmap

  • Basic support for STM32F0 / F1 / F3 / F4
  • UART ISP flashing support
  • SWD debugging and register inspection
  • Skill system (Skills)
  • Early template library and experience base
  • Skill marketplace (browse / install community skills online)
  • Real-time serial data visualization
  • STM32CubeMX project import
  • VS Code extension
  • RP2040 / Pico / Pico W support
  • ESP32 / ESP8266 MicroPython support

🤝 Contributing

Issues and PRs are welcome. Contributions are especially appreciated in these areas:

  • New Skill packs
  • More STM32 / RP2040 / ESP board and template support
  • Documentation improvements and translations
  • Fault reproduction and fixes
  • Example projects and demo videos

Contributing a Skill

# 1. Create a template
/skill create my_awesome_tool "My tool"

2. Develop and test

Edit ~/.gary/skills/my_awesome_tool/

3. Export

/skill export my_awesome_tool

4. Submit a PR

Star History

Star History Chart ---

📜 License

This project is released under the Apache-2.0 License.


🗡️ Just Gary Do It.

Website · GitHub · Submit an Issue

SEE ALSO

clihub5/13/2026GARYCLI(1)