Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,21 @@ pre-commit run --all-files

VS Code 示例配置位于 `VSC_sample_configs/`。贡献流程和提交规范见 [CONTRIBUTING.md](CONTRIBUTING.md)。

## Codex Skill

仓库在 [`skills/mambo`](skills/mambo/SKILL.md) 内置了面向 Mambo 的 Agentic Embedded Skill,用于指导 Codex 配置 Mambo/Zephyr 环境、编写最小可验证程序,并通过 DM-MC02、CMSIS-DAP、AresPlot 和串口采集工具进行安全调试。

从仓库根目录将 Skill 链接到个人 Codex 技能目录:

```shell
mkdir -p "${CODEX_HOME:-$HOME/.codex}/skills"
ln -s "$PWD/skills/mambo" "${CODEX_HOME:-$HOME/.codex}/skills/mambo"
```

安装后可通过 `$mambo` 调用。默认使用新生模式,以简单中文逐步解释并核对构建、接线和运行证据;明确说“专家模式”或“老手模式”后,才会切换为更精简的批量诊断。两种模式都不会在未授权时烧录固件、连接调试探针或启用执行器电源。

Skill 同时提供只读 AresPlot CSV 采集、按时间区间绘图、JSON 配置示例和 DM-MC02 V1.1 使用说明书,详见 [`skills/mambo/references`](skills/mambo/references) 与 [`skills/mambo/scripts`](skills/mambo/scripts)。

## 文档

- 文档入口:[Documents/README.md](Documents/README.md)
Expand Down
15 changes: 15 additions & 0 deletions README.md.eng
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,18 @@ pre-commit run --all-files
```

VS Code example settings are available in `VSC_sample_configs/`. See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines.

## Codex Skill

The repository includes an Agentic Embedded Skill at [`skills/mambo`](skills/mambo/SKILL.md). It guides Codex through Mambo/Zephyr setup, small verifiable program changes, and safe debugging with the DM-MC02, CMSIS-DAP, AresPlot, and the bundled serial capture tools.

From the repository root, link the Skill into the personal Codex skill directory:

```shell
mkdir -p "${CODEX_HOME:-$HOME/.codex}/skills"
ln -s "$PWD/skills/mambo" "${CODEX_HOME:-$HOME/.codex}/skills/mambo"
```

Invoke it with `$mambo`. Beginner mode is the default and teaches one evidence-backed step at a time. Explicitly request `expert mode` for concise, batched diagnostics. Both modes require authorization before flashing, attaching a debug probe, or enabling actuator power.

The Skill also bundles read-only AresPlot CSV capture, time-window rendering, a JSON configuration example, and the DM-MC02 V1.1 manual under [`skills/mambo/references`](skills/mambo/references) and [`skills/mambo/scripts`](skills/mambo/scripts).
42 changes: 42 additions & 0 deletions skills/mambo/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
name: mambo
description: "Configure, build, and debug small robots with the Mambo Zephyr embedded framework, especially the Damiao DM-MC02 board and AresPlot. Use for Mambo/Zephyr environment setup, devicetree and Kconfig work, safe board bring-up, small robot applications, UART diagnostics, and trusted AresPlot capture."
---

# Mambo

Guide a user from evidence to one small, working Mambo robot increment at a time. This is the Agentic Embedded contract: inspect the repository and generated artifacts, teach the reason for each step, make the smallest testable change, and preserve a reproducible record of commands and observations. Prefer the DM-MC02 unless the user names another supported board. Keep all actuator power disabled until the user has confirmed the electrical setup and explicitly asks to enable it.

## Select Mode

- Start in beginner mode. Read [beginner.md](references/beginner.md). Use simple Chinese, define a term the first time it matters, state cause and effect, and request or run one objective check before moving on.
- Enter expert mode only when the user explicitly says `专家模式`, `老手模式`, or an unambiguous equivalent. Read [expert.md](references/expert.md). Be concise and batch related diagnostics.
- Return to beginner mode when the user says `新手模式` or equivalent. Also fall back, and say why, when wiring, board identity, build output, flash state, or observed behavior conflicts with an assumption.
- Treat beginner and expert as conversation branches, not Git branches. A mode change alters teaching depth and diagnostic batching; it never weakens evidence or safety requirements.
- Keep the safety gates in [troubleshooting-safety.md](references/troubleshooting-safety.md) in both modes. Never flash, reset through a probe, open a debug probe, or enable motor power unless the user explicitly authorizes it and the board, probe, target, and connection are confirmed.

## Route The Work

1. Establish facts first: repository root, `west` workspace, board target, application, toolchain, and the exact physical connection. Read [environment.md](references/environment.md) for host setup and checks.
2. For DM-MC02, read [dm-mc02-wiring.md](references/dm-mc02-wiring.md) before proposing a cable. Treat its unresolved items as blockers, not guesses. The original manual is [dm-mc02-manual-v1.1.pdf](references/dm-mc02-manual-v1.1.pdf).
3. Make the smallest app change that demonstrates one behavior. Inspect the existing sample, board DTS, overlays, Kconfig, and generated build artifacts before editing. Keep motor outputs and controlled XT30 power off during bring-up unless authorized.
4. Build before diagnosing runtime behavior. Report the exact command and result; distinguish a successful build from a flashed image and from an observed board behavior.
5. Use AresPlot only on a trusted debug target. Read [aresplot.md](references/aresplot.md) and [aresplot-config.md](references/aresplot-config.md) before configuring it.

## AresPlot Loop

Use this fixed loop: baseline build; add minimal observables; build; obtain flash authorization; connect the dedicated serial port; capture or plot; inspect one selected interval; form one hypothesis; change one thing; repeat. Do not use `SET_VARIABLE`; the bundled capture tool cannot and must not send it.

- Use the browser workflow at [Web Serial Plotter](https://captainkaz.github.io/web-serial-plotter/) with the matching ELF only on a trusted debug build.
- Use `scripts/aresplot_capture.py` for a read-only, reproducible CSV capture. Require `--trusted-debug-target` and a reviewed JSON config. Start from [aresplot-capture-example.json](references/aresplot-capture-example.json).
- Use `scripts/render_aresplot_csv.py` to inspect a CSV interval offline. Run both scripts with the same Python environment that supplies their optional dependencies.

## Load References Deliberately

- Read [beginner.md](references/beginner.md) for guided setup and a first program.
- Read [expert.md](references/expert.md) for concise diagnostics and evidence batching.
- Read [environment.md](references/environment.md) for Linux, macOS, Windows, west, Python, and serial permissions.
- Read [dm-mc02-wiring.md](references/dm-mc02-wiring.md) for the board-side UART and SWD facts and their limits.
- Read [aresplot.md](references/aresplot.md) for protocol, devicetree, Kconfig, ELF, sampling, and bandwidth details.
- Read [aresplot-config.md](references/aresplot-config.md) for capture JSON fields, address windows, types, and CLI use.
- Read [troubleshooting-safety.md](references/troubleshooting-safety.md) when a build, serial link, probe, or observed behavior fails.
4 changes: 4 additions & 0 deletions skills/mambo/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "Mambo Embedded Robotics"
short_description: "Build and debug Mambo Zephyr robots safely"
default_prompt: "Use $mambo to build and safely debug my DM-MC02 robot program."
21 changes: 21 additions & 0 deletions skills/mambo/references/aresplot-capture-example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"serial_port": "/dev/ttyUSB0",
"baud_rate": 921600,
"sample_rate_hz": 100,
"duration_seconds": 3,
"output_csv": "capture.csv",
"ack_timeout_seconds": 2,
"max_frame_bytes": 256,
"variables": [
{
"name": "loop_time_us",
"address": "0x24000100",
"type": "uint32"
},
{
"name": "setpoint",
"address": "0x24000104",
"type": "float32"
}
]
}
134 changes: 134 additions & 0 deletions skills/mambo/references/aresplot-capture-schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Mambo AresPlot Read-Only Capture Configuration",
"type": "object",
"required": [
"serial_port",
"baud_rate",
"duration_seconds",
"output_csv",
"variables"
],
"properties": {
"serial_port": {
"type": "string",
"minLength": 1
},
"baud_rate": {
"type": "integer",
"minimum": 1
},
"sample_rate_hz": {
"type": "integer",
"minimum": 1,
"maximum": 1000
},
"sample_period_ms": {
"type": "integer",
"minimum": 1
},
"duration_seconds": {
"type": "number",
"exclusiveMinimum": 0
},
"output_csv": {
"type": "string",
"minLength": 1
},
"ack_timeout_seconds": {
"type": "number",
"exclusiveMinimum": 0
},
"max_frame_bytes": {
"type": "integer",
"minimum": 64,
"maximum": 512
},
"max_variables": {
"type": "integer",
"minimum": 1,
"maximum": 50
},
"address_ranges": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["start", "end"],
"properties": {
"start": {
"$ref": "#/$defs/address"
},
"end": {
"$ref": "#/$defs/address"
}
},
"additionalProperties": false
}
},
"variables": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["name", "address", "type"],
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"address": {
"$ref": "#/$defs/address"
},
"type": {
"enum": [
"int8",
"uint8",
"int16",
"uint16",
"int32",
"uint32",
"float32",
"bool"
]
}
},
"additionalProperties": false
}
}
},
"allOf": [
{
"oneOf": [
{
"required": ["sample_rate_hz"],
"not": {
"required": ["sample_period_ms"]
}
},
{
"required": ["sample_period_ms"],
"not": {
"required": ["sample_rate_hz"]
}
}
]
}
],
"additionalProperties": false,
"$defs": {
"address": {
"oneOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 4294967295
},
{
"type": "string",
"pattern": "^(0x[0-9a-fA-F]+|[0-9]+)$"
}
]
}
}
}
30 changes: 30 additions & 0 deletions skills/mambo/references/aresplot-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# AresPlot Capture Config

Run only on a trusted debug target. The capture CLI sends `SET_SAMPLE_RATE`, then `START_MONITOR`, and finally a zero-variable `START_MONITOR` to stop; it never implements or sends `SET_VARIABLE`.

## JSON Fields

Required fields are `serial_port`, `baud_rate`, exactly one of `sample_rate_hz` or `sample_period_ms`, `duration_seconds`, `output_csv`, and `variables`. Use `aresplot-capture-schema.json` for the machine-readable schema and `aresplot-capture-example.json` as the starting configuration.

Each variable requires `name`, `address`, and `type`. Addresses accept JSON integers or strings such as `"0x24000100"`. Names and addresses must be unique, and each address must be naturally aligned for its type. Accepted CLI types are `int8`, `uint8`, `int16`, `uint16`, `int32`, `uint32`, `float32`, and `bool`. The header also names `float64`, but this CLI rejects it because the current firmware emits a placeholder `0.0`, not a float64 observation.

## Choose Addresses From Evidence

Never invent or reuse an address from another build. Build first, preserve `build/zephyr/zephyr.elf`, and resolve each symbol from that exact ELF. The Web Serial Plotter can search the imported ELF. For a command-line check, read `CMAKE_NM:FILEPATH` from the build directory's `CMakeCache.txt`, then run that `arm-zephyr-eabi-nm` executable with `-S -n` on `zephyr.elf` and match the complete symbol name.

Monitor only stable, naturally aligned global or `static` scalar observables. Prefer a dedicated `static volatile` debug mirror updated by the thread that owns the source state; `volatile` keeps the observation in memory but is not a synchronization primitive. Do not monitor a stack local, a heap object that may be freed, MMIO, a pointer value when the intended data is its target, a multiword snapshot, or an actuator command variable. Rebuild and re-resolve every address after code, Kconfig, devicetree, linker, or toolchain changes.

Optional fields: `ack_timeout_seconds` (default 2), `max_frame_bytes` (default 256, range 64..512), and `address_ranges`. An omitted range list uses the DM-MC02 Zephyr memory regions: DTCM `0x20000000..0x2001ffff`, SRAM0 `0x24000000..0x2404ffff`, SRAM1/2 `0x30000000..0x30007fff`, and SRAM4 `0x38000000..0x38003fff`. A supplied range list can only narrow the permitted target addresses. The CLI checks that every typed value fits inside one permitted range.

Start from `aresplot-capture-example.json`. Override config values with `--port`, `--baud`, `--sample-rate-hz`, `--sample-period-ms`, `--duration`, and `--output`. Exactly one rate form is accepted: `sample_period_ms` is converted to a whole `sample_rate_hz` before transmission; the wire payload is always the firmware protocol's `uint32 rate_hz` little-endian value. Pass `--trusted-debug-target` deliberately. Inspect timestamp gaps after every capture and reduce rate or series count when gaps occur.

```sh
python3 scripts/aresplot_capture.py \
--config references/aresplot-capture-example.json \
--trusted-debug-target --duration 3

python3 scripts/render_aresplot_csv.py capture.csv \
--series loop_time_us --start 0 --end 3 --output loop.png
```

`--start` and `--end` are seconds in the renderer's unwrapped MCU timeline. The capture summary counts MCU timestamp gaps larger than two expected periods; treat a nonzero count as a reason to reduce rate or channel count. The renderer reports malformed rows and timestamp wraps/resets instead of silently treating them as normal samples.
27 changes: 27 additions & 0 deletions skills/mambo/references/aresplot.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# AresPlot In Mambo

Use AresPlot only on a trusted debug target. The protocol accepts raw MCU addresses and the firmware dereferences them. Read-only host tooling does not make an untrusted image or wrong address harmless.

## Repository Behavior

- `include/ares/protocol/plotter/aresplot_protocol.h` defines SOP `0xA5`, EOP `0x5A`, command IDs, types, and defaults.
- `lib/ares/protocol/plotter/aresplot_protocol.c` frames as `SOP, CMD, LEN_LE16, payload, XOR checksum, EOP`. The XOR covers CMD, both length bytes, and payload.
- `START_MONITOR` payload is a count byte followed by `address_le32, type_u8` for each variable. A zero count stops monitoring. `SET_SAMPLE_RATE` carries `rate_hz_le32`. ACK payload is `acknowledged_cmd, status`.
- Monitor data is `timestamp_ms_le32` followed by one `float32` per requested variable. The firmware converts supported source types to float32 before sending.
- `CONFIG_PLOTTER=y` creates an automatic UART binding using `DT_ALIAS(plot)`. Define a `plot` alias in the final devicetree or use the manual binding path demonstrated by `plotter_demo`.
- `CONFIG_PLOTTER` selects the protocol, UART interface, and ARES communication library. `CONFIG_ARESPLOT_FREQ` has range 1..1000 and affects the automatic default. `CONFIG_ARESPLOT_MAX_VARS_TO_MONITOR` defaults to 10; `CONFIG_ARESPLOT_SHARED_BUFFER_SIZE` defaults to 256.
- `samples/communication/plotter_demo` shows explicit binding and variable registration. `plotter_auto` shows automatic binding but its board setup must still supply the selected UART and `plot` alias.

## UART And ELF Workflow

Use 921600 baud, 8N1 on the dedicated AresPlot UART when the application/overlay configures that rate. Preserve `build/zephyr/zephyr.elf`; import it into [Web Serial Plotter](https://captainkaz.github.io/web-serial-plotter/) to select symbols by name. Treat ELF addresses as valid only for that exact build and trusted board image. Rebuild, re-import, and review the address list after layout-changing code or configuration changes.

## Types And Limits

The header defines `int8`, `uint8`, `int16`, `uint16`, `int32`, `uint32`, `float32`, `float64`, and `bool`. The capture CLI accepts every implemented monitoring type except `float64`: it rejects `float64` with a compatibility error because the current sender has no `FLOAT64` case and emits `0.0` through `default`. `bool` is sent as `0.0` or `1.0`.

For `N` variables, each monitor payload is `4 + 4N` bytes and the full outgoing frame is `10 + 4N` bytes. At 921600 baud, 8N1 carries at most about 92,160 bytes/s before protocol, scheduling, and logging overhead. Approximate required wire bytes/s as `(10 + 4N) * sample_rate_hz`; leave margin and start low. Sampling faster than the variable update rate only repeats values. The firmware's timer drives sends and `send_raw()` calls `uart_tx()` directly without queue/backpressure, so do not claim a lossless 1000 Hz capture. Detect timestamp gaps in the CSV and lower rate or channel count if the UART cannot keep up. Rates above 1000 collapse to a 1 ms period even though the host command accepts a 32-bit rate.

## Debug Loop

Build a baseline. Add one or two non-actuating observables. Build again. Obtain flash authorization. Connect the dedicated serial link. Capture/plot a short interval. Inspect one interval, state one hypothesis, change one thing, and repeat. Never use plotter control features to write a variable during this workflow.
Loading
Loading