204 lines
6.3 KiB
Markdown
204 lines
6.3 KiB
Markdown
# 记录下调试过程
|
||
脑袋不好使,过一周就记不清楚了。趁着还有印象,做下调试记录吧。
|
||
|
||
|
||
## 缘起
|
||
原来一直用stm8s003这款芯片,最多时候3颗003配合分工完成功能。
|
||
主控mcu各种IO口模拟多串口接收,数据流交叉流动,再配合自己搞的小调度内核,写起程序来太爽了。
|
||
|
||
直到疫情来了,各种芯片价格暴涨,原来1块的的直接暴涨到10块,而且缺货~
|
||
好日子到头了,只能考虑切换到国产MCU。
|
||
|
||
华大的这款看起来名字不错,比ww产的有更好的发展预期,就定它了。虽然现在国产MCU也缺货~
|
||
|
||
|
||
## HC32F003C4PA
|
||
性能看起来不错,很契合手头产品的使用场景。
|
||
* 32Mhz Corex-M0
|
||
* 16K Flash
|
||
* 2K RAM
|
||
* 低功耗
|
||
* 10Byte Chip ID
|
||
* 12bit 1Msps SARADC
|
||
|
||
|
||
## 为什么是python
|
||
python有多好自不用说,主要是主力开发工具是丐版MacBook Air,一入苹果,终身windows黑了。
|
||
话说之前主力系统是debian,足够清淡了~
|
||
|
||
国产这些MCU们,还没意思到社区的力量。更多diy玩家的参与,足够的热度,流量来了销量也水到渠成。
|
||
类似乐鑫/合宙(*唉,都是最早参与的一批人,就是没有跟随其喝汤,属实可惜*),日子过得真香。
|
||
希望华大成为下一个,虽然看起来完全没有搞社区的意识、能力。
|
||
|
||
|
||
## 番外思考
|
||
借助于自己搞的那套小调度内核,mcu甚至只有基本IO、串口、定时器功能就能完成大部分工作。
|
||
哪天能否自己封测个小mcu?
|
||
|
||
8/20脚TSSOP封装,2个串口,2-4个定时器,剩下全是基本IO。售价?5毛不能再多了,
|
||
那是不是能发财啦 :]
|
||
|
||
|
||
## 小目标
|
||
* **编译/下载**脱离windows环境依赖,支持mac及linux系统
|
||
* python脚本,串口烧录bin文件
|
||
* 离线烧录器,按键自动串口下载固件 (稍后一丢丢)
|
||
* 工程模版,gcc编译
|
||
|
||
|
||
## 调试方法
|
||
首先hc系列支持串口下载,高级点的mcu有mode引脚,可以直接进入uart下载模式。
|
||
hc32f003呢,启动时候uart应该是10ms内接收到0x18字节可以直接进入uart下载模式。
|
||
|
||
话说这种有很大风险,如果相连的外设启动后,不小心发了个0x18过来,是不是就炸了~
|
||
关键也没有文档说很清楚,如何退出uart下载模式。先mark下@
|
||
|
||
arm-none-eabi-gcc是支持M0内核编译的,加之华大提供了IAR/MDK的工程模版、启动文件,
|
||
移植到mac/linux系统应该是没问题的。
|
||
|
||
先说下烧录固件这部分功能吧,windows下有官方提供的HDSC ISP V2.07在线烧录工具,
|
||
连接好串口及RST引脚后,使用逻辑分析仪抓串口数据包就ok了。
|
||
后来发现了文档[HC32F003系列的FLASH串行编程.pdf](https://github.com/kicer/hc32flash/tree/master/docs/HC32F003系列的FLASH串行编程.pdf),
|
||
显然是过期的,协议格式不一致,但是有很大参考价值。
|
||
|
||
后面发现ISP烧录工具是Mono .NET的,借助ILSpy反汇编出来。
|
||
可以得到你想得到的一切~
|
||
|
||
当然理论上也是可以直接把反汇编后的代码再重新生成linux/mac上用的。
|
||
但.NET不是本人的菜,自己写个python用起来会更爽~
|
||
下载脚本借鉴了stm8flash、luatool工具的很多代码,
|
||
芯片配置数据及ramcode都是从官方ISP软件中复制过来的,没有精力验证。
|
||
遇到坑就填吧,反正有原始反汇编代码可以参考。
|
||
|
||
所以,就这么简单
|
||
|
||
|
||
## 调试过程
|
||
|
||
### bootloader启动
|
||
1. 复位RESET引脚约18ms
|
||
2. pc循环发送0x18 0xFF共10组
|
||
3. mcu应答0x11共9组
|
||
4. 检查mcu状态
|
||
> 01 FC 0B 00 00 02 00 00 00 0A
|
||
< 01 02 EE FF ED (加密)
|
||
< 01 02 FF FF FE (未加密)
|
||
5. 加密则执行解密动作(擦除FLASH上内容)
|
||
> B5 34 84 52 BF
|
||
< 01
|
||
6. 准备下载ramcode
|
||
> 00 00 00 00 20 A4 07 00 00 CB
|
||
< 01
|
||
7. 开始下载ramcode
|
||
> B8 0A ... 9F
|
||
< 01
|
||
8. 启动ramcode
|
||
> C0 00 00 00 00 00 00 00 00 C0
|
||
< happybaby 00 00
|
||
|
||
|
||
### ramcode启动
|
||
启动后mcu端发送字符串 *happybaby*
|
||
> 68 61 70 70 79 62 61 62 79 00 00
|
||
|
||
0. 修改通信用波特率
|
||
- 修改成9600bps (00 00 80 25)
|
||
> 49 01 00 00 00 00 04 00 80 25 00 00 F3
|
||
- 修改成115200bps (00 01 C2 00)
|
||
> 49 01 00 00 00 00 04 00 00 C2 01 00 11
|
||
- 应答
|
||
< 49 00 00 00 00 00 00 00 49
|
||
|
||
1. 请求0x20字节数据 (指定波特率)
|
||
> 49 05 00 00 00 00 20 00 6E
|
||
< 49 00 00 00 00 00 20 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FE FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF EF 38
|
||
|
||
2. 校验错误
|
||
> 49 05 00 00 00 00 20 00 5E
|
||
< 49 01 00 00 00 00 00 00 4A
|
||
|
||
3. 请求0x10字节数据
|
||
> 49 05 00 00 00 00 10 00 5E
|
||
< 49 00 00 00 00 00 10 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FE 48
|
||
|
||
4. 请求0x0200字节数据
|
||
> 49 05 00 00 00 00 00 02 50
|
||
> 49 05 00 02 00 00 00 02 52
|
||
> ...
|
||
> 49 05 00 3C 00 00 00 02 8C
|
||
> 49 05 00 3E 00 00 00 02 8E
|
||
|
||
5. 空白检测
|
||
> 49 07 00 00 00 00 04 00 00 40 00 00 94
|
||
< 49 00 00 00 00 00 01 00 01 4B
|
||
> 49 07 00 00 00 00 04 00 00 02 00 00 56
|
||
< 49 00 0F 00 00 00 01 00 00 59
|
||
|
||
6. 整片擦除
|
||
> 49 02 00 00 00 00 00 00 4B
|
||
|
||
7. 页擦除(1sector=512Bytes)
|
||
> 49 03 00 00 00 00 00 00 4C
|
||
< 49 00 00 00 00 00 00 00 49
|
||
> 49 03 00 02 00 00 00 00 4E
|
||
< 49 00 00 02 00 00 00 00 4B
|
||
> ...
|
||
> 49 03 00 3E 00 00 00 00 8A
|
||
> 49 00 00 3E 00 00 00 00 87
|
||
|
||
8. 编程
|
||
> 49 04 00 00 00 00 20 00 <data> CHK
|
||
< 49 00 00 00 00 00 00 00 49
|
||
|
||
9. 校验,所有数据的累加和取最后两个字节
|
||
> 49 06 00 00 00 00 04 00 20 00 00 00 73
|
||
< 49 00 00 00 00 00 02 00 CF 1F 39
|
||
> 49 06 00 00 00 00 04 00 00 40 00 00 93
|
||
< 49 00 00 00 00 00 02 00 00 C0 0B
|
||
|
||
|
||
#### 读取FLASH数据
|
||
> 49 05 A0 A1 A2 A3 L0 L1 CHK
|
||
< 49 00 A0 A1 A2 A3 L0 L1 <data> CHK
|
||
* 49 05: 协议头
|
||
* A3..0: 起始地址
|
||
* L1..0: 字节长度
|
||
* data: FLASH数据
|
||
|
||
#### 按页擦除FLASH数据
|
||
> 49 03 A0 A1 A2 A3 00 00 CHK
|
||
< 49 00 A0 A1 A2 A3 00 00 CHK
|
||
* 49 03: 协议头
|
||
* A3..0: 起始地址
|
||
|
||
#### 整片擦除FLASH数据,耗时约40ms
|
||
> 49 02 00 00 00 00 00 00 4B
|
||
< 49 00 00 00 00 00 00 00 49
|
||
* 49 02: 协议头
|
||
|
||
|
||
#### 空白检测
|
||
> 49 07 00 00 00 00 04 00 A0 A1 A2 A3 CHK
|
||
< 49 C1 C0 00 00 00 01 00 00 CHK
|
||
* 49 07: 协议头
|
||
* C1..0: 检测值
|
||
* A3..0: 字节长度
|
||
|
||
#### 校验
|
||
> 49 06 00 00 00 00 04 00 L0 L1 L2 L3 CHK
|
||
< 49 00 00 00 00 00 02 00 S1 S0 CHK
|
||
* 49 06: 协议头
|
||
* S1..0: 校验和
|
||
* L3..0: 字节长度
|
||
|
||
#### 编程
|
||
> 49 04 A0 A1 A2 A3 L0 L1 <data> CHK
|
||
< 49 00 A0 A1 A2 A3 00 00 CHK
|
||
* 49 04: 协议头
|
||
* A3..0: 起始地址
|
||
* L1..0: 字节长度,最大支持0x40字节
|
||
|
||
#### 加密
|
||
> 49 09 00 00 00 00 00 00 52
|
||
< 49 00 00 00 00 00 00 00 49
|