关于HA0 MCAL,掉电后跑不起来,可以查看这个:https://forum.ytmicro.com/topic/2320/ha01-smcal3_0_0-demo-烧录后掉电再上电代码无法运行问题
环境:
YTM32B1ME15;
Yuntu MCAL 0.8.0;
EEPROM 单比特 ECC 错误可由硬件纠正;双比特错误不可纠正,实测读取时会触发精确 BusFault,且先于 EEPROM 中断处理。仅在 EEPROM_IRQHandler 中处理,会因故障指令反复执行而升级为 HardFault。
MCAL 0.8.0 的 Eep 驱动提供 ECC 中断使能接口,但未实现完整的错误处理和日志记录。
2、处理方案示例在应用层实现:
单比特:在 EEPROM 中断中记录错误地址、计数等信息并清除标志,数据由硬件纠正。 双比特:通过 RAM 向量表接管 BusFault,识别 EEPROM 不可纠正错误,按 Thumb-2 指令长度跳过故障读取指令,记录错误,并将错误地址按 4 字节对齐后擦除对应字。 前提:启动代码已将向量表复制到 RAM;示例在初始化时安装 BusFault 处理函数。 3、验证结果实板测试中,正常读写、单比特纠错、双比特检测及后续重写恢复四步均通过:Eep_EccStepResult=0x01010101,Eep_EccTestFailCnt=0。双比特错误地址为 0x02000040,程序未再出现 BusFault 升级为 HardFault。
99d327fa-a27f-4ed0-9f2c-f750d5bfa25b-image.png
c455d210-b380-4896-a820-67683f11b28c-image.png
main.c 初始化 MCU 时钟,随后 Board_Init 调用 Platform_Init、Fls_Init、Eep_Init 和 Eep_EccDemoInit。启动代码须先将向量表复制到 RAM 并设置 VTOR。
IVT_RAM_start[5U] = (uint32)Eep_BusFault_Handler; __DSB(); __ISB(); SCB->SHCSR |= SCB_SHCSR_BUSFAULTENA_Msk; SCB->CCR |= SCB_CCR_BFHFNMIGN_Msk; EEPROM->STS = EEPROM_STS_UNRECOVERR_MASK | EEPROM_STS_RECOVERR_MASK | EEPROM_STS_CMD_FAIL_MASK | EEPROM_STS_ACCERR_MASK; EEPROM->CTRL |= EEPROM_CTRL_RECOVERRIE_MASK | EEPROM_CTRL_UNRECOVERRIE_MASK; (void)Platform_SetIrq(EEPROM_IRQn, TRUE); 6.2 注入与读取源码使用偏移 0x40、长度 8 字节,先写入测试数据。单比特模式为 1,双比特模式为 2,模式 0 关闭注入;Eep_EccReadJob 通过 Eep_MainFunction 等待作业完成。
EEPROM->ERR_INJECT_CTRL = EEPROM_ERR_INJECT_CTRL_ECCERR_INJ_EN(Mode) | EEPROM_ERR_INJECT_CTRL_ECCERR_INJ_ADDR(Offset); Eep_EccInject(EEP_ECC_INJ_MULTI_BIT, EEP_ECC_TEST_ADDR); Eep_EccJobResultAfterMulti = (uint32)Eep_EccReadJob( EEP_ECC_TEST_ADDR, ReadBuffer, EEP_ECC_TEST_LEN); Eep_EccInject(EEP_ECC_INJ_DISABLE, 0U); Eep_EccPollMultiBit();上述寄存器赋值为非零模式分支摘录。注入仅供测试,示例会写入并擦除 EEPROM 测试区域。
6.3 BusFault 处理应用的 naked 异常入口根据 EXC_RETURN 位 2 选择 MSP 或 PSP,将堆栈指针传给 Eep_BusFaultHandlerC。当前实现使用 pStack[6] 作为保存的 PC,下面为对应 C 代码摘录。
FaultPc = pStack[6]; if (0U != (EEPROM->STS & EEPROM_STS_UNRECOVERR_MASK)) { if (0x1DU <= (*(volatile uint16 *)(FaultPc) >> 11U)) InsnLen = 4U; else InsnLen = 2U; pStack[6] = FaultPc + InsnLen; Eep_EccHandleBusFault(); } else if (TRUE == Fls_Lld_GetTwoBitEccErrFlag()) { pStack[6] = FaultPc + 2U; } SCB->CFSR = SCB_CFSR_BUSFAULTSR_Msk | SCB_CFSR_PRECISERR_Msk;重要限制:跳过加载指令不会生成有效读取值,也不保证 Eep 作业失败。
6,4 错误记录与对齐擦除Eep_EccHandleBusFault 读取错误地址与计数,更新日志,关闭注入并清状态后调用 Eep_EccEraseWord。以下摘录省略地址范围校验及状态清理。
ErrAddr = EEPROM->ECCERR_ADDR; Eep_EccLog.MultiBitErrCnt++; Eep_EccLog.LastErrAddr = ErrAddr; Eep_EccLog.LastErrCnt = EEPROM->ECCERR_CNT & EEPROM_ECCERR_CNT_ECCERR_CNT_MASK; Eep_EccLog.LastErrType = EEP_ECC_ERR_TYPE_MULTI; Eep_EccLog.NotifyCnt++; EEPROM->ERR_INJECT_CTRL = 0U; EEPROM->STS = EEPROM_STS_UNRECOVERR_MASK; Eep_EccEraseWord(ErrAddr); WordAddr = HwAddr & (uint32)(~0x3U); WordPtr = (volatile uint32 *)WordAddr; EEPROM->CTRL |= EEPROM_CTRL_WE_MASK; /* 源码在写入前后执行 ISB 和 DSB */ *WordPtr = 0x00000000U; EEPROM->CTRL &= (uint32)(~EEPROM_CTRL_WE_MASK); EEPROM->CMD_UNLOCK = EEP_ECC_CMD_UNLOCK_KEY; EEPROM->CMD = EEP_ECC_ERASE_SECTOR_CMD; /* 轮询 DONE 或等待超时,然后清状态 */擦除会破坏整个对齐字的数据。当前代码未向上层报告擦除超时或命令失败,且在异常上下文直接操作 EEPROM,可能与正在进行的 Eep 作业竞争;产品化前须核对芯片手册并验证失败处理和数据恢复,不能仅凭日志认定擦除成功。
6.5 EEPROM ECC 中断EEPROM_IRQHandler 根据 STS 处理:单比特分支记录 RECOVERR 并清标志;双比特分支临时关闭 UNRECOVERRIE,记录并调用 Eep_EccEraseWord,最后清状态并重开。双比特读取可能先进入 BusFault。
6b63415c-6681-4394-8366-8aae3e5fef6d-ME15_ECC_EccErrorHandling_Demo.zip
软件版本:HA0 MCAL 2_3_0
硬件:YTM32B1HA01 EVB
I2C master I2C_STANDARD_MODE模式通信,如果主机未收到应答信号,SCL会持续保持低电平状态,直到下次开始通信。
问题原因在从机返回NACK时,驱动中会调用I2C_Lld_MasterEndTransfer复位TX和RX FIFO,若通信速率较低,那么可能会出现硬件还没完成收尾动作软件便清FIFO结束传输的情况。
解决方案I2C_Lld_MasterNACKDetEventHdl函数中在调用I2C_Lld_MasterEndTransfer清除FIFO之前预留超时时间,如下图:
7b336797-86f8-4894-bb2d-2923a6e5b7f1-image.png
[CddI2c_Master_Slave_Demo_YTM32B1HA0.7z](无效文件格式,允许的格式有:.png, .jpg, .bmp, .txt, .webp, .webm, .mp4, .gif, .hex, .bin, .s19, .elf, .zip, .patch, .pdf, .yct, .jpeg) CddI2c_Master_Slave_Demo_YTM32B1HA0 (2).zip
3.0.0 版本 mcal 的 core_cm33.h 文件中 __ghs__ 下的 __FPU_USED 和 __DSP_USED 没有考虑编译器选项,如下图
eadbc127-e4ca-44ea-8445-3038349ddfab-image.png
2.3.0 版本有做相关保护,如下图
1eaac383-21a8-49da-bfcf-5a8db7a4449e-image.png
影响:
编译器产生如下报错
6a5a0b49-775b-461d-8a5e-307a7d0e157b-image.png
影响点如下图,ytm_ccarm.h 中 __FPU_USED = 1 时使用的 __VMSR 函数和 __VFP_FPSCR 符号在编译器使用 -fnone 参数时不存在
13f2dc13-e468-4374-a8e5-fc2dff40b5a9-image.png
我尝试为 openocd 添加 pflash 写入功能,根据手册和 demo 的描述,pflash 单次写入要 32 字节,目前每32字节都要根据这个流程处理一遍,使用 jlink 测试下载的速度大概在 1KB/s,
> flash write_image Hello_World.hex Padding image section 0 at 0x020000a0 with 1888 bytes Padding image section 1 at 0x02000bd4 with 44 bytes Padding image section 2 at 0x02004e68 with 24 bytes (bank write end alignment) wrote 20096 bytes from file Hello_World.hex in 13.192564s (1.488 KiB/s)请问有没有提高速度的方向或者思路?
本文主要发布 OpenOCD 云途版 工具包:无需安装 Keil / J-Link 补丁包,使用 DAP-Link(CMSIS-DAP) 就能对 YTM32 系列芯片进行 烧录、擦除、校验和在线调试,也可以直接配合 VS Code + Cortex-Debug 使用。
下面以 YTM32B1HA01 开发板 + DAP-Link(SWD) 为例,演示从烧录到在 VS Code 里单步调试的完整流程,文中截图均为实板操作。
一、下载 工具包:openocd-ytmicro-20261024.zip(Windows 64 位,约 5.4 MB)openocd-ytmicro-20261024.zip
解压即可使用,无需安装,也不依赖其他运行库。可以放在任意目录,下文假设解压到 D:\tools\openocd:
D:\tools\openocd\ ├── openocd.exe ├── YTMicro\ <- 各系列芯片的下载算法和器件信息 ├── interface\ <- cmsis-dap.cfg、jlink.cfg、stlink.cfg └── target\ <- ytmicro.cfg(所有云途芯片通用) 二、支持的芯片和调试器芯片(DEVICE 取下面任意一个名字,不区分大小写):
系列 DEVICE 名称 YTM32B1HA0 YTM32B1HA01 YTM32B1LD0 YTM32B1LD04 YTM32B1LE0 / LE1 YTM32B1LE04、YTM32B1LE05、YTM32B1LE14、YTM32B1LE15 YTM32B1MC0 YTM32B1MC03 YTM32B1MD1 / MD2 YTM32B1MD14、YTM32B1MD24 YTM32B1ME0 / ME1 YTM32B1ME05、YTM32B1ME15 YTM32Z1LS0 / LS1 YTM32Z1LS06、YTM32Z1LS16 YTM32Z1MC0 / MD0 / ME0 YTM32Z1MC03、YTM32Z1MD04、YTM32Z1ME05PFlash 和 DFlash 都会自动识别,可直接烧录。
调试器(接口均为 SWD):
调试器 配置文件 驱动 DAP-Link / CMSIS-DAP interface/cmsis-dap.cfg 免驱,插上即用(推荐) J-Link interface/jlink.cfg 需用 Zadig 把 J-Link 切换为 WinUSB 驱动 ST-Link interface/stlink.cfg 需用 Zadig 安装 WinUSB 驱动三、命令行烧录(一条命令搞定)提示:J-Link 切换为 WinUSB 后,SEGGER 官方软件(J-Flash、Ozone 等)就无法识别它了,需要时再在设备管理器中改回来。日常使用 OpenOCD 更推荐 DAP-Link。
打开 cmd,进入工程目录(固件路径相对于当前目录),执行:
D:\tools\openocd\openocd.exe -f interface/cmsis-dap.cfg -c "set DEVICE YTM32B1HA01" -f target/ytmicro.cfg -c "program build/HA0_Adc_Demo.elf verify reset exit"参数说明:
-f interface/cmsis-dap.cfg:使用的调试器,换成 jlink.cfg / stlink.cfg 即可切换; -c "set DEVICE YTM32B1HA01":芯片型号,必须写在 target/ytmicro.cfg 前面; -f target/ytmicro.cfg:云途芯片通用配置,所有型号都用这一个; program ... verify reset exit:烧录 → 校验 → 复位运行 → 退出。实板运行结果(HA01 + DAP-Link,ADC Demo 约 14 KB,烧录 + 校验约 1 秒):
命令行烧录
看到 ** Programming Finished ** 和 ** Verified OK ** 就表示烧录成功。
常用操作 rem 烧录 hex / elf(自带地址) openocd.exe -f interface/cmsis-dap.cfg -c "set DEVICE YTM32B1HA01" -f target/ytmicro.cfg -c "program app.hex verify reset exit" rem 烧录 bin 文件,需要指定起始地址(HA0 PFlash 起始地址为 0x02000000,其他系列请查手册存储器映射) openocd.exe -f interface/cmsis-dap.cfg -c "set DEVICE YTM32B1HA01" -f target/ytmicro.cfg -c "program app.bin 0x02000000 verify reset exit" rem 擦除第一个 flash bank(PFlash) openocd.exe -f interface/cmsis-dap.cfg -c "set DEVICE YTM32B1HA01" -f target/ytmicro.cfg -c "init; reset halt; flash erase_sector 0 0 last; exit" rem 调低 SWD 速率(线较长或连接不稳定时),单位 kHz,默认 4000 openocd.exe -f interface/cmsis-dap.cfg -c "set DEVICE YTM32B1HA01" -c "set ADAPTER_SPEED 1000" -f target/ytmicro.cfg -c "program app.elf verify reset exit" 四、在 VS Code 中调试(Cortex-Debug) 1. 准备 VS Code 安装扩展 Cortex-Debug(marus25.cortex-debug); 安装 ARM GCC 工具链(需要其中的 arm-none-eabi-gdb.exe)。用云途 YCT 配置工具生成过 GCC 工程的话,工具链已经自带了; 工程能正常编译出 .elf。 2. 配置 .vscode/launch.json { "version": "0.2.0", "configurations": [ { "name": "HA0_Adc_Demo Debug", "type": "cortex-debug", "request": "launch", "cwd": "${workspaceFolder}", "executable": "${workspaceFolder}/build/HA0_Adc_Demo.elf", "servertype": "openocd", "device": "YTM32B1HA01", "serverpath": "D:/tools/openocd/openocd.exe", "configFiles": [ "interface/cmsis-dap.cfg", "target/ytmicro.cfg" ], "openOCDPreConfigLaunchCommands": [ "set DEVICE YTM32B1HA01" ], "svdFile": "${workspaceFolder}/.vscode/chip.svd", "runToEntryPoint": "main", "liveWatch": { "enabled": true, "samplesPerSecond": 4 } } ] }需要按自己的情况修改的地方:
字段 说明 executable 编译生成的 elf 路径 serverpath openocd.exe 的实际解压路径(用 / 或 \\) configFiles 第一项为调试器,换 J-Link 就写 interface/jlink.cfg openOCDPreConfigLaunchCommands set DEVICE <芯片型号>,芯片型号写在这里,它会在 ytmicro.cfg 之前执行 svdFile 芯片 SVD 文件,用于查看外设寄存器(可选) armToolchainPath 如果 arm-none-eabi-gdb 不在 PATH 中,加上这一项指向工具链的 bin 目录,例如 "C:/xxx/gcc-arm-none-eabi-10.3-2021.10/bin"launch.json 配置
3. 开始调试按 F5(或点击 运行和调试 → 开始调试)。Cortex-Debug 会自动启动 OpenOCD、下载程序,并停在 main()。之后就可以正常设置断点、单步、查看变量:
断点调试
上图在 ADC 采样循环中设置了断点,左侧 Variables 中可以看到实时读到的 voltage 值。
配置了 svdFile 后,在 XPeripherals 面板中可以按位域查看外设寄存器,例如 ADC0 的 CFG0:
外设寄存器
五、注意事项 set DEVICE 一定要在 target/ytmicro.cfg 之前。命令行中放在 -f target/ytmicro.cfg 前面;VS Code 中写在 openOCDPreConfigLaunchCommands 里。 烧录会占用一段 SRAM 作为工作区,烧录完成后不会恢复其中的内容。正常的"烧录 → 复位运行"流程没有影响;如果在调试过程中写 flash 后不复位直接继续运行,需要注意这一点。 芯片处于低功耗模式、或 SWD 引脚被复用时,可能连不上,可以在复位状态下连接(按住复位键再启动 OpenOCD)。 六、常见问题 现象 处理方法 Device 'XXX' not found 芯片名写错了,对照第二节表格检查 Error: unable to find a matching CMSIS-DAP device 调试器没插好,或被其他软件(Keil、其他 OpenOCD 进程)占用 Error connecting DP: cannot read IDR 检查 SWD 接线和目标板供电;可尝试降低 ADAPTER_SPEED Not enough working area 可在 set DEVICE 后加 -c "set WORKAREASIZE 0x4000" 增大工作区 VS Code 提示找不到 gdb 在 launch.json 中加 armToolchainPath 七、性能参考YTM32B1ME05,1 MB PFlash,DAP-Link SWD 4 MHz:
整片擦除:约 0.1 s 写入速度:约 160 KB/s 1 MB 完整镜像烧录 + 校验:约 9 s使用中遇到问题,欢迎在本帖回复,附上芯片型号、调试器型号和 OpenOCD 的完整输出,方便我们定位。
-
Announcements
Announcements regarding our community
-
Discussion & Question
A place to talk about whatever you want or ask a question
-
Blogs
Blog posts from individual members
快速上手云途开发生态
发帖前请查看
帮助改进和优化YT CONFIG TOOL,有机会抽取YTM32B1ME0 EVB哦...