按重要性排序。前 4 个错了直接烧不通,后 6 个错了表现”看起来编译通过,跑起来不对”。
1. 选对 board 模板 — flash 大小必须对
| 芯片型号 | 倒数第3字母 | 倒数第4字母 | 含义 | board | logic_device |
|---|---|---|---|---|---|
| AG32VF303VCT6 | C | V | 256KB / LQFP-100 | agrv2k_303 | AGRV2KL100 |
| AG32VF407RGT6 | G | R | 1MB / LQFP-64 | agrv2k_407 | AGRV2KL64 |
| AG32VF103RCT6 | C | R | 256KB / LQFP-64 | agrv2k_103 或 agrv2k_303 | AGRV2KL64 |
| AG32VH303RCT6 | C | R | 256KB / LQFP-64 | agrv2k_303 | AGRV2KL64 |
| AG32VH407RGT6 | G | R | 1MB / LQFP-64 | agrv2k_407 | AGRV2KL64 |
AG32 flash 只有 256KB 和 1MB 两档。
规则:倒数第3字母 C → 256KB,G → 1MB;1MB 选 agrv2k_407,256KB 选 agrv2k_103/303。
错误表现:Device ID does not match, expected 0x40200001:1024KB but got 0x40200001:256KB
2. VE 文件的来源 — 所有工程都需要
VE 决定了 MCU 内部信号线(像 GPIO4_2、UART1_UARTTXD)绑到哪个物理引脚。 没 VE,代码里 GPIO_AF_ENABLE(GPIO_AF_PIN(UART, 1, UARTTXD)) 不会路由到你想要的 pin,SDK 会用内部默认(可能不匹配你的板子)。
VE 查找顺序(优先级从高到低):
1. platformio.ini 里 logic_ve = my_board.ve 显式指定 ← 非 logic 工程也建议写
2. SDK 的 boards/<你选的 board>/board.ve 默认
3. 没有 → chip 用内部默认(强烈不推荐,可能不匹配你的板子)
boards 模板目录在哪:E:\project\AGM\AGM_MCU\AgRV_pio\platforms\AgRV\boards\
里面有 4 个 board:agrv2k_103 / agrv2k_303 / agrv2k_407 / agrv2k_test。
每个 board 子目录里有 4 个文件:
– board.asf — Quartus 设计级设置(上拉下拉等)
– board.c — SDK 板级初始化(clock / UART / GPIO)
– board.h — SDK 板级头文件(LED/BUTTON/GPIO 定义)
– board.ve — 引脚映射(默认 VE)
重要: 即使是”纯 MCU、没自定义 logic”的工程,只要你的板子引脚跟 SDK 默认不一样(比如 UART1 默认在 PIN_66/67,但你硬件接到 PIN_51/52),必须配 logic_ve = my_board.ve + logic_device = AGRV2KL100,然后跑一次 pio run -t buildlogic(VE-only 路径,Supra 编译出 0 logic slices),让 gen_vlog 重新生成 board.vx / board.hx / board.vex 包含你的引脚映射。否则 SDK 跑在错误的引脚上,代码看起来编译过但实际不工作。
要换引脚绑定时: 复制 boards/<board>/board.ve 到工程根目录,改里面的 XXX PIN_n 行,然后在 platformio.ini 显式 logic_ve = my_board.ve,跑 pio run -t buildlogic 让它生效。
注意: PIO 平台识别的是 logic.ve / logic_ve(短横线或下划线,通用选项),不识别 board_logic.ve(那是无效的)。
3. SYSCLK 必须跟 SDK 默认 BOARD_PLL_FREQUENCY 一致
SDK 默认 BOARD_PLL_FREQUENCY = 100000000(100MHz),在 framework-agrv_sdk/src/system.h:25-27 定义。
- VE 写
SYSCLK 100→ PLL 锁 100MHz,SYS_Clocks.PLL_FREQUENCYlink init = 100MHz,UART baud 算对 - VE 写
SYSCLK 200但没传-DBOARD_PLL_FREQUENCY=200000000→SYS_Clocks.PLL_FREQUENCY变量 = 100MHz,IBRD 按 100MHz 算,实际 PCLK 200MHz,实际 baud 232K = 期望 2 倍 → COM5 看到乱码 - 想用 200MHz:VE 写 200 + build 加
-DBOARD_PLL_FREQUENCY=200000000
简单工程保持 SYSCLK 100 最省事。
4. 不用 CPLD logic 时,platformio.ini 简化要点
不用 logic 的工程(纯 MCU),但如果引脚不匹配 SDK 默认,仍需配 logic_ve(见 §2)。简化要点:
[setup]
board = agrv2k_303
framework = agrv_sdk
program = my_app
build_src_filter = "-<*> +<./src/**/*.c>"
[setup_logic]
; 必须配 (即使不用 logic, 引脚不匹配 SDK 默认就要写): logic_ve = my_board.ve ; 你的 VE 文件 (引脚不匹配时) logic_device = AGRV2KL100 ; chip 型号 ; 不写 ip_name / logic_dir ; 不走 prelogic 路径 (没 user_ip)
[setup_upload]
protocol = cmsis-dap-openocd debug_tool = ${this.protocol} upload_protocol = ${this.protocol} check_logic = 0 ; 关键!没 logic 时必须加,否则烧录前 check_logic 失败
[setup_monitor]
logger_if = UART0 monitor_port = COM5 ; AGM DAP-LINK 桥接的 COM 口 monitor_speed = 115200
[setup_batch]
关键差别 (vs 有 logic 的工程):
– ❌ 不设 ip_name (无 user_ip)
– ❌ 不设 logic_dir (Supra 不会跑 P&R/bitgen,只走 VE-only 路径)
– ✅ 仍可设 logic_ve (引脚路由必须)
– ✅ 仍可设 logic_device (chip 型号)
– ✅ 仍可设 design.asf (上拉/下拉)
– ✅ check_logic = 0 (没 logic 时跳过)
烧录命令 (没 logic,只烧 code):
pio run -t upload # 只烧 MCU code 到 0x80000000
如果引脚改了(VE 改了),还要先 pio run -t buildlogic 让 Quartus 重新综合生成 board.vx/board.hx,再 pio run -t logic(烧 CPLD bitstream 含引脚路由)+ pio run -t upload(烧 code)。
5. boot ROM 启用了 IWDG(~0.25s 超时)
main() 第一行必须 disable:
int main(void) {
volatile uint16_t *iwdg = (volatile uint16_t *)(0x40000000 + 0x34);
*iwdg = 0x0000; // 直接寄存器清
IWDG_Disable(); // SDK API 备份
board_init();
// ... 你的代码
}
否则 main loop 跑超过 0.25s 板子被 IWDG 复位,COM5 看到固定 pattern 重复。
6. 烧完 code 后板子处于 halt 状态,需要 reset 才能跑
pio run -t upload 最后是 reset halt,CPU 在 halt 不会跑 main。
必须主动 reset + resume(用 openocd 命令脚本):
source [find agrv2k.cfg]
reset
sleep 200
resume
sleep 200
shutdown
或者烧完按一下板子 RST 按钮。
7. 引脚上下拉在 board.asf 里设
VE 文件只声明信号↔引脚路由,引脚的上下拉/驱动电流/OD 模式在 .asf 里:
# example_board.asf
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to PIN_16
set_instance_assignment -name WEAK_PULL_DOWN_RESISTOR ON -to PIN_26
set_instance_assignment -name CURRENT_STRENGTH -to PIN_32 16MA
pio run -t logic 烧 logic 时,这些 as 设置一起烧进去。
8. 串口监听用 DAP-LINK 桥接的 COM5
monitor_port = COM5(USB VID:PID=CAFE:1001那条)- 115200 8N1
- openocd 烧录后退出,DAP-LINK 桥接要等几秒才恢复
- COM4/COM6 通常是蓝牙,不是 AG32
9. 引脚别重复占用
VE 里同一个物理引脚只能绑一个信号线,同一个信号线也只能绑一个引脚。SPI0_SI_IO0 和 GPIO0_0 是同一个硬件,不能分别绑 PIN_2 和 PIN_16。
gen_vlog 会报:SPI0_SI_IO0/GPIO0_0 is assigned to both PIN_16 and PIN_2!
如果某个 GPIOx_y 被官方 VE 占用了,改用其他 bit(如 GPIO0_0 被占,改 GPIO0_1)。
10. 复用 SPI_AD 等已验证工程做新工程
最稳的做法:
1. 复制整个工程目录(SPI_AD 验证过 UART/logic/clock 全 OK)
2. 改 platformio.ini 的 board / program / logic_ve
3. 改 board.ve 的引脚路由
4. 改 main.c 的功能
5. 删 logic 目录(不用 logic 时)
6. 保留 SPI_AD main() 头的 IWDG_Disable,直接抄
速记表:0x80000000 flash 布局
| 区段 | 256KB 起始 | 1MB 起始 | 大小 |
|---|---|---|---|
| MCU code | 0x80000000 | 0x80000000 | 0 ~ 156KB(256K) / 0x870000(1M) |
| Logic (压缩) | 0x80034000 | 0x800F4000 | 48KB |
| Logic (非压缩) | 0x80027000 | 0x800E7000 | 100KB |
| Option bytes | 0x81000000 | 0x81000000 | 128B |
核心公式:logic 起始 = 0x80000000 + flash_size - logic_size
– 256K = 0x40000
– 1M = 0x100000
– 48K = 0xC000
– 100K = 0x19000
.