This commit is contained in:
Myfro9
2026-06-22 16:41:47 +08:00
20 changed files with 290 additions and 1498 deletions
+3
View File
@@ -345,3 +345,6 @@ vercel-react-view-transitions/references/nextjs.md
vercel-react-view-transitions/references/patterns.md vercel-react-view-transitions/references/patterns.md
vercel-react-view-transitions/SKILL.md vercel-react-view-transitions/SKILL.md
web-design-guidelines/SKILL.md web-design-guidelines/SKILL.md
*.mjs
*.pckl
*.pyc
@@ -0,0 +1,143 @@
# Updating Existing Local Plugins
Use this reference when a plugin already exists and the request is about updating the plugin during
local development.
All scripts here are specified relative to the skill root. Update the path for running the scripts
depending on your current working directory.
## When To Use This Flow
Use this flow when all of the following are true:
- the plugin already exists locally
- the marketplace entry already points at the plugin source you are editing
- the user wants Codex to see the updated plugin without manually editing marketplace files
If the user still needs the initial plugin entry or marketplace structure created, use the scaffold
flow first and only then switch to this reinstall flow.
## Update Loop
1. Update the plugin manifest to a single Codex cachebuster suffix:
```bash
python3 scripts/update_plugin_cachebuster.py \
<plugin-path>
```
Prefer the default helper behavior here. If you omit `--cachebuster`, the helper uses a UTC
timestamp down to seconds, which is the recommended path for routine local iteration.
Only use a manual cachebuster override when the user explicitly asks for one or when a workflow
outside Codex depends on a specific token:
```bash
python3 scripts/update_plugin_cachebuster.py \
<plugin-path> \
--cachebuster local-20260519-184516
```
2. For the default scaffolded flow, read the marketplace name from the personal marketplace file:
```bash
python3 scripts/read_marketplace_name.py
```
Here, "personal marketplace" means the marketplace whose file is at
`~/.agents/plugins/marketplace.json`. On Windows, use the equivalent path under the user profile.
The helper uses Python's home-directory resolution and prints the marketplace name to use when
constructing the install command.
To read the name from a different marketplace file, pass the path directly:
```bash
python3 scripts/read_marketplace_name.py --marketplace-path <path-to-marketplace.json>
```
3. Reinstall from that marketplace name:
```bash
codex plugin add <plugin-name>@<marketplace-name-from-marketplace-json>
```
The default personal marketplace is discovered implicitly from
`~/.agents/plugins/marketplace.json`. You do not need `codex plugin marketplace add` for that
path, and `codex plugin marketplace list` is not the right check for whether that default
marketplace exists.
4. If the plugin is not using the personal marketplace file, check which configured local
marketplace is actually surfacing that plugin:
```bash
codex plugin list
```
If the plugin is not in the personal marketplace file, confirm which marketplace entry points at
the plugin source you are editing and make sure that marketplace is still local. If it is a
different local marketplace, reinstall from that marketplace name instead of forcing the personal
marketplace flow. If it is not local, stop and help the user resolve the mismatch before
continuing.
5. If the plugin lives in a different confirmed local marketplace, substitute that marketplace
name:
```bash
codex plugin add <plugin-name>@<local-marketplace>
```
6. Prompt the user to use a new thread to try the updated plugin, so that Codex picks up new skills
and tools.
## Cachebuster Policy
- Preserve the existing version prefix and replace only the suffix.
- Treat the preserved prefix as everything before `+`.
- Use the format:
```text
<base-version>+codex.<cachebuster>
```
Examples:
- `0.1.0` → `0.1.0+codex.local-20260519-184516`
- `0.1.0+codex.old-token` → `0.1.0+codex.local-20260519-184516`
- `1.2.3-beta.1+codex.prev` → `1.2.3-beta.1+codex.local-20260519-184516`
- `dev-build+other-tag` → `dev-build+codex.local-20260519-184516`
Replace the existing Codex cachebuster instead of appending another one. Do not keep incrementing
numeric version components just to trigger reinstall behavior.
## Marketplace Rules
- Marketplace manipulation should happen through commands, not by hand-editing `marketplace.json`
or `config.toml` during this update/reinstall flow.
- Prefer the personal marketplace file for the default scaffolded flow.
- Read the personal marketplace name with
`python3 scripts/read_marketplace_name.py` and use the printed value when constructing
`codex plugin add <plugin-name>@<marketplace-name>`.
- For non-default marketplace files, use
`python3 scripts/read_marketplace_name.py --marketplace-path <path-to-marketplace.json>` to read
the name before constructing reinstall commands.
- Do not tell the user to run `codex plugin marketplace add` for the default personal-marketplace
flow. That marketplace is discovered implicitly by Codex.
- If the user specified a different marketplace path, make sure that marketplace is installed
before giving install or reinstall instructions. Non-default marketplace paths are not
discovered implicitly.
- Use `codex plugin list` when the plugin lives in a different configured marketplace and you need
to confirm which marketplace is surfacing that plugin.
- If a non-default local marketplace has not been configured yet, install it with
`codex plugin marketplace add <path-to-marketplace-root>` before telling the user to run
`codex plugin add <plugin-name>@<marketplace-name>`.
- If the plugin is not in the personal marketplace file, confirm that the selected marketplace is
local before telling the user to reinstall from it.
- If the selected marketplace is not local, stop and help the user resolve that mismatch rather
than pretending the normal local reinstall flow applies.
- If the plugin source is not already the source referenced by the chosen marketplace entry, stop
and fix that first. This update flow does not rewrite marketplace entries.
## After Reinstall
After reinstalling, prompt the user to start a new thread for testing. That is the safe boundary for
picking up the updated plugin and its MCP tools.
@@ -0,0 +1,48 @@
#!/usr/bin/env python3
"""Print the top-level marketplace name from any marketplace.json file."""
from __future__ import annotations
import argparse
import json
import sys
from pathlib import Path
def default_marketplace_path() -> Path:
return Path.home() / ".agents" / "plugins" / "marketplace.json"
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description=(
"Print the top-level marketplace name from marketplace.json. Defaults to the personal "
"marketplace path under the current home directory."
)
)
parser.add_argument(
"--marketplace-path",
default=str(default_marketplace_path()),
help="Path to marketplace.json",
)
return parser.parse_args()
def main() -> None:
args = parse_args()
marketplace_path = Path(args.marketplace_path).expanduser().resolve()
payload = json.loads(marketplace_path.read_text(encoding="utf-8"))
if not isinstance(payload, dict):
raise ValueError(f"{marketplace_path} must contain a JSON object.")
name = payload.get("name")
if not isinstance(name, str) or not name.strip():
raise ValueError(f"{marketplace_path} must contain a non-empty string 'name'.")
print(name.strip())
if __name__ == "__main__":
try:
main()
except Exception as err: # noqa: BLE001 - CLI should surface a single clear message.
print(str(err), file=sys.stderr)
raise SystemExit(1) from err
@@ -0,0 +1,78 @@
#!/usr/bin/env python3
"""Rewrite a local plugin version to a single Codex cachebuster suffix."""
from __future__ import annotations
import argparse
import json
import re
import sys
from datetime import datetime, timezone
from pathlib import Path
CACHEBUSTER_PREFIX = "codex"
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description=(
"Rewrite a local plugin's version so it preserves everything before '+' and uses "
"a single +codex.<cachebuster> suffix."
)
)
parser.add_argument("plugin_path", help="Path to the plugin root directory")
parser.add_argument(
"--cachebuster",
help="Optional cachebuster token to embed in the plugin version",
)
return parser.parse_args()
def main() -> None:
args = parse_args()
plugin_root = Path(args.plugin_path).expanduser().resolve()
manifest_path = plugin_root / ".codex-plugin" / "plugin.json"
manifest = load_manifest(manifest_path)
version = manifest.get("version")
if not isinstance(version, str) or not version.strip():
raise ValueError(f"{manifest_path} must contain a non-empty string 'version'.")
cachebuster = sanitize_cachebuster(args.cachebuster or default_cachebuster())
next_version = with_cachebuster(version, cachebuster)
manifest["version"] = next_version
manifest_path.write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
print(f"Updated plugin version: {version} -> {next_version}")
def load_manifest(manifest_path: Path) -> dict[str, object]:
if not manifest_path.is_file():
raise FileNotFoundError(f"missing manifest: {manifest_path}")
payload = json.loads(manifest_path.read_text(encoding="utf-8"))
if not isinstance(payload, dict):
raise ValueError(f"{manifest_path} must contain a JSON object.")
return payload
def sanitize_cachebuster(value: str) -> str:
sanitized = re.sub(r"[^a-z0-9-]+", "-", value.strip().lower())
sanitized = re.sub(r"-{2,}", "-", sanitized).strip("-")
if not sanitized:
raise ValueError("Cachebuster must contain at least one letter or digit.")
return sanitized
def default_cachebuster() -> str:
return datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S")
def with_cachebuster(version: str, cachebuster: str) -> str:
version_prefix = version.split("+", 1)[0]
return f"{version_prefix}+{CACHEBUSTER_PREFIX}.{cachebuster}"
if __name__ == "__main__":
try:
main()
except Exception as err: # noqa: BLE001 - CLI should surface a single clear message.
print(str(err), file=sys.stderr)
raise SystemExit(1) from err
-192
View File
@@ -1,192 +0,0 @@
---
name: BMSv4_pincfg
description: Modify an existing STM32CubeMX project for BMSv4 hardware pin and peripheral settings. Use when a CubeMX `.ioc` project already exists and BMSv4 SPI3, SPISW_nCSx / SPIADC_nCSx GPIO outputs, PWM outputs, CUR_poly ADC2 inputs, and specific ADC3 inputs must be configured, code regenerated, and the build re-verified.
metadata:
author: bowei-local
version: "2.1"
compatibility: Requires an existing STM32CubeMX project, local STM32CubeMX installation, and a working CMake build in the target workspace.
---
# BMSv4 Pin Configuration
Apply the BMSv4 hardware pin/peripheral configuration to an existing STM32CubeMX project. Update the `.ioc`, regenerate code with the locally installed CubeMX, then verify the project still builds.
This skill is for modifying an existing CubeMX project only. Do not create a new project when using this skill.
## Preconditions
- Confirm the target workspace already contains a CubeMX `.ioc` file and generated STM32 project structure.
- Confirm CubeMX exists locally and detect the installed CubeMX version before editing `.ioc` metadata.
- Keep the existing project name, MCU, clock tree, toolchain, and user code sections unless the user explicitly asks to change them.
- Preserve `ProjectManager.KeepUserCode=true`.
- Treat the existing project as the baseline. Only change configuration items explicitly described in this skill or explicitly requested by the user.
- If the user asks to modify this skill itself, update only the skill file in that turn. Do not also modify any target STM32 project or `.ioc` unless the user separately asks to apply the updated skill.
## Required BMSv4 configuration
### SPI3
- Enable `SPI3`.
- Configure `SPI3` as `Half-Duplex Master`.
- Use `PC10` as `SPI3_SCK`.
- Use `PC12` as `SPI3_MOSI`.
- Disable hardware NSS and use software NSS.
- Parameters:
- Frame format: `Motorola`
- Data size: `8 Bits`
- First bit: `MSB First`
- Prescaler: `2`
- CPOL: `Low`
- CPHA: `1 Edge`
- CRC calculation: `Disabled`
### Battery switch decoder chip selects
Configure these pins as `GPIO_Output`, label them exactly as listed, and default them to inactive high unless the user explicitly requests another reset state:
- `PE14` -> `SPISW_nCS1`
- `PE12` -> `SPISW_nCS2`
- `PE10` -> `SPISW_nCS3`
- `PE8` -> `SPISW_nCS4`
- `PG1` -> `SPISW_nCS5`
- `PF15` -> `SPISW_nCS6`
### Battery voltage ADC decoder chip selects
Configure these pins as `GPIO_Output`, label them exactly as listed, and default them to inactive high unless the user explicitly requests another reset state:
- `PE13` -> `SPIADC_nCS1`
- `PE11` -> `SPIADC_nCS2`
- `PE9` -> `SPIADC_nCS3`
- `PE7` -> `SPIADC_nCS4`
- `PG0` -> `SPIADC_nCS5`
- `PF14` -> `SPIADC_nCS6`
### Current-sense ADC inputs
Configure the following six pins as `ADC2` analog inputs and label them exactly as listed:
- `PB1` -> `ADC2_IN9` -> `CUR_poly1`
- `PB0` -> `ADC2_IN8` -> `CUR_poly2`
- `PC5` -> `ADC2_IN15` -> `CUR_poly3`
- `PC4` -> `ADC2_IN14` -> `CUR_poly4`
- `PA7` -> `ADC2_IN7` -> `CUR_poly5`
- `PA6` -> `ADC2_IN6` -> `CUR_poly6`
Requirements for these ADC inputs:
- Configure each listed pin as `Analog`.
- Use `No pull-up and no pull-down`.
- Apply the exact labels `CUR_poly1..6`.
- Use `ADC2` for all six channels.
- Preserve any existing ADC peripheral configuration unless the user explicitly asks to change sampling sequences, trigger sources, DMA, scan mode, or conversion timing.
- If the target project does not yet enable an ADC instance for these channels, add the minimum ADC configuration required for CubeMX to keep the pin-to-channel mapping valid, without altering unrelated peripherals.
- Do not stop at pin signal mapping plus regular channel/rank fields. Add whatever CubeMX metadata the installed version requires so the ADC GUI actually shows the channels as selected.
Required `ADC2` parameters for these inputs:
- Clock Prescaler: `PCLK2 divided by 4`
- Resolution: `12 bits`
- Data Alignment: `Right alignment`
- Scan Conversion Mode:
- keep `Disabled` when only one `CUR_poly` channel is configured into the ADC2 regular group
- set `Enabled` when multiple `CUR_poly` channels are configured into the ADC2 regular group
- Continuous Conversion Mode: `Disabled`
- Discontinuous Conversion Mode: `Disabled`
- DMA Continuous Requests: `Disabled`
- End Of Conversion Selection: `EOC flag at the end of single channel conversion`
- Number Of Conversion: set this to the number of `CUR_poly` channels actually configured into the ADC2 regular group
- External Trigger Conversion Source: `Regular Conversion launched by software`
- External Trigger Conversion Edge: `None`
- Rank:
- when one `CUR_poly` channel is configured, use `Rank = 1`
- when multiple `CUR_poly` channels are configured, assign sequential regular ranks starting at `1`
- Injected Number Of Conversions: `0`
- Enable `ADC1, ADC2 and ADC3 global interrupts` in NVIC with preemption priority `0` and sub priority `0`
### Additional ADC3 inputs
Configure the following two pins as analog `ADC3` inputs and label them exactly as listed:
- `PA3` -> `ADC3_IN3` -> `lt3763_cur`
- `PF5` -> `ADC3_IN15` -> `ADC_VBAT_TMP`
Requirements for these ADC inputs (BMSv31-style ADC3 workflow):
- Configure each listed pin as `Analog`.
- Use `No pull-up and no pull-down`.
- Apply the exact labels `lt3763_cur` and `ADC_VBAT_TMP`.
- Use `ADC3` for both channels.
- Preserve any existing `ADC3` configuration unless the user explicitly asks to change sampling sequences, trigger sources, DMA, scan mode, or conversion timing.
- If the target project does not yet enable an `ADC3` instance for these channels, add the minimum ADC configuration required for CubeMX to keep the pin-to-channel mapping valid, without altering unrelated peripherals.
- Keep pin mapping for both channels, but do not require both channels to be simultaneously configured in the ADC3 regular group.
- Treat `ADC3_IN15` specially on `STM32F407ZGTx`: `PF5 -> ADC3_IN15` is a valid ADC3-only pin mapping in the device database, and it must not be modeled using the same shared-signal metadata pattern as `ADC2_IN15` on `PC5`.
- Do not reuse `SH.ADCx_IN15` entries that belong to `ADC1/ADC2` when configuring `PF5 -> ADC3_IN15`. If the installed CubeMX version uses a different metadata representation for ADC3-only `IN15`, preserve or generate that exact representation instead of forcing it into the ADC1/ADC2 shared-signal format.
- ADC3 working mode must follow BMSv31 style:
- initialize ADC3 as single regular conversion (`Scan Conversion Mode = Disabled`, `Number Of Conversion = 1`, `Rank = 1`)
- keep `Continuous Conversion Mode = Disabled`
- keep `Discontinuous Conversion Mode = Disabled`
- keep `DMA Continuous Requests = Disabled`
- keep `End Of Conversion Selection = EOC flag at the end of single channel conversion`
- use software trigger (`External Trigger Conversion Source = Regular Conversion launched by software`, `External Trigger Conversion Edge = None`)
- do channel selection at runtime by reconfiguring `sConfig.Channel` before each conversion (e.g. switch between `ADC_CHANNEL_3` and `ADC_CHANNEL_15`)
## Execution steps
1. Detect the local CubeMX version and confirm the project `.ioc` header is not stamped with a newer version than the installed tool.
2. Open the existing `.ioc` project. Do not replace it with a newly created project.
3. Compare the existing project configuration against the configuration explicitly listed in this skill.
4. Modify only the listed configuration items that differ:
- the `SPI3` mode and parameters listed above
- the twelve named GPIO output definitions listed above
- the six PWM pin assignments, timer channel mappings, timer base settings, and default duty-cycle settings listed above
- the six `CUR_poly` ADC input pin assignments, analog modes, labels, required ADC2 channel mappings, and ADC parameters listed above
- the two additional `ADC3` input pin assignments, analog modes, labels, and required ADC3 channel mappings listed above
- when configuring ADC inputs, also add the CubeMX shared-signal metadata required by the installed version so the ADC page shows the intended `INx` entries as selected
- when configuring `PF5 -> ADC3_IN15`, verify against the local device database that the mapping is ADC3-only and do not alias it to the `ADC1/ADC2 IN15` shared-signal entry used by `PC5`
- for ADC3, keep the two pin mappings but configure ADC3 peripheral as single-conversion runtime-switch mode (BMSv31 style), not fixed multi-channel scan sequence
5. Keep every other existing project configuration unchanged if it is not explicitly covered by this skill, including unrelated peripherals, clocks, middleware, pins, NVIC settings, DMA settings, and user code.
6. If any requested pin conflicts with an existing peripheral assignment, stop and report the conflict instead of silently remapping the hardware.
7. Regenerate code using the installed CubeMX while preserving user code sections.
- This is mandatory after any `.ioc` change. Do not skip regeneration.
8. Validate the generated result before finishing:
- `Core/Src/spi.c` contains `MX_SPI3_Init()` with `SPI_DIRECTION_1LINE`, master mode, prescaler `2`, `SPI_POLARITY_LOW`, `SPI_PHASE_1EDGE`, software NSS, and CRC disabled.
- `Core/Src/gpio.c` initializes the required `GPIOE`, `GPIOF`, and `GPIOG` chip-select pins as outputs.
- `Core/Inc/main.h` exports the requested pin names and ports.
- `Core/Src/tim.c` contains `MX_TIM1_Init()` and `MX_TIM3_Init()` with a `10 kHz` PWM base derived from the project timer clocks.
- The generated compare values default to `50%` duty cycle for `pwm_polyctl1..6`.
- The generated GPIO/pin metadata maps `PA9`, `PA8`, `PC9`, `PC8`, `PC7`, and `PC6` to the requested timer channels.
- The generated GPIO/pin metadata maps `PB1`, `PB0`, `PC5`, `PC4`, `PA7`, and `PA6` to `ADC2_IN9`, `ADC2_IN8`, `ADC2_IN15`, `ADC2_IN14`, `ADC2_IN7`, and `ADC2_IN6` with labels `CUR_poly1..6`.
- The generated GPIO/pin metadata maps `PA3` and `PF5` to `ADC3_IN3` and `ADC3_IN15` with labels `lt3763_cur` and `ADC_VBAT_TMP`.
- The generated ADC configuration matches the required `ADC2` settings: `PCLK2/4`, `12-bit`, right alignment, continuous disabled, discontinuous disabled, DMA continuous requests disabled, single-channel EOC, software trigger, trigger edge none, and injected conversions `0`.
- The ADC2 regular group explicitly includes the requested `CUR_poly` channels rather than only setting the pins to analog input mode.
- `Scan Conversion Mode`, `Number Of Conversion`, and the regular channel `Rank` values are adjusted to match the number of `CUR_poly` channels actually configured in ADC2.
- The `.ioc` contains the CubeMX shared ADC signal metadata needed for the locally installed version to render the requested ADC2 inputs as selected in the GUI, not just low-level regular channel fields.
- Re-open or re-load the `.ioc` with the installed CubeMX and confirm the ADC GUI shows the expected `ADC2` input selections instead of leaving the `INx` list unchecked.
- The `.ioc` contains the CubeMX shared ADC signal metadata needed for the locally installed version to render the requested ADC3 inputs as selected in the GUI, not just low-level pin signal fields.
- Re-open or re-load the `.ioc` with the installed CubeMX and confirm `PA3 -> ADC3_IN3` and `PF5 -> ADC3_IN15` pin mappings are preserved without pin-level conflict warnings.
- `Core/Src/adc.c` (or generated ADC3 init code) uses single regular conversion style for ADC3: scan disabled and number-of-conversion = 1.
- ADC3 channel usage follows runtime channel reconfiguration style instead of fixed two-channel scan sequence.
- `ADC3` `IN15` metadata must not overwrite or corrupt the existing `ADC2_IN15` representation used for `PC5`.
- The generated GPIO settings for the six ADC pins remain `Analog mode` with `No pull-up and no pull-down`.
- The generated GPIO settings for `PA3` and `PF5` remain `Analog mode` with `No pull-up and no pull-down`.
- The NVIC enables `ADC1, ADC2 and ADC3 global interrupts` with preemption priority `0` and sub priority `0`.
- If CubeMX generated or updated ADC init code, it does not silently remove unrelated existing ADC settings outside the channels required for `CUR_poly1..6`, `lt3763_cur`, and `ADC_VBAT_TMP`.
- The `.ioc` still opens in the locally installed CubeMX version.
9. Run `cmake --preset Debug`.
10. Run `cmake --build --preset Debug`.
11. Confirm the expected ELF exists under `build/Debug/`.
12. Treat the task as failed if code generation was not executed or if build is not successful. Do not report completion in that case.
## Notes & guardrails
- Do not infer CubeMX compatibility from memory. Detect the installed version each time.
- Do not hand-edit generated C source first and then try to backfill the `.ioc`; the `.ioc` is the source of truth.
- Do not treat missing detail in this skill as permission to normalize or simplify the rest of the project.
- Do not remove or rewrite existing project configuration that is outside the explicit scope of this skill.
- Do not rename the GPIO labels. They must remain `SPISW_nCS1..6` and `SPIADC_nCS1..6`.
- Do not rename the ADC labels. They must remain `CUR_poly1..6`.
- Do not rename the additional ADC3 labels. They must remain `lt3763_cur` and `ADC_VBAT_TMP`.
- Do not guess PWM frequency parameters from screenshots alone. Derive PSC/ARR/CCR from the actual timer clock in the target project.
- Do not invent ADC parameters that are not explicitly shown or requested; keep unspecified ADC timing details at the generated or pre-existing values unless the user later constrains them.
- Do not leave ADC2 half-configured. It is not sufficient to set only pin analog mode and `ADC2_INx` signal mapping; the required regular ADC2 channels must also be present in the ADC2 configuration.
- Do not leave ADC3 half-configured. It is not sufficient to set only pin analog mode and `ADC3_INx` signal mapping; add the minimum ADC3 configuration and metadata needed for CubeMX to keep and display the requested channels.
- Do not force ADC3 into fixed multi-channel scan mode for these two channels when BMSv31-style behavior is requested.
- Do not assume `ADCx_IN15` metadata is interchangeable across ADC instances on this MCU family. `ADC2_IN15` on `PC5` and `ADC3_IN15` on `PF5` may require different `.ioc` representations.
- Do not add extra ADC channels, sampling logic, or conversion sequencing beyond what is needed to preserve the requested `CUR_poly1..6`, `lt3763_cur`, and `ADC_VBAT_TMP` pin mappings.
- For `_nCS` lines, prefer reset state high so external devices stay deselected after boot.
- If CubeMX generation removes or rewrites required user code outside the modified peripherals, stop and report before making manual source patches.
- If the project uses a non-`Debug` preset name, keep the workspace's existing preset strategy, but still verify a full configure + build path before finishing.
- Do not mark the task complete unless both conditions are met: CubeMX code generation completed successfully, and the project build completed successfully.
-213
View File
@@ -1,213 +0,0 @@
---
name: BMSv4_pincfg
description: Modify an existing STM32CubeMX project for BMSv4 hardware pin and peripheral settings. Use when a CubeMX `.ioc` project already exists and BMSv4 SPI3, SPISW_nCSx / SPIADC_nCSx GPIO outputs, PWM outputs, CUR_poly ADC2 inputs, and specific ADC3 inputs must be configured, code regenerated, and the build re-verified.
metadata:
author: bowei-local
version: "2.1"
compatibility: Requires an existing STM32CubeMX project, local STM32CubeMX installation, and a working CMake build in the target workspace.
---
# BMSv4 Pin Configuration
Apply the BMSv4 hardware pin/peripheral configuration to an existing STM32CubeMX project. Update the `.ioc`, regenerate code with the locally installed CubeMX, then verify the project still builds.
This skill is for modifying an existing CubeMX project only. Do not create a new project when using this skill.
## Preconditions
- Confirm the target workspace already contains a CubeMX `.ioc` file and generated STM32 project structure.
- Confirm CubeMX exists locally and detect the installed CubeMX version before editing `.ioc` metadata.
- Keep the existing project name, MCU, clock tree, toolchain, and user code sections unless the user explicitly asks to change them.
- Preserve `ProjectManager.KeepUserCode=true`.
- Treat the existing project as the baseline. Only change configuration items explicitly described in this skill or explicitly requested by the user.
- If the user asks to modify this skill itself, update only the skill file in that turn. Do not also modify any target STM32 project or `.ioc` unless the user separately asks to apply the updated skill.
## Required BMSv4 configuration
### SPI3
- Enable `SPI3`.
- Configure `SPI3` as `Half-Duplex Master`.
- Use `PC10` as `SPI3_SCK`.
- Use `PC12` as `SPI3_MOSI`.
- Disable hardware NSS and use software NSS.
- Parameters:
- Frame format: `Motorola`
- Data size: `8 Bits`
- First bit: `MSB First`
- Prescaler: `2`
- CPOL: `Low`
- CPHA: `1 Edge`
- CRC calculation: `Disabled`
### Battery switch decoder chip selects
Configure these pins as `GPIO_Output`, label them exactly as listed, and default them to inactive high unless the user explicitly requests another reset state:
- `PE14` -> `SPISW_nCS1`
- `PE12` -> `SPISW_nCS2`
- `PE10` -> `SPISW_nCS3`
- `PE8` -> `SPISW_nCS4`
- `PG1` -> `SPISW_nCS5`
- `PF15` -> `SPISW_nCS6`
### Battery voltage ADC decoder chip selects
Configure these pins as `GPIO_Output`, label them exactly as listed, and default them to inactive high unless the user explicitly requests another reset state:
- `PE13` -> `SPIADC_nCS1`
- `PE11` -> `SPIADC_nCS2`
- `PE9` -> `SPIADC_nCS3`
- `PE7` -> `SPIADC_nCS4`
- `PG0` -> `SPIADC_nCS5`
- `PF14` -> `SPIADC_nCS6`
### PWM outputs
Configure the following pins as timer PWM outputs and label them exactly as listed:
- `PA9` -> `TIM1_CH2` -> `pwm_polyctl1`
- `PA8` -> `TIM1_CH1` -> `pwm_polyctl2`
- `PC9` -> `TIM3_CH4` -> `pwm_polyctl3`
- `PC8` -> `TIM3_CH3` -> `pwm_polyctl4`
- `PC7` -> `TIM3_CH2` -> `pwm_polyctl5`
- `PC6` -> `TIM3_CH1` -> `pwm_polyctl6`
Use PWM output mode with configurable duty cycle. Default duty cycle must be `50%`.
Timer settings for both `TIM1` and `TIM3`:
- Clock source: `Internal Clock`
- PWM frequency: `10 kHz`
- Compute timer parameters from the existing project clocks instead of guessing
- For the standard `STM32F407ZGTx` clock tree used in this workspace, `TIM1` and `TIM3` both see an `84 MHz` timer clock, so use:
- Prescaler `PSC = 83`
- Counter Period `ARR = 99`
- Default Pulse `CCR = 50`
- Keep counter mode `Up`
- Keep clock division `No Division`
- Keep repetition counter `0` unless the selected timer requires a different default generated by CubeMX
### Current-sense ADC inputs
Configure the following six pins as `ADC2` analog inputs and label them exactly as listed:
- `PB1` -> `ADC2_IN9` -> `CUR_poly1`
- `PB0` -> `ADC2_IN8` -> `CUR_poly2`
- `PC5` -> `ADC2_IN15` -> `CUR_poly3`
- `PC4` -> `ADC2_IN14` -> `CUR_poly4`
- `PA7` -> `ADC2_IN7` -> `CUR_poly5`
- `PA6` -> `ADC2_IN6` -> `CUR_poly6`
Requirements for these ADC inputs:
- Configure each listed pin as `Analog`.
- Use `No pull-up and no pull-down`.
- Apply the exact labels `CUR_poly1..6`.
- Use `ADC2` for all six channels.
- Preserve any existing ADC peripheral configuration unless the user explicitly asks to change sampling sequences, trigger sources, DMA, scan mode, or conversion timing.
- If the target project does not yet enable an ADC instance for these channels, add the minimum ADC configuration required for CubeMX to keep the pin-to-channel mapping valid, without altering unrelated peripherals.
- Do not stop at pin signal mapping plus regular channel/rank fields. Add whatever CubeMX metadata the installed version requires so the ADC GUI actually shows the channels as selected.
Required `ADC2` parameters for these inputs:
- Clock Prescaler: `PCLK2 divided by 4`
- Resolution: `12 bits`
- Data Alignment: `Right alignment`
- Scan Conversion Mode:
- keep `Disabled` when only one `CUR_poly` channel is configured into the ADC2 regular group
- set `Enabled` when multiple `CUR_poly` channels are configured into the ADC2 regular group
- Continuous Conversion Mode: `Disabled`
- Discontinuous Conversion Mode: `Disabled`
- DMA Continuous Requests: `Disabled`
- End Of Conversion Selection: `EOC flag at the end of single channel conversion`
- Number Of Conversion: set this to the number of `CUR_poly` channels actually configured into the ADC2 regular group
- External Trigger Conversion Source: `Regular Conversion launched by software`
- External Trigger Conversion Edge: `None`
- Rank:
- when one `CUR_poly` channel is configured, use `Rank = 1`
- when multiple `CUR_poly` channels are configured, assign sequential regular ranks starting at `1`
- Injected Number Of Conversions: `0`
- Enable `ADC1, ADC2 and ADC3 global interrupts` in NVIC with preemption priority `0` and sub priority `0`
### Additional ADC3 inputs
Configure the following two pins as analog `ADC3` inputs and label them exactly as listed:
- `PA3` -> `ADC3_IN3` -> `lt3763_cur`
- `PF5` -> `ADC3_IN15` -> `ADC_VBAT_TMP`
Requirements for these ADC inputs (BMSv31-style ADC3 workflow):
- Configure each listed pin as `Analog`.
- Use `No pull-up and no pull-down`.
- Apply the exact labels `lt3763_cur` and `ADC_VBAT_TMP`.
- Use `ADC3` for both channels.
- Preserve any existing `ADC3` configuration unless the user explicitly asks to change sampling sequences, trigger sources, DMA, scan mode, or conversion timing.
- If the target project does not yet enable an `ADC3` instance for these channels, add the minimum ADC configuration required for CubeMX to keep the pin-to-channel mapping valid, without altering unrelated peripherals.
- Keep pin mapping for both channels, but do not require both channels to be simultaneously configured in the ADC3 regular group.
- Treat `ADC3_IN15` specially on `STM32F407ZGTx`: `PF5 -> ADC3_IN15` is a valid ADC3-only pin mapping in the device database, and it must not be modeled using the same shared-signal metadata pattern as `ADC2_IN15` on `PC5`.
- Do not reuse `SH.ADCx_IN15` entries that belong to `ADC1/ADC2` when configuring `PF5 -> ADC3_IN15`. If the installed CubeMX version uses a different metadata representation for ADC3-only `IN15`, preserve or generate that exact representation instead of forcing it into the ADC1/ADC2 shared-signal format.
- ADC3 working mode must follow BMSv31 style:
- initialize ADC3 as single regular conversion (`Scan Conversion Mode = Disabled`, `Number Of Conversion = 1`, `Rank = 1`)
- keep `Continuous Conversion Mode = Disabled`
- keep `Discontinuous Conversion Mode = Disabled`
- keep `DMA Continuous Requests = Disabled`
- keep `End Of Conversion Selection = EOC flag at the end of single channel conversion`
- use software trigger (`External Trigger Conversion Source = Regular Conversion launched by software`, `External Trigger Conversion Edge = None`)
- do channel selection at runtime by reconfiguring `sConfig.Channel` before each conversion (e.g. switch between `ADC_CHANNEL_3` and `ADC_CHANNEL_15`)
## Execution steps
1. Detect the local CubeMX version and confirm the project `.ioc` header is not stamped with a newer version than the installed tool.
2. Open the existing `.ioc` project. Do not replace it with a newly created project.
3. Compare the existing project configuration against the configuration explicitly listed in this skill.
4. Modify only the listed configuration items that differ:
- the `SPI3` mode and parameters listed above
- the twelve named GPIO output definitions listed above
- the six PWM pin assignments, timer channel mappings, timer base settings, and default duty-cycle settings listed above
- the six `CUR_poly` ADC input pin assignments, analog modes, labels, required ADC2 channel mappings, and ADC parameters listed above
- the two additional `ADC3` input pin assignments, analog modes, labels, and required ADC3 channel mappings listed above
- when configuring ADC inputs, also add the CubeMX shared-signal metadata required by the installed version so the ADC page shows the intended `INx` entries as selected
- when configuring `PF5 -> ADC3_IN15`, verify against the local device database that the mapping is ADC3-only and do not alias it to the `ADC1/ADC2 IN15` shared-signal entry used by `PC5`
- for ADC3, keep the two pin mappings but configure ADC3 peripheral as single-conversion runtime-switch mode (BMSv31 style), not fixed multi-channel scan sequence
5. Keep every other existing project configuration unchanged if it is not explicitly covered by this skill, including unrelated peripherals, clocks, middleware, pins, NVIC settings, DMA settings, and user code.
6. If any requested pin conflicts with an existing peripheral assignment, stop and report the conflict instead of silently remapping the hardware.
7. Regenerate code using the installed CubeMX while preserving user code sections.
- This is mandatory after any `.ioc` change. Do not skip regeneration.
8. Validate the generated result before finishing:
- `Core/Src/spi.c` contains `MX_SPI3_Init()` with `SPI_DIRECTION_1LINE`, master mode, prescaler `2`, `SPI_POLARITY_LOW`, `SPI_PHASE_1EDGE`, software NSS, and CRC disabled.
- `Core/Src/gpio.c` initializes the required `GPIOE`, `GPIOF`, and `GPIOG` chip-select pins as outputs.
- `Core/Inc/main.h` exports the requested pin names and ports.
- `Core/Src/tim.c` contains `MX_TIM1_Init()` and `MX_TIM3_Init()` with a `10 kHz` PWM base derived from the project timer clocks.
- The generated compare values default to `50%` duty cycle for `pwm_polyctl1..6`.
- The generated GPIO/pin metadata maps `PA9`, `PA8`, `PC9`, `PC8`, `PC7`, and `PC6` to the requested timer channels.
- The generated GPIO/pin metadata maps `PB1`, `PB0`, `PC5`, `PC4`, `PA7`, and `PA6` to `ADC2_IN9`, `ADC2_IN8`, `ADC2_IN15`, `ADC2_IN14`, `ADC2_IN7`, and `ADC2_IN6` with labels `CUR_poly1..6`.
- The generated GPIO/pin metadata maps `PA3` and `PF5` to `ADC3_IN3` and `ADC3_IN15` with labels `lt3763_cur` and `ADC_VBAT_TMP`.
- The generated ADC configuration matches the required `ADC2` settings: `PCLK2/4`, `12-bit`, right alignment, continuous disabled, discontinuous disabled, DMA continuous requests disabled, single-channel EOC, software trigger, trigger edge none, and injected conversions `0`.
- The ADC2 regular group explicitly includes the requested `CUR_poly` channels rather than only setting the pins to analog input mode.
- `Scan Conversion Mode`, `Number Of Conversion`, and the regular channel `Rank` values are adjusted to match the number of `CUR_poly` channels actually configured in ADC2.
- The `.ioc` contains the CubeMX shared ADC signal metadata needed for the locally installed version to render the requested ADC2 inputs as selected in the GUI, not just low-level regular channel fields.
- Re-open or re-load the `.ioc` with the installed CubeMX and confirm the ADC GUI shows the expected `ADC2` input selections instead of leaving the `INx` list unchecked.
- The `.ioc` contains the CubeMX shared ADC signal metadata needed for the locally installed version to render the requested ADC3 inputs as selected in the GUI, not just low-level pin signal fields.
- Re-open or re-load the `.ioc` with the installed CubeMX and confirm `PA3 -> ADC3_IN3` and `PF5 -> ADC3_IN15` pin mappings are preserved without pin-level conflict warnings.
- `Core/Src/adc.c` (or generated ADC3 init code) uses single regular conversion style for ADC3: scan disabled and number-of-conversion = 1.
- ADC3 channel usage follows runtime channel reconfiguration style instead of fixed two-channel scan sequence.
- `ADC3` `IN15` metadata must not overwrite or corrupt the existing `ADC2_IN15` representation used for `PC5`.
- The generated GPIO settings for the six ADC pins remain `Analog mode` with `No pull-up and no pull-down`.
- The generated GPIO settings for `PA3` and `PF5` remain `Analog mode` with `No pull-up and no pull-down`.
- The NVIC enables `ADC1, ADC2 and ADC3 global interrupts` with preemption priority `0` and sub priority `0`.
- If CubeMX generated or updated ADC init code, it does not silently remove unrelated existing ADC settings outside the channels required for `CUR_poly1..6`, `lt3763_cur`, and `ADC_VBAT_TMP`.
- The `.ioc` still opens in the locally installed CubeMX version.
9. Run `cmake --preset Debug`.
10. Run `cmake --build --preset Debug`.
11. Confirm the expected ELF exists under `build/Debug/`.
12. Treat the task as failed if code generation was not executed or if build is not successful. Do not report completion in that case.
## Notes & guardrails
- Do not infer CubeMX compatibility from memory. Detect the installed version each time.
- Do not hand-edit generated C source first and then try to backfill the `.ioc`; the `.ioc` is the source of truth.
- Do not treat missing detail in this skill as permission to normalize or simplify the rest of the project.
- Do not remove or rewrite existing project configuration that is outside the explicit scope of this skill.
- Do not rename the GPIO labels. They must remain `SPISW_nCS1..6` and `SPIADC_nCS1..6`.
- Do not rename the ADC labels. They must remain `CUR_poly1..6`.
- Do not rename the additional ADC3 labels. They must remain `lt3763_cur` and `ADC_VBAT_TMP`.
- Do not guess PWM frequency parameters from screenshots alone. Derive PSC/ARR/CCR from the actual timer clock in the target project.
- Do not invent ADC parameters that are not explicitly shown or requested; keep unspecified ADC timing details at the generated or pre-existing values unless the user later constrains them.
- Do not leave ADC2 half-configured. It is not sufficient to set only pin analog mode and `ADC2_INx` signal mapping; the required regular ADC2 channels must also be present in the ADC2 configuration.
- Do not leave ADC3 half-configured. It is not sufficient to set only pin analog mode and `ADC3_INx` signal mapping; add the minimum ADC3 configuration and metadata needed for CubeMX to keep and display the requested channels.
- Do not force ADC3 into fixed multi-channel scan mode for these two channels when BMSv31-style behavior is requested.
- Do not assume `ADCx_IN15` metadata is interchangeable across ADC instances on this MCU family. `ADC2_IN15` on `PC5` and `ADC3_IN15` on `PF5` may require different `.ioc` representations.
- Do not add extra ADC channels, sampling logic, or conversion sequencing beyond what is needed to preserve the requested `CUR_poly1..6`, `lt3763_cur`, and `ADC_VBAT_TMP` pin mappings.
- For `_nCS` lines, prefer reset state high so external devices stay deselected after boot.
- If CubeMX generation removes or rewrites required user code outside the modified peripherals, stop and report before making manual source patches.
- If the project uses a non-`Debug` preset name, keep the workspace's existing preset strategy, but still verify a full configure + build path before finishing.
- Do not mark the task complete unless both conditions are met: CubeMX code generation completed successfully, and the project build completed successfully.
-152
View File
@@ -1,152 +0,0 @@
#MicroXplorer Configuration settings - do not modify
CAD.formats=
CAD.pinconfig=
CAD.provider=
Dma.Request0=USART2_RX
Dma.Request1=USART2_TX
Dma.RequestsNb=2
Dma.USART2_RX.0.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART2_RX.0.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART2_RX.0.Instance=DMA1_Stream5
Dma.USART2_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART2_RX.0.MemInc=DMA_MINC_ENABLE
Dma.USART2_RX.0.Mode=DMA_NORMAL
Dma.USART2_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART2_RX.0.PeriphInc=DMA_PINC_DISABLE
Dma.USART2_RX.0.Priority=DMA_PRIORITY_LOW
Dma.USART2_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
Dma.USART2_TX.1.Direction=DMA_MEMORY_TO_PERIPH
Dma.USART2_TX.1.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART2_TX.1.Instance=DMA1_Stream6
Dma.USART2_TX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART2_TX.1.MemInc=DMA_MINC_ENABLE
Dma.USART2_TX.1.Mode=DMA_NORMAL
Dma.USART2_TX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART2_TX.1.PeriphInc=DMA_PINC_DISABLE
Dma.USART2_TX.1.Priority=DMA_PRIORITY_LOW
Dma.USART2_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
File.Version=6
GPIO.groupedBy=Group By Peripherals
KeepUserPlacement=false
Mcu.CPN=STM32F407ZGT6
Mcu.Family=STM32F4
Mcu.IP0=DMA
Mcu.IP1=NVIC
Mcu.IP2=RCC
Mcu.IP3=SYS
Mcu.IP4=USART2
Mcu.IPNb=5
Mcu.Name=STM32F407Z(E-G)Tx
Mcu.Package=LQFP144
Mcu.Pin0=PH0-OSC_IN
Mcu.Pin1=PH1-OSC_OUT
Mcu.Pin2=PA13
Mcu.Pin3=PA14
Mcu.Pin4=PD5
Mcu.Pin5=PD6
Mcu.PinsNb=6
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32F407ZGTx
MxCube.Version=6.11.1
MxDb.Version=DB.6.0.111
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.DMA1_Stream5_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
NVIC.DMA1_Stream6_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false
NVIC.USART2_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
PA13.Mode=Serial_Wire
PA13.Signal=SYS_JTMS-SWDIO
PA14.Mode=Serial_Wire
PA14.Signal=SYS_JTCK-SWCLK
PD5.Mode=Asynchronous
PD5.Signal=USART2_TX
PD6.Mode=Asynchronous
PD6.Signal=USART2_RX
PH0-OSC_IN.Mode=HSE-External-Oscillator
PH0-OSC_IN.Signal=RCC_OSC_IN
PH1-OSC_OUT.Mode=HSE-External-Oscillator
PH1-OSC_OUT.Signal=RCC_OSC_OUT
PinOutPanel.RotationAngle=0
ProjectManager.AskForMigrate=true
ProjectManager.BackupPrevious=false
ProjectManager.CompilerOptimize=6
ProjectManager.ComputerToolchain=false
ProjectManager.CoupleFile=true
ProjectManager.CustomerFirmwarePackage=
ProjectManager.DefaultFWLocation=true
ProjectManager.DeletePrevious=true
ProjectManager.DeviceId=STM32F407ZGTx
ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.28.3
ProjectManager.FreePins=false
ProjectManager.HalAssertFull=false
ProjectManager.HeapSize=0x200
ProjectManager.KeepUserCode=true
ProjectManager.LastFirmware=true
ProjectManager.LibraryCopy=1
ProjectManager.MainLocation=Core/Src
ProjectManager.NoMain=false
ProjectManager.PreviousToolchain=
ProjectManager.ProjectBuild=false
ProjectManager.ProjectFileName=BMSv4.ioc
ProjectManager.ProjectName=BMSv4
ProjectManager.ProjectStructure=
ProjectManager.RegisterCallBack=
ProjectManager.StackSize=0x400
ProjectManager.TargetToolchain=CMake
ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_USART2_UART_Init-USART2-false-HAL-true
RCC.48MHZClocksFreq_Value=42000000
RCC.AHBFreq_Value=84000000
RCC.APB1CLKDivider=RCC_HCLK_DIV2
RCC.APB1Freq_Value=42000000
RCC.APB1TimFreq_Value=84000000
RCC.APB2CLKDivider=RCC_HCLK_DIV1
RCC.APB2Freq_Value=84000000
RCC.APB2TimFreq_Value=84000000
RCC.CortexFreq_Value=84000000
RCC.EthernetFreq_Value=84000000
RCC.FCLKCortexFreq_Value=84000000
RCC.FCLKFreq_Value=84000000
RCC.FamilyName=M
RCC.HCLKFreq_Value=84000000
RCC.HSE_VALUE=25000000
RCC.HSI_VALUE=16000000
RCC.I2SClocksFreq_Value=96000000
RCC.IPParameters=48MHZClocksFreq_Value,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2CLKDivider,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,EthernetFreq_Value,FCLKCortexFreq_Value,FCLKFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2SClocksFreq_Value,LSE_VALUE,LSI_VALUE,MCO2PinFreq_Value,PLLCLKFreq_Value,PLLM,PLLN,PLLP,PLLQ,PLLQCLKFreq_Value,PLLSourceVirtual,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VcooutputI2S
RCC.LSE_VALUE=32768
RCC.LSI_VALUE=32000
RCC.MCO2PinFreq_Value=84000000
RCC.PLLCLKFreq_Value=84000000
RCC.PLLM=25
RCC.PLLN=168
RCC.PLLP=RCC_PLLP_DIV2
RCC.PLLQ=4
RCC.PLLQCLKFreq_Value=42000000
RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE
RCC.RTCFreq_Value=32000
RCC.RTCHSEDivFreq_Value=12500000
RCC.SYSCLKFreq_VALUE=84000000
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
RCC.VCOI2SOutputFreq_Value=192000000
RCC.VCOInputFreq_Value=1000000
RCC.VCOOutputFreq_Value=168000000
RCC.VcooutputI2S=96000000
USART2.BaudRate=115200
USART2.IPParameters=VirtualMode,BaudRate,Mode,OverSampling
USART2.Mode=MODE_TX_RX
USART2.OverSampling=UART_OVERSAMPLING_16
USART2.VirtualMode=VM_ASYNC
board=custom
-100
View File
@@ -1,100 +0,0 @@
# VS Code Debug Setup
Use this guide when the reproduction workspace must be flashable and debuggable in VS Code with ST-Link and Cortex-Debug.
## Expected local prerequisites
- `STM32CubeCLT` installed locally
- `marus25.cortex-debug` extension available in VS Code
- `STM32_Programmer_CLI` on `PATH` or otherwise discoverable by VS Code tasks
## 1. `.vscode/settings.json`
Keep the active CMake preset on `Debug` and point VS Code to the local CubeCLT root.
```json
{
"files.associations": {
"tcp_client.h": "c",
"lwip.h": "c",
"ethernetif.h": "c"
},
"cmake.configurePreset": "Debug",
"cmake.buildPreset": "Debug",
"STM32VSCodeExtension.cubeCLT.path": "C:/ST/STM32CubeCLT_1.19.0"
}
```
## 2. `.vscode/tasks.json`
Provide three tasks:
- `CMake: clean rebuild`
- `CubeProg: Flash project (SWD)`
- `Build + Flash`
Use `${command:cmake.launchTargetPath}` for the download path so the task follows the active target.
## 3. `.vscode/launch.json`
Create both launch and attach profiles with:
- `type: "cortex-debug"`
- `servertype: "stlink"`
- `device: "STM32F407ZGTx"`
- `interface: "swd"`
- `runToEntryPoint: "main"`
- `serverArgs: ["-m", "0"]`
Point `executable` at the reproduction ELF. For this skill's default example:
```json
"executable": "${workspaceFolder}/build/Debug/BMSv4.elf"
```
Keep all tool paths derived from `STM32VSCodeExtension.cubeCLT.path`:
- `serverpath`
- `stm32cubeprogrammer`
- `stlinkPath`
- `armToolchainPath`
- `gdbPath`
- `svdFile`
## 4. `.vscode/c_cpp_properties.json`
Use the CMake Tools provider instead of hardcoded include paths.
```json
{
"version": 4,
"configurations": [
{
"name": "STM32",
"configurationProvider": "ms-vscode.cmake-tools",
"intelliSenseMode": "${default}"
}
]
}
```
## 5. `.vscode/extensions.json`
Recommend, at minimum:
- `ms-vscode.cpptools-extension-pack`
- `ms-vscode.cmake-tools`
- `marus25.cortex-debug`
- `mcu-debug.debug-tracker-vscode`
- `mcu-debug.memory-view`
- `mcu-debug.peripheral-viewer`
- `mcu-debug.rtos-views`
Add project-specific editor helpers only if they are already part of the source workflow.
## 6. Final checks
- `cmake --build --preset Debug` succeeds before debugging.
- VS Code resolves `${command:cmake.launchTargetPath}` to the expected ELF.
- ST-Link GDB server starts without path errors.
- Flash task uses the same ELF that the debug configuration launches.
-167
View File
@@ -1,167 +0,0 @@
# STM32CubeMX Minimal Reproduction Guide
Use this guide when the task is to recreate the known `BMSv4` minimal project for `STM32F407ZGTx` in a clean workspace and prove that the generated project still builds.
## Scope
- CubeMX version: `6.11.1`
- MCU: `STM32F407ZGTx`
- Project name: `BMSv4`
- Toolchain: `CMake`
- Output folder: default to `<workspace>/reproduction`
## 1. Verify tools
Use explicit local paths for CubeMX and fail early if they do not exist.
```powershell
$mxRoot = "C:/Program Files/STMicroelectronics/STM32Cube/STM32CubeMX"
$mxExe = Join-Path $mxRoot "STM32CubeMX.exe"
$javaExe = Join-Path $mxRoot "jre/bin/java.exe"
$mxInfo = Get-Item $mxExe | Select-Object FullName,@{N="Version";E={$_.VersionInfo.ProductVersion}}
$mxInfo
if ($mxInfo.Version -notmatch '^6\.11\.1(?:-.+)?$') {
throw "Unsupported STM32CubeMX version: $($mxInfo.Version). Required: 6.11.1 or 6.11.1-*"
}
```
If the version is not `6.11.1` or `6.11.1-*`, stop immediately. Do not create the project, patch the `.ioc`, or generate code.
## 2. Create the base project
Generate the initial `.ioc` from CubeMX CLI instead of copying an existing project.
```powershell
$workspace = (Get-Location).Path
$projDir = Join-Path $workspace "reproduction"
New-Item -ItemType Directory -Force -Path $projDir | Out-Null
Set-Location $projDir
@'
load STM32F407ZGTx
project name BMSv4
project toolchain CMake
project path __PROJECT_PATH__
config saveas BMSv4.ioc
exit
'@.Replace("__PROJECT_PATH__", $projDir) | Set-Content -Encoding ascii .mx_init.txt
& $javaExe -jar $mxExe -q .mx_init.txt
```
## 3. Patch `.ioc` metadata that CubeMX CLI does not encode reliably
This reproduction needs precise clock, DMA, and NVIC entries. Apply them directly, then regenerate code.
```powershell
$ioc = "BMSv4.ioc"
$content = Get-Content $ioc
$fixes = @(
"RCC.EthernetFreq_Value=84000000",
"RCC.PLLP=RCC_PLLP_DIV2",
"Dma.Request0=USART2_RX",
"Dma.Request1=USART2_TX",
"Dma.RequestsNb=2",
"Dma.USART2_RX.0.Direction=DMA_PERIPH_TO_MEMORY",
"Dma.USART2_RX.0.Instance=DMA1_Stream5",
"Dma.USART2_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode",
"Dma.USART2_TX.1.Direction=DMA_MEMORY_TO_PERIPH",
"Dma.USART2_TX.1.Instance=DMA1_Stream6",
"Dma.USART2_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode",
"Mcu.IP0=DMA",
"Mcu.IP1=NVIC",
"Mcu.IP2=RCC",
"Mcu.IP3=SYS",
"Mcu.IP4=USART2",
"Mcu.IPNb=5",
"NVIC.DMA1_Stream5_IRQn=true\\:0\\:0\\:false\\:false\\:true\\:false\\:true\\:true",
"NVIC.DMA1_Stream6_IRQn=true\\:0\\:0\\:false\\:false\\:true\\:false\\:true\\:true",
"NVIC.ForceEnableDMAVector=true",
"NVIC.USART2_IRQn=true\\:0\\:0\\:false\\:false\\:true\\:false\\:false\\:true",
"ProjectManager.UnderRoot=true",
"ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_USART2_UART_Init-USART2-false-HAL-true"
)
$newLines = $content | Where-Object {
$_ -notmatch '^RCC\.EthernetFreq_Value' -and
$_ -notmatch '^RCC\.PLLP' -and
$_ -notmatch '^Dma\.' -and
$_ -notmatch '^Mcu\.IP' -and
$_ -notmatch '^NVIC\.DMA' -and
$_ -notmatch '^NVIC\.USART2_IRQn' -and
$_ -notmatch '^NVIC\.ForceEnableDMAVector' -and
$_ -notmatch '^ProjectManager\.functionlistsort' -and
$_ -notmatch '^ProjectManager\.UnderRoot'
}
$newLines += $fixes
$newLines | Set-Content -Encoding ascii $ioc
```
## 4. Configure peripheral modes and generate code
Use CubeMX script mode for the main project shape, then generate.
```powershell
@'
config load BMSv4.ioc
set mode RCC HSE-External-Oscillator
set mode SYS Serial_Wire
set mode USART2 Asynchronous
set pin PH0 RCC_OSC_IN
set pin PH1 RCC_OSC_OUT
set pin PA13 SYS_JTMS-SWDIO
set pin PA14 SYS_JTCK-SWCLK
set pin PD5 USART2_TX
set pin PD6 USART2_RX
set ip parameters RCC OscillatorType RCC_OSCILLATORTYPE_HSE, OscillatorTypeHSE RCC_OSCILLATORTYPE_HSE, HSEState RCC_HSE_ON, PLLState RCC_PLL_ON, PLLSource RCC_PLLSOURCE_HSE, PLLM 25, PLLN 168, PLLP PLLP_DIV2, PLLQ 4, SYSCLKSource RCC_SYSCLKSOURCE_PLLCLK, AHBCLKDivider RCC_SYSCLK_DIV1, APB1CLKDivider RCC_HCLK_DIV2, APB2CLKDivider RCC_HCLK_DIV1
set ip parameters USART2 VirtualMode VM_ASYNC, BaudRate 115200, Mode MODE_TX_RX, OverSampling UART_OVERSAMPLING_16
config save
generate code .
exit
'@ | Set-Content -Encoding ascii .mx_config.txt
& $javaExe -jar $mxExe -q .mx_config.txt
```
## 5. Add the minimal user code needed for reproduction
Apply only small, isolated changes inside user-code regions.
```powershell
$usartFile = "Core/Src/usart.c"
$usart = Get-Content $usartFile -Raw
$usartPatch = "/* USER CODE BEGIN 1 */`r`nint __io_putchar(int ch)`r`n{`r`n HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 1000);`r`n return ch;`r`n}`r`n/* USER CODE END 1 */"
$usart = $usart -replace '(?s)/\* USER CODE BEGIN 1 \*/.*?/\* USER CODE END 1 \*/', $usartPatch
$usart | Set-Content -Encoding utf8 $usartFile
$mainFile = "Core/Src/main.c"
$main = Get-Content $mainFile -Raw
$main = $main -replace '(?s)/\* USER CODE BEGIN PV \*/.*?/\* USER CODE END PV \*/', "/* USER CODE BEGIN PV */`r`nuint8_t receiveBuf50[50];`r`n/* USER CODE END PV */"
$main = $main -replace '(?s)/\* USER CODE BEGIN 2 \*/.*?/\* USER CODE END 2 \*/', " /* USER CODE BEGIN 2 */`r`n HAL_UARTEx_ReceiveToIdle_DMA(&huart2, receiveBuf50, sizeof(receiveBuf50));`r`n /* USER CODE END 2 */"
$main = $main -replace '(?s)/\* USER CODE BEGIN 4 \*/.*?/\* USER CODE END 4 \*/', "/* USER CODE BEGIN 4 */`r`nvoid HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)`r`n{`r`n if (huart->Instance == USART2)`r`n {`r`n HAL_UART_Transmit_DMA(&huart2, receiveBuf50, Size);`r`n HAL_UARTEx_ReceiveToIdle_DMA(&huart2, receiveBuf50, sizeof(receiveBuf50));`r`n }`r`n}`r`n/* USER CODE END 4 */"
$main = $main -replace 'PLLP_DIV2', 'RCC_PLLP_DIV2'
$main | Set-Content -Encoding utf8 $mainFile
```
## 6. Restore the VS Code workflow only if needed
If the reproduction must match the existing debug flow, rebuild the `.vscode` files using the patterns in [DEBUG_SETUP.md](./DEBUG_SETUP.md).
## 7. Validate the reproduction
```powershell
cmake --preset Debug
cmake --build --preset Debug
```
Required checks:
- `BMSv4.ioc` reopens cleanly in CubeMX.
- `Core/Src/usart.c` contains the `__io_putchar` user patch.
- `Core/Src/main.c` contains the DMA receive-to-idle user patch.
- `build/Debug/BMSv4.elf` exists after build.
-62
View File
@@ -1,62 +0,0 @@
---
name: cubemx-min-prj
description: Create a minimal STM32CubeMX reproduction project from scratch, regenerate code, and verify the local build/debug setup. Use when Codex needs to reproduce an STM32 issue in a clean workspace, derive a smallest CubeMX+CMake project from an existing board/project, rebuild `.vscode` STM32 debug files, or document the exact CubeMX CLI and `.ioc` patching steps required to recreate the project.
---
# CubeMX Minimal Project
Create a fresh STM32CubeMX project that reproduces only the hardware and firmware behavior the user needs to debug. Prefer a clean, scriptable reproduction over copying a large existing workspace.
## Workflow
1. Inspect the source context.
- Read the target `.ioc`, build presets, and any `.vscode` files before creating the reproduction.
- Identify the minimum MCU, clock tree, peripherals, DMA/NVIC settings, and user-code hooks required to reproduce the issue.
- Keep explicit dates and tool versions. For this workspace, the known-good CubeMX version is `6.11.1`.
2. Verify local tools.
- Detect the installed STM32CubeMX path and version before touching `.ioc` metadata.
- Run the local version check command from [REPRODUCTION_GUIDE.md](./REPRODUCTION_GUIDE.md) first.
- Stop immediately unless the detected version is exactly `6.11.1` or starts with `6.11.1-`.
- Confirm CMake, the selected toolchain, and any STM32CubeCLT paths needed for build/debug are present.
- If the installed CubeMX is older than the source `.ioc` format, stop and report the version mismatch.
3. Create the reproduction workspace.
- Default to a new subdirectory such as `reproduction/` under the current workspace.
- Generate the base project from CubeMX CLI/script mode instead of copying generated sources.
- Keep the project minimal: only add the peripherals, pins, and middleware needed to reproduce the issue.
4. Configure CubeMX deterministically.
- Use CubeMX script commands for project creation, pin assignment, peripheral mode selection, and code generation whenever the CLI supports it.
- If CubeMX CLI cannot express required metadata, patch the `.ioc` directly with exact keys and then regenerate code.
- Treat the `.ioc` as the source of truth. Do not hand-edit generated C files first and backfill the `.ioc` later.
5. Patch only the user-owned parts of generated code.
- Restrict manual source changes to `/* USER CODE BEGIN */` regions or isolated helper functions added specifically for the reproduction.
- Use this for items like `printf` retargeting, DMA idle receive callbacks, or small harness logic that CubeMX cannot generate.
6. Rebuild the developer workflow when requested.
- Mirror `.vscode/settings.json`, `tasks.json`, `launch.json`, `c_cpp_properties.json`, and `extensions.json` only if the user wants a debug-ready workspace.
- Reuse the existing project's naming and only swap the target ELF/project name where needed.
- Read [DEBUG_SETUP.md](./DEBUG_SETUP.md) for the BMSv31-style VS Code template expected in this workspace.
7. Validate before finishing.
- Re-open the `.ioc` in CubeMX after any direct file patching and confirm the GUI reflects the intended configuration.
- Run `cmake --preset Debug` and `cmake --build --preset Debug` unless the user explicitly asks only for scaffolding.
- Confirm the expected ELF exists under `build/Debug/`.
- Treat the task as incomplete if CubeMX generation or local build verification was skipped without user approval.
## Guardrails
- Prefer the smallest reproducible project, not a feature-complete clone.
- Do not proceed with project creation, `.ioc` edits, or code generation when CubeMX is not `6.11.1` or `6.11.1-*`.
- Preserve exact issue-critical details such as clock values, DMA streams, NVIC enables, and peripheral modes.
- Use absolute paths inside one-off local commands only when required by CubeMX or local tooling.
- Keep generated project names, MCU names, and toolchain selections explicit in the final notes.
- If reproducing from a larger project, document what was intentionally omitted.
- If CubeMX silently rewrites required metadata, capture the exact `.ioc` keys that must be re-applied.
## References
- Read [REPRODUCTION_GUIDE.md](./REPRODUCTION_GUIDE.md) when the task is specifically to recreate the known STM32F407ZGTx/BMSv4 minimal project with CubeMX CLI, `.ioc` patching, user-code updates, and local build verification.
- Read [DEBUG_SETUP.md](./DEBUG_SETUP.md) when the task includes restoring VS Code Cortex-Debug, flash tasks, STM32CubeCLT paths, or extension recommendations.
-4
View File
@@ -1,4 +0,0 @@
interface:
display_name: "CubeMX Minimal Project"
short_description: "Create and verify a minimal STM32CubeMX reproduction project."
default_prompt: "Use $cubemx-min-prj to create a minimal STM32CubeMX project that reproduces the target configuration and builds locally."
-428
View File
@@ -1,428 +0,0 @@
---
name: cubemx-min-prj
description: Create an STM32CubeMX minimum project (CMake/VS Code ready) matching STM32F407ZGTx clocks and debug setup. Use when generating a new CubeMX-based STM32 project or updating this workflow; confirm the locally installed CubeMX version before creating or editing any `.ioc` so the project stays openable on the user's machine.
metadata:
author: bowei-local
version: "1.5"
compatibility: Requires STM32CubeMX at C:/Program Files/STMicroelectronics/STM32Cube/STM32CubeMX/STM32CubeMX.exe and STM32CubeCLT available for VS Code debug.
---
# STM32CubeMX Project Creator
Teach Claude to create a new STM32CubeMX project for `STM32F407ZGTx`, output a CMake build for VS Code, and prep debug tasks. The generated project must preserve the required `USART2` behavior exactly, including DMA-based idle reception and the supporting user-code hooks in `usart.c`, `main.c`, and `syscalls.c`.
The skill must be self-contained. Do not inspect, copy from, diff against, or otherwise rely on other user projects as templates or references when generating a new project.
## Preconditions
- Confirm CubeMX exists at `C:/Program Files/STMicroelectronics/STM32Cube/STM32CubeMX/STM32CubeMX.exe`; otherwise stop and report.
- Confirm the installed CubeMX version before generating or editing the project. If the local version cannot be determined, stop and report instead of guessing.
- REQUIRED VERSION LOCK: local STM32CubeMX must be exactly `6.11.1`. If the detected version is not exactly `6.11.1`, stop immediately and report an error; do not proceed. Note: `6.11.1-*` is equal to `6.11.1`.
- Ensure written `.ioc` metadata is `MxCube.Version=6.11.1` for this skill.
- Use only the installed CubeMX, its bundled databases, and the requested project directory as inputs. Do not use another workspace or existing STM32 project as a reference.
- Have an output directory where the new project folder will be created.
- Ask the user for the project name.
- VS Code STM32 extensions are available (CMake Tools, Cortex-Debug, STM32 VS Code Extension).
## Strict IOC acceptance gates
- The generated `.ioc` must match this skill's required configuration exactly (MCU, clock tree, RCC/NVIC/DMA/GPIO/USART2 settings, and pin map). No partial match is acceptable.
- Re-check the final `.ioc` against the required values before finishing; if any field differs, treat as failure and fix/regenerate.
- For `USART2` compatibility, do not hand-write `WordLength/Parity/StopBits` enum lines in `.ioc`. Keep `USART2.IPParameters` minimal (`VirtualMode,BaudRate,Mode,OverSampling`) and let CubeMX resolve 8N1 defaults during load/generation.
- Opening the `.ioc` must not show `Not a valid ioc file` or required-field incompatibility errors.
- If any IOC gate fails, stop, fix in IOC, regenerate, and re-validate before any further edits.
## MCU + clock configuration
- MCU: `STM32F407ZGTx`, package `LQFP144`.
- Clock source: HSE crystal = `25_000_000 Hz` on `PH0/PH1`.
- PLL: source HSE, `PLLM=25`, `PLLN=168`, `PLLP=2`, `PLLQ=4`.
- Resulting clocks: `SYSCLK=84 MHz`, `HCLK=84 MHz`, `APB1=42 MHz`, `APB2=84 MHz`, `I2S=96 MHz`, `MCO2=84 MHz`, `Systick=1 ms`.
- Ensure RCC: `SYSCLK source = PLLCLK`, `LSI = 32000`, and keep the divider values listed here.
## Generation targets
- Toolchain/IDE: CMake (Ninja or Make). Enable `CMAKE_EXPORT_COMPILE_COMMANDS`.
- Languages: C + ASM, C standard C11.
- Linker script: device-generated `STM32F407ZGTx_FLASH.ld`.
- Peripherals to enable by default: RCC, SYS, NVIC, GPIO, DMA, USART2.
- GPIO baseline:
- SWD: `PA13` = `SYS_JTMS-SWDIO`, `PA14` = `SYS_JTCK-SWCLK`
- Oscillators: `PH0/PH1` for HSE
- USART pins: `PD5` = `USART2_TX`, `PD6` = `USART2_RX`
- Remove all other GPIO assignments unless the user explicitly asks for them
- NVIC baseline:
- `NVIC_PRIORITYGROUP_4`
- System handlers enabled as generated by CubeMX
- `SysTick_IRQn` enabled with priority `15`
- Enable `DMA1_Stream5_IRQn` and `DMA1_Stream6_IRQn`
- DMA baseline:
- `USART2_RX`: `DMA1_Stream5`, `DMA_CHANNEL_4`, `DMA_PERIPH_TO_MEMORY`, `DMA_NORMAL`, byte alignment, memory increment enabled, peripheral increment disabled, priority low, FIFO disabled
- `USART2_TX`: `DMA1_Stream6`, `DMA_CHANNEL_4`, `DMA_MEMORY_TO_PERIPH`, `DMA_NORMAL`, byte alignment, memory increment enabled, peripheral increment disabled, priority low, FIFO disabled
- USART2 baseline:
- Virtual mode: `VM_ASYNC`
- Parameters in generated init: `115200`, `8N1`, `TX_RX`, `UART_HWCONTROL_NONE`, `UART_OVERSAMPLING_16`
- `HAL_UART_MspInit()` must configure `PD5/PD6` as `GPIO_AF7_USART2` and link both DMA handles with `__HAL_LINKDMA`
- `stm32f4xx_it.c` must keep `DMA1_Stream5_IRQHandler()` and `DMA1_Stream6_IRQHandler()` calling `HAL_DMA_IRQHandler(&hdma_usart2_rx)` and `HAL_DMA_IRQHandler(&hdma_usart2_tx)`
- Do not add other peripherals unless the user explicitly requests them.
## USART2 runtime behavior
- `printf` redirection pattern:
- Keep `syscalls.c` with `extern int __io_putchar(int ch) __attribute__((weak));`
- Do not implement `__io_putchar()` in `syscalls.c`
- Re-define `int __io_putchar(int ch)` in `Core/Src/usart.c`
- Implementation must call `HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 1000);` and return `ch`
- DMA receive flow:
- In `main.c`, after `MX_GPIO_Init();`, `MX_DMA_Init();`, and `MX_USART2_UART_Init();`, call `HAL_UARTEx_ReceiveToIdle_DMA(&huart2, receiveBuf50, sizeof(receiveBuf50));`
- Implement `HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)` in user code, not the legacy `HAL_UART_RxCpltCallback()`
- In that callback, when `huart->Instance == USART2`, terminate the buffer safely, process the received command, then immediately re-arm `HAL_UARTEx_ReceiveToIdle_DMA(&huart2, receiveBuf50, sizeof(receiveBuf50));`
- Ensure the generated project includes all symbols used by this flow:
- `UART_HandleTypeDef huart2`
- `DMA_HandleTypeDef hdma_usart2_rx`
- `DMA_HandleTypeDef hdma_usart2_tx`
- a receive buffer such as `uint8_t receiveBuf50[50]`
## VS Code integration (mirror reference patterns)
Create `.vscode/` with:
- `settings.json`:
- `"cmake.configurePreset": "Debug"`
- `"cmake.buildPreset": "Debug"`
- `"STM32VSCodeExtension.cubeCLT.path": "C:/ST/STM32CubeCLT_1.19.0"` (or user path)
- `c_cpp_properties.json`: `configurationProvider` = `ms-vscode.cmake-tools`
- `tasks.json`: include
- A fixed `CMake: configure` task that runs `cmake --preset Debug`
- A fixed default build task that runs `cmake --build --preset Debug`
- A fixed clean rebuild task that runs `cmake --build --preset Debug --clean-first`
- Mark the fixed build task as the default build group so VS Code `Ctrl+Shift+B` works immediately
- Flash task: `STM32_Programmer_CLI --connect port=swd --download ${workspaceFolder}/build/Debug/<proj>.elf -hardRst -rst --start`
- Aggregate "Build + Flash" task depending on rebuild + flash
- Avoid depending on `${command:cmake.activeBuildPresetName}`, `${command:cmake.activeConfigurePresetName}`, or `${command:cmake.launchTargetPath}` for the default build path, because `Ctrl+Shift+B` may fail before CMake Tools initializes those values
- `launch.json`: Cortex-Debug launch + attach configs:
- `servertype: stlink`, `device: STM32F407ZGTx`, `interface: swd`
- `executable: ${workspaceFolder}/build/Debug/<proj>.elf`
- `svdFile: ${config:STM32VSCodeExtension.cubeCLT.path}/STMicroelectronics_CMSIS_SVD/STM32F407.svd`
- `serverpath`/`stlinkPath`: `${config:STM32VSCodeExtension.cubeCLT.path}/STLink-gdb-server/bin/ST-LINK_gdbserver`
- `armToolchainPath`: `${config:STM32VSCodeExtension.cubeCLT.path}/GNU-tools-for-STM32/bin`
- `gdbPath`: `${config:STM32VSCodeExtension.cubeCLT.path}/GNU-tools-for-STM32/bin/arm-none-eabi-gdb`
- `preLaunchTask`: `CMake: clean rebuild` (for launch config)
## CMake scaffolding (root)
- `CMakeLists.txt`: include toolchain `cmake/gcc-arm-none-eabi.cmake`, set `CMAKE_C_STANDARD 11`, enable C & ASM, create executable `${CMAKE_PROJECT_NAME}`, `add_subdirectory(cmake/stm32cubemx)`, add user sources, link `stm32cubemx`.
- `CMakePresets.json`: generator Ninja, binary dir `build/${presetName}`, presets Debug/RelWithDebInfo/Release/MinSizeRel inheriting default.
- `cmake/gcc-arm-none-eabi.cmake`: set `TOOLCHAIN_PREFIX=arm-none-eabi-`, compilers, target flags `-mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard`, link script `STM32F407ZGTx_FLASH.ld`, typical link flags with gc-sections and map file.
- `cmake/stm32cubemx/CMakeLists.txt`: interface lib with `USE_HAL_DRIVER`, `STM32F407xx`, includes for `Core/Inc` and `Drivers`, and CubeMX-generated sources for the minimal setup (at minimum `main.c`, `gpio.c`, `dma.c`, `usart.c`, `stm32f4xx_it.c`, `stm32f4xx_hal_msp.c`, `system_stm32f4xx.c`, `startup_stm32f407xx.s`, and required HAL driver files). Keep it aligned with CubeMX output; regenerate if peripherals differ.
## Execution steps
1) Verify CubeMX binary exists; if missing, stop.
2) Detect and record the installed CubeMX version before doing any `.ioc` work. Use that exact version when validating compatibility and when writing `MxCube.Version` / related metadata.
- Hard stop unless the detected version is exactly `6.11.1`.
3) Do not handcraft a full STM32 project when CubeMX generation is available locally. Generate with the installed CubeMX first, then patch only the required user sections and build files.
4) Do not inspect or copy from any other project on disk. This skill must work independently from CubeMX metadata, generated output, and the instructions in this file only.
5) Ask user for project name and target directory.
6) Create project folder and open CubeMX:
- Set MCU to STM32F407ZGTx (LQFP144).
- Configure RCC: HSE 25 MHz on `PH0/PH1`, `PLLM=25`, `PLLN=168`, `PLLP=2`, `PLLQ=4`, `SYSCLK` from PLL.
- Enable required peripherals for the default template: SYS, RCC, NVIC, GPIO, DMA, USART2.
- Configure only these GPIO entries by default: `PH0`, `PH1`, `PA13`, `PA14`, `PD5`, `PD6`.
- Configure `USART2` as asynchronous on `PD5/PD6`.
- Configure DMA requests exactly as specified here: `USART2_RX -> DMA1_Stream5`, `USART2_TX -> DMA1_Stream6`.
- Set `NVIC_PRIORITYGROUP_4`, keep `SysTick_IRQn` at priority `15`, and enable both DMA stream IRQs.
- Project Manager -> Toolchain/IDE: CMake; set project name and path.
- Code Generator: Generate peripheral initialization as "HAL", keep user sections.
- Generate code.
7) Validate the generated output before patching:
- Confirm `main.c` exists and `SystemClock_Config()` uses `HSE`, `PLL_ON`, `PLLM=25`, `PLLN=168`, `PLLP=RCC_PLLP_DIV2`, `PLLQ=4`, `SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK`, `AHB = DIV1`, `APB1 = DIV2`, `APB2 = DIV1`.
- Confirm the generated project includes `USART2`, `DMA1_Stream5`, `DMA1_Stream6`, and `USART2_IRQn`.
- Confirm the generated `.ioc` does not report required-field incompatibilities for RCC, DMA, SYS, GPIO, or USART2.
- Confirm `.ioc` loads without `Not a valid ioc file`.
- Confirm `.ioc` does not contain hand-written `USART2.WordLength`, `USART2.Parity`, `USART2.StopBits` lines and `USART2.IPParameters` remains `VirtualMode,BaudRate,Mode,OverSampling` before generation.
- If CubeMX output falls back to `HSI`, `PLL_NONE`, missing DMA streams, or missing USART2 init, treat generation as failed and fix generation inputs before patching.
8) Patch the generated sources to preserve the required `USART2` runtime behavior:
- In `Core/Src/usart.c`, add `__io_putchar()` in user code and keep it bound to `HAL_UART_Transmit(&huart2, ...)`.
- In `Core/Src/syscalls.c`, leave `__io_putchar()` as a weak external declaration only.
- In `Core/Src/main.c`, declare a receive buffer, call `HAL_UARTEx_ReceiveToIdle_DMA(&huart2, receiveBuf50, sizeof(receiveBuf50));` during initialization, and implement `HAL_UARTEx_RxEventCallback()` to process and re-arm reception.
- In `Core/Src/stm32f4xx_it.c`, keep both DMA IRQ handlers for `USART2`.
- This step is the only allowed direct source-code modification step.
9) Normalize the generated layout to the required root structure if CubeMX emits a different but equivalent layout:
- Required end state is root `Core/Inc`, `Core/Src`, `Drivers`, `cmake`, `.vscode`, linker script, startup file, and root `.ioc`.
- If CubeMX emits `Inc/` and `Src/` at the root, move them to `Core/Inc` and `Core/Src` before patching build files.
10) Add/adjust the CMake scaffolding files (root CMakeLists, presets, toolchain, stm32cubemx CMakeLists) to match the templates above if CubeMX did not emit them.
11) Add `.vscode` files as above; set `executable` paths to the chosen project name.
12) Validate VS Code build behavior:
- Confirm the default VS Code build task maps to `cmake --build --preset Debug`.
- Confirm build tasks do not rely on unresolved CMake Tools command substitutions for the default build path.
- If needed, prefer fixed `Debug` preset names and fixed `${workspaceFolder}/build/Debug/<proj>.elf` paths over dynamic commands.
13) Before finishing, re-check the generated `.ioc` header and confirm its CubeMX version metadata still matches the local installation. Fix it if it drifted.
- For this skill, it must be exactly `MxCube.Version=6.11.1`.
14) Enforce no-manual-edit rule:
- Except for `USART2 runtime behavior` source edits in step 8, do not directly modify generated source code to fix config mismatches.
- All non-runtime configuration fixes must be made in `.ioc`, then regenerated from CubeMX.
15) Run `cmake --preset Debug` then `cmake --build --preset Debug` to verify build; ensure `${workspaceFolder}/build/Debug/<proj>.elf` exists.
16) Verify VS Code `Ctrl+Shift+B` can invoke the generated default build task without manual preset reselection.
17) For flashing, run VS Code task "Build + Flash" or `STM32_Programmer_CLI --connect port=swd --download build/Debug/<proj>.elf -hardRst -rst --start`.
18) For debugging, launch "Build & Debug Microcontroller - ST-Link" in VS Code (Cortex-Debug).
## Notes & guardrails
- Prefer using commands listed in `Reference commands` whenever possible. If a listed command cannot be used, use an equivalent command and briefly state why.
- Keep `SKILL.md` concise; move verbose reference to separate files if added.
- If user chooses another MCU, re-derive clocks accordingly instead of using the above constants.
- Version policy for this skill is strict: only `6.11.1` is allowed. Any other detected version is a hard error.
- Do not continue from an invalid CubeMX load that logs missing required RCC, DMA, SYS, GPIO, or USART fields. Fix the `.ioc` / generation inputs first.
- For `USART2`, avoid hardcoding enum text values in `.ioc` for `WordLength/Parity/StopBits`; rely on CubeMX defaults and generated init checks instead.
- Do not finish if IOC cannot be opened cleanly by CubeMX.
- Do not continue patching if generated `main.c` shows `HSI` or `PLL_NONE` instead of the required `HSE + PLL` clock tree.
- This skill must remain independent. Do not read another STM32 project to discover valid `.ioc` keys, clock parameters, or file layouts.
- Prefer deterministic VS Code tasks. Do not assume VS Code `Ctrl+Shift+B` will work if the tasks depend on unresolved extension-provided command variables.
- Do not refer to the VS Code build shortcut as `Ctrl+B`; in standard VS Code usage the build shortcut is `Ctrl+Shift+B`.
- For the default build path, prefer fixed `Debug` preset tasks over dynamic `${command:...}` substitutions unless those substitutions are explicitly verified in the current workspace.
- Unless the user asks for more peripherals, remove any auto-enabled middleware or peripheral blocks beyond DMA, GPIO, NVIC, RCC, SYS, and USART2 from both the CubeMX configuration and generated build files.
- When stripping peripherals from a copied `.ioc`, also remove their dependent pins, DMA requests, NVIC entries, generated source files, and middleware references so the result stays internally consistent.
- For GPIO specifically, keep only these default pins: `PH0`, `PH1`, `PA13`, `PA14`, `PD5`, `PD6`.
- Do not replace the required `HAL_UARTEx_ReceiveToIdle_DMA()` + `HAL_UARTEx_RxEventCallback()` flow with polling, interrupt-only receive, or `HAL_UART_Receive_DMA()`.
- Do not move `__io_putchar()` into `syscalls.c`; keep the actual implementation in `usart.c` so `printf` stays coupled to `USART2`.
- Except for the explicit `USART2 runtime behavior` edits, do not directly edit generated C sources for configuration purposes; enforce configuration via IOC + regenerate.
## Reference commands
Use these commands as operational references for this skill. Adapt `<proj>` / paths as needed.
1) Check CubeMX binary and version
```powershell
$mx='C:/Program Files/STMicroelectronics/STM32Cube/STM32CubeMX/STM32CubeMX.exe'
Test-Path $mx
(Get-Item $mx).VersionInfo
```
2) Set CubeMX CLI runtime (required by later commands)
```powershell
$java='C:/Program Files/STMicroelectronics/STM32Cube/STM32CubeMX/jre/bin/java.exe'
$jar='C:/Program Files/STMicroelectronics/STM32Cube/STM32CubeMX/STM32CubeMX.exe'
```
3) Probe CLI command capabilities (optional, useful when syntax differs by install)
```powershell
@'
help
project
config
set
get
generate
exit
'@ | Set-Content -Encoding ascii .mx_probe_cmd.txt
& $java -jar $jar -q .mx_probe_cmd.txt
```
4) Create a brand new project + IOC (empty workspace case)
```powershell
@'
load STM32F407ZGTx
project name <proj>
project toolchain CMake
generate code .
config saveas <proj>.ioc
exit
'@ | Set-Content -Encoding ascii .mx_create_cmd.txt
& $java -jar $jar -q .mx_create_cmd.txt
```
5) Configure existing IOC then regenerate code (already-created IOC case)
```powershell
@'
config load <proj>.ioc
generate code .
exit
'@ | Set-Content -Encoding ascii .mx_cmd.txt
& $java -jar $jar -q .mx_cmd.txt
```
6) Apply minimum required pin/peripheral modes before regeneration
```powershell
@'
config load <proj>.ioc
set mode RCC HSE-External-Oscillator
set mode SYS Serial_Wire
set mode USART2 Asynchronous
set pin PH0 RCC_OSC_IN
set pin PH1 RCC_OSC_OUT
set pin PA13 SYS_JTMS-SWDIO
set pin PA14 SYS_JTCK-SWCLK
set pin PD5 USART2_TX
set pin PD6 USART2_RX
config save
generate code .
exit
'@ | Set-Content -Encoding ascii .mx_set_basic_cmd.txt
& $java -jar $jar -q .mx_set_basic_cmd.txt
```
7) Apply RCC clock parameters required by this skill, then regenerate
```powershell
@'
config load <proj>.ioc
set ip parameters RCC OscillatorType RCC_OSCILLATORTYPE_HSE
set ip parameters RCC OscillatorTypeHSE RCC_OSCILLATORTYPE_HSE
set ip parameters RCC HSEState RCC_HSE_ON
set ip parameters RCC HSEStateARG RCC_HSE_ON
set ip parameters RCC HSEUsed 1
set ip parameters RCC PLLState RCC_PLL_ON
set ip parameters RCC PLLStateARG RCC_PLL_ON
set ip parameters RCC PLLUsed 1
set ip parameters RCC PLLUsedForSys 1
set ip parameters RCC PLLSource RCC_PLLSOURCE_HSE
set ip parameters RCC PLLSourceARG RCC_PLLSOURCE_HSE
set ip parameters RCC PLLSourceVirtual RCC_PLLSOURCE_HSE
set ip parameters RCC PLLM 25
set ip parameters RCC PLLN 168
set ip parameters RCC PLLP PLLP_DIV2
set ip parameters RCC PLLQ 4
set ip parameters RCC SYSCLKSource RCC_SYSCLKSOURCE_PLLCLK
set ip parameters RCC SYSCLKSourceARG RCC_SYSCLKSOURCE_PLLCLK
set ip parameters RCC AHBCLKDivider RCC_SYSCLK_DIV1
set ip parameters RCC AHBCLKDividerARG RCC_SYSCLK_DIV1
set ip parameters RCC APB1CLKDivider RCC_HCLK_DIV2
set ip parameters RCC APB1CLKDividerARG RCC_HCLK_DIV2
set ip parameters RCC APB2CLKDivider RCC_HCLK_DIV1
set ip parameters RCC APB2CLKDividerARG RCC_HCLK_DIV1
set ip parameters RCC FLatency FLASH_LATENCY_2
set ip parameters RCC HCLKFreq_Value 84000000
set ip parameters RCC AHBFreq_Value 84000000
set ip parameters RCC APB1Freq_Value 42000000
set ip parameters RCC APB2Freq_Value 84000000
set ip parameters RCC APB1TimFreq_Value 84000000
set ip parameters RCC APB2TimFreq_Value 84000000
set ip parameters RCC SYSCLKFreq_VALUE 84000000
set ip parameters RCC CortexFreq_Value 84000000
set ip parameters RCC FCLKCortexFreq_Value 84000000
set ip parameters RCC PLLCLKFreq_Value 84000000
set ip parameters RCC PLLQCLKFreq_Value 42000000
set ip parameters RCC VCOInputFreq_Value 1000000
set ip parameters RCC VCOOutputFreq_Value 168000000
set ip parameters RCC HSE_VALUE 25000000
set ip parameters RCC LSI_VALUE 32000
set ip parameters USART2 VirtualMode VM_ASYNC
set ip parameters USART2 BaudRate 115200
set ip parameters USART2 Mode MODE_TX_RX
set ip parameters USART2 OverSampling UART_OVERSAMPLING_16
config save
generate code .
exit
'@ | Set-Content -Encoding ascii .mx_clock_uart_cmd.txt
& $java -jar $jar -q .mx_clock_uart_cmd.txt
```
7b) Apply DMA baseline using IOC `Dma.*` keys (CubeMX CLI does not accept `USART2_RxDMA/USART2_TxDMA` as valid `set ip parameters`)
```powershell
$ioc='<proj>.ioc'
$lines=Get-Content $ioc
# Remove invalid/legacy USART2 DMA keys and existing Dma section before rewriting
$lines=$lines | Where-Object {
$_ -notmatch '^USART2\.USART2_RxDMA=' -and
$_ -notmatch '^USART2\.USART2_TxDMA=' -and
$_ -notmatch '^Dma\.'
}
# Keep USART2 IP parameters minimal per skill gate
$lines=$lines | ForEach-Object {
if($_ -match '^USART2\.IPParameters='){ 'USART2.IPParameters=VirtualMode,BaudRate,Mode,OverSampling' }
elseif($_ -match '^USART2\.BaudRate='){ 'USART2.BaudRate=115200' }
elseif($_ -match '^USART2\.Mode='){ 'USART2.Mode=MODE_TX_RX' }
elseif($_ -match '^USART2\.OverSampling='){ 'USART2.OverSampling=UART_OVERSAMPLING_16' }
elseif($_ -match '^USART2\.VirtualMode='){ 'USART2.VirtualMode=VM_ASYNC' }
else { $_ }
}
# Ensure required USART2 fields exist
if(-not ($lines -match '^USART2\.BaudRate=')){ $lines += 'USART2.BaudRate=115200' }
if(-not ($lines -match '^USART2\.IPParameters=')){ $lines += 'USART2.IPParameters=VirtualMode,BaudRate,Mode,OverSampling' }
if(-not ($lines -match '^USART2\.Mode=')){ $lines += 'USART2.Mode=MODE_TX_RX' }
if(-not ($lines -match '^USART2\.OverSampling=')){ $lines += 'USART2.OverSampling=UART_OVERSAMPLING_16' }
if(-not ($lines -match '^USART2\.VirtualMode=')){ $lines += 'USART2.VirtualMode=VM_ASYNC' }
# DMA request block for USART2 RX/TX
$dma=@(
'Dma.Request0=USART2_RX',
'Dma.Request1=USART2_TX',
'Dma.RequestsNb=2',
'Dma.USART2_RX.0.Direction=DMA_PERIPH_TO_MEMORY',
'Dma.USART2_RX.0.FIFOMode=DMA_FIFOMODE_DISABLE',
'Dma.USART2_RX.0.Instance=DMA1_Stream5',
'Dma.USART2_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE',
'Dma.USART2_RX.0.MemInc=DMA_MINC_ENABLE',
'Dma.USART2_RX.0.Mode=DMA_NORMAL',
'Dma.USART2_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE',
'Dma.USART2_RX.0.PeriphInc=DMA_PINC_DISABLE',
'Dma.USART2_RX.0.Priority=DMA_PRIORITY_LOW',
'Dma.USART2_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode',
'Dma.USART2_TX.1.Direction=DMA_MEMORY_TO_PERIPH',
'Dma.USART2_TX.1.FIFOMode=DMA_FIFOMODE_DISABLE',
'Dma.USART2_TX.1.Instance=DMA1_Stream6',
'Dma.USART2_TX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE',
'Dma.USART2_TX.1.MemInc=DMA_MINC_ENABLE',
'Dma.USART2_TX.1.Mode=DMA_NORMAL',
'Dma.USART2_TX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE',
'Dma.USART2_TX.1.PeriphInc=DMA_PINC_DISABLE',
'Dma.USART2_TX.1.Priority=DMA_PRIORITY_LOW',
'Dma.USART2_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode'
)
# Place DMA block near top for readability
$out=@()
$inserted=$false
foreach($l in $lines){
$out+=$l
if(-not $inserted -and $l -eq 'CAD.provider='){
$out+=$dma
$inserted=$true
}
}
if(-not $inserted){ $out=$dma + $lines }
if(-not ($out -match '^NVIC\.DMA1_Stream5_IRQn=')){ $out += 'NVIC.DMA1_Stream5_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true' }
if(-not ($out -match '^NVIC\.DMA1_Stream6_IRQn=')){ $out += 'NVIC.DMA1_Stream6_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true' }
$out | Set-Content -Encoding ascii $ioc
@'
config load <proj>.ioc
generate code .
exit
'@ | Set-Content -Encoding ascii .mx_dma_fix_cmd.txt
& $java -jar $jar -q .mx_dma_fix_cmd.txt
```
8) Validate IOC can be loaded cleanly
```powershell
@'
config load <proj>.ioc
exit
'@ | Set-Content -Encoding ascii .mx_validate_cmd.txt
& $java -jar $jar -q .mx_validate_cmd.txt
```
9) Inspect workspace and key files
```powershell
Get-ChildItem -Recurse -Force
Get-Content -Raw <proj>.ioc
rg -n "<pattern>" .
```
10) Verify generated clock/USART code quickly
```powershell
rg -n "OscillatorType|HSEState|PLLState|PLLM|PLLN|PLLP|PLLQ|SYSCLKSource|APB1CLKDivider|APB2CLKDivider|FLASH_LATENCY" Src/main.c
rg -n "huart2.Init.BaudRate|huart2.Init.Mode|huart2.Init.OverSampling" Src/main.c
```
11) Configure and build with CMake
```powershell
cmake --preset Debug
cmake --build --preset Debug
```
12) VS Code default build task target (Ctrl+Shift+B)
```powershell
cmake --build --preset Debug
```
-16
View File
@@ -1,16 +0,0 @@
{
"version": 4,
"configurations": [
{
/**
* ms-vscode.cmake-tools plugin should be installed.
*
* It provides data for C/C++ plugin,
* such as include paths, browse paths, defines, etc.
*/
"name": "STM32",
"configurationProvider": "ms-vscode.cmake-tools",
"intelliSenseMode": "${default}"
}
]
}
-19
View File
@@ -1,19 +0,0 @@
{
"recommendations": [
"ms-vscode.cpptools", // (dependencies to ms-vscode.cpptools-extension-pack)
"ms-vscode.cpptools-themes", // (dependencies to ms-vscode.cpptools-extension-pack)
"ms-vscode.cmake-tools", // (dependencies to ms-vscode.cpptools-extension-pack)
"twxs.cmake", // (dependencies to ms-vscode.cpptools-extension-pack)
"ms-vscode.cpptools-extension-pack", // Provides CMake and C++ file coloring, completion & support
"dan-c-underwood.arm", // Provides syntax highlighting for the Arm Assembly language
"zixuanwang.linkerscript", // Provides syntax highlighting for linker scripts
"ms-vscode.hexeditor", // Provides hex editor fo viewing & anipulating files in their raw hexadecimal representation
"trond-snekvik.gnu-mapfiles", // Provides syntax highlighting and symbol listing for GNU linker .map files
"jeff-hykin.better-cpp-syntax", // Provides syntax highlighting for C++
"marus25.cortex-debug", // Provides debug support on Arm Cortex-M
"mcu-debug.debug-tracker-vscode", // Dependencies to "marus25.cortex-debug"
"mcu-debug.memory-view", // Dependencies to "marus25.cortex-debug"
"mcu-debug.peripheral-viewer", // Dependencies to "marus25.cortex-debug"
"mcu-debug.rtos-views" // Dependencies to "marus25.cortex-debug"
]
}
-66
View File
@@ -1,66 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Build & Debug Microcontroller - ST-Link",
"cwd": "${workspaceFolder}",
"type": "cortex-debug",
"executable": "${workspaceFolder}/build/Debug/BMSv3.elf",
// Let CMake extension decide executable: "${command:cmake.launchTargetPath}"
// Or fixed file path: "${workspaceFolder}/path/to/filename.elf"
"request": "launch",
"servertype": "stlink",
"device": "STM32F407ZGTx", //MCU used
"interface": "swd",
"serialNumber": "", //Set ST-Link ID if you use multiple at the same time
"runToEntryPoint": "main",
"showDevDebugOutput": "raw",
"svdFile": "${config:STM32VSCodeExtension.cubeCLT.path}/STMicroelectronics_CMSIS_SVD/STM32F407.svd",
"v1": false, //Change it depending on ST Link version
"serverpath": "${config:STM32VSCodeExtension.cubeCLT.path}/STLink-gdb-server/bin/ST-LINK_gdbserver",
"stm32cubeprogrammer":"${config:STM32VSCodeExtension.cubeCLT.path}/STM32CubeProgrammer/bin",
"stlinkPath": "${config:STM32VSCodeExtension.cubeCLT.path}/STLink-gdb-server/bin/ST-LINK_gdbserver",
"armToolchainPath": "${config:STM32VSCodeExtension.cubeCLT.path}/GNU-tools-for-STM32/bin",
"gdbPath":"${config:STM32VSCodeExtension.cubeCLT.path}/GNU-tools-for-STM32/bin/arm-none-eabi-gdb",
"serverArgs": [
"-m","0",
],
"preLaunchTask": "CMake: clean rebuild"
/* If you use external loader, add additional arguments */
//"serverArgs": ["--extload", "path/to/ext/loader.stldr"],
},
{
"name": "Attach to Microcontroller - ST-Link",
"cwd": "${workspaceFolder}",
"type": "cortex-debug",
"executable": "${workspaceFolder}/build/Debug/BMSv3.elf",
// Let CMake extension decide executable: "${command:cmake.launchTargetPath}"
// Or fixed file path: "${workspaceFolder}/path/to/filename.elf"
"request": "attach",
"servertype": "stlink",
"device": "STM32F407ZGTx", //MCU used
"interface": "swd",
"serialNumber": "", //Set ST-Link ID if you use multiple at the same time
"runToEntryPoint": "main",
"showDevDebugOutput": "raw",
"svdFile": "${config:STM32VSCodeExtension.cubeCLT.path}/STMicroelectronics_CMSIS_SVD/STM32F407.svd",
"v1": false, //Change it depending on ST Link version
"serverpath": "${config:STM32VSCodeExtension.cubeCLT.path}/STLink-gdb-server/bin/ST-LINK_gdbserver",
"stm32cubeprogrammer":"${config:STM32VSCodeExtension.cubeCLT.path}/STM32CubeProgrammer/bin",
"stlinkPath": "${config:STM32VSCodeExtension.cubeCLT.path}/STLink-gdb-server/bin/ST-LINK_gdbserver",
"armToolchainPath": "${config:STM32VSCodeExtension.cubeCLT.path}/GNU-tools-for-STM32/bin",
"gdbPath":"${config:STM32VSCodeExtension.cubeCLT.path}/GNU-tools-for-STM32/bin/arm-none-eabi-gdb",
"serverArgs": [
"-m","0",
],
/* If you use external loader, add additional arguments */
//"serverArgs": ["--extload", "path/to/ext/loader.stldr"],
}
]
}
-10
View File
@@ -1,10 +0,0 @@
{
"files.associations": {
"tcp_client.h": "c",
"lwip.h": "c",
"ethernetif.h": "c"
},
"cmake.configurePreset": "Debug",
"cmake.buildPreset": "Debug",
"STM32VSCodeExtension.cubeCLT.path": "C:/ST/STM32CubeCLT_1.19.0"
}
-62
View File
@@ -1,62 +0,0 @@
{
"version": "2.0.0",
"windows": {
"options": {
"shell": {
"executable": "cmd.exe",
"args": ["/d", "/c"]
}
}
},
"tasks": [
{
"type": "shell",
"label": "CubeProg: Flash project (SWD)",
"command": "STM32_Programmer_CLI",
"args": [
"--connect",
"port=swd",
"--download",
"${command:cmake.launchTargetPath}",
// Let CMake extension decide executable: "${command:cmake.launchTargetPath}",
"-hardRst", // Hardware reset - if rst pin is connected
"-rst", // Software reset (backup)
"--start" // Start execution
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": []
},
{
"label": "Build + Flash",
"dependsOrder": "sequence",
"dependsOn": [
"CMake: clean rebuild",
"CubeProg: Flash project (SWD)",
]
},
{
"type": "cmake",
"label": "CMake: clean rebuild",
"command": "cleanRebuild",
"targets": [
"all"
],
"preset": "${command:cmake.activeBuildPresetName}",
"group": "build",
"problemMatcher": [],
"detail": "CMake template clean rebuild task"
},
{
"type": "shell",
"label": "CubeProg: List all available communication interfaces",
"command": "STM32_Programmer_CLI",
"args": ["--list"],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": []
}
]
}
+7 -1
View File
@@ -104,7 +104,13 @@ C:\Users\bowei\.claude\skills\langgraph-plan-review\scripts\manage_dev_server.ps
```powershell ```powershell
C:\Users\bowei\.claude\skills\langgraph-plan-review\scripts\manage_dev_server.ps1 start C:\Users\bowei\.claude\skills\langgraph-plan-review\scripts\manage_dev_server.ps1 start
``` ```
Wait for the "Ready" confirmation before proceeding. Open the Studio URL in a browser for real-time tracking. Wait for the "[dev-server] Ready" line in the output. Then **immediately tell the user** in your text response:
- that the dev server is running, and
- the Studio URL: `https://smith.langchain.com/studio/?baseUrl=http://127.0.0.1:2024`
Example message to user:
> LangGraph dev server 已就绪。可在浏览器中打开 Studio 实时监控工作流:
> https://smith.langchain.com/studio/?baseUrl=http://127.0.0.1:2024
3. Start or resume the LangGraph app: 3. Start or resume the LangGraph app:
```powershell ```powershell
# Use double backslashes (\\) in the JSON string so Windows paths are valid JSON. # Use double backslashes (\\) in the JSON string so Windows paths are valid JSON.
+10 -5
View File
@@ -76,14 +76,17 @@ def resolve_codex() -> str:
exe = os.environ.get("CODEX_EXE", "") exe = os.environ.get("CODEX_EXE", "")
if exe and Path(exe).exists(): if exe and Path(exe).exists():
return exe return exe
# 2. PATH lookup # 2. Known install paths (checked before PATH to avoid picking up wrong codex variant)
for candidate in [
r"C:\Users\bowei\miniconda3\envs\langgraph\codex.cmd",
r"C:\Users\bowei\.conda\envs\langgraph\codex.cmd",
]:
if Path(candidate).exists():
return candidate
# 3. PATH lookup fallback
found = shutil.which("codex") or shutil.which("codex.cmd") found = shutil.which("codex") or shutil.which("codex.cmd")
if found: if found:
return found return found
# 3. Hardcoded fallback for the original developer machine
fallback = r"C:\Users\bowei\.conda\envs\langgraph\codex.cmd"
if Path(fallback).exists():
return fallback
raise FileNotFoundError( raise FileNotFoundError(
"Cannot find codex executable. Set CODEX_EXE environment variable or add codex to PATH." "Cannot find codex executable. Set CODEX_EXE environment variable or add codex to PATH."
) )
@@ -128,6 +131,8 @@ def main() -> int:
command_args, command_args,
capture_output=True, capture_output=True,
text=True, text=True,
encoding="utf-8",
errors="replace",
timeout=timeout, timeout=timeout,
input=prompt, input=prompt,
cwd=work_dir, cwd=work_dir,
+1 -1
View File
@@ -1,6 +1,6 @@
--- ---
name: vivado-prj-create name: vivado-prj-create
description: DIRECT EXECUTION - Auto-create Vivado FPGA projects. Triggers: "create Vivado project", "Vivado工程", "FPGA project", "Xilinx project", "setup Vivado". When triggered, IMMEDIATELY execute Step 0 without listing skills or asking for confirmation. description: 'DIRECT EXECUTION - Auto-create Vivado FPGA projects. Triggers: "create Vivado project", "Vivado工程", "FPGA project", "Xilinx project", "setup Vivado". When triggered, IMMEDIATELY execute Step 0 without listing skills or asking for confirmation.'
--- ---
# Vivado Project TCL Generator # Vivado Project TCL Generator