Files
skills-win/cubemx-min-prj/REPRODUCTION_GUIDE.md
T

168 lines
6.4 KiB
Markdown

# 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.