|
书从何起,废话开始,说是很久以前发过一帖,探讨一下,通过手机otg烧录stc单片机
突然某一天又心血来潮,又想研究研究这STC-ISP的烧录通讯协议,又说是前人栽树,后人吃果,随着时代的进步,传统c51已经开始慢慢淹没在历史的长河里,进而被ARM,Arduino,派等平台产品替代,很多前人种树的地已经不在,果再也吃不到了,但是什么说呢,还是那句话,谷姐带路,立马高速。本帖纯属个人记录,又臭又长,不懂装懂,认真阅读者可能要耗费不少时间,为避免看君一帖等于白白耗时看一帖,谨慎注意。
一:分析STC烧录通讯协议。
本次从源头STC15系列的官方技术手册中提供的“利用主控芯片对从芯片(限STC15系列)进行ISP下载程序”章节结合STC-ISP官方PC程序来分析。
首先在STC8H系列技术手册给出大概参考流程图如下,仅供参考,仅供参考,仅供参考。
另外在手册中的“使用STC的IAP系列单片机开发自己的ISP程序”这章节内容中,同样也可以看到一些相关内容,IAP等待时间,命令字节等,这里有用到汇编语言,不是很懂,例如这里的这几个MOV,这A5,5A是不是看起来跟我们写准备编程,擦除Flash,用户代码时的参数3,参数4一样呢?
再看这几个命令字#1, #2,#3,是不是又跟我们设置命令字节中01,02,03一样呢?难道仅仅是巧合?相信答案应该是有关联的,因为手册中有说:STC的串口ISP(In-System-Programming)程序就是使用IAP功能来对用户的程序进行在线升级的。
OK,到这了,数据包格式以及流程大概已经就有个框架了,既然它可以利用主控芯片对从芯片进行ISP下载程序,那么换个角度看,这个主控就可以是PC,手机等,而STC-ISP要做的大概就是把这个流程,协议,串口驱动等这些关系给打通。
然后通过GitHub上这几个库stcgal,stcflash,stc8prog开源的源码的分析,以及网上一些资料的来看,STC早期产品的通信协议会有些差异,型号的不同也会有差异,mcu回复的参数信息数据包也有些差异,例如最初的STC89通信协议数据包,串口方式无奇偶校验,数据包校验和只有一个字节,MCU回复的命令字节也不同,握手前交互次数也不同。其次不同型号,功能参数不一样,使用外部晶振时钟和内部时钟时,MCU回复的响应数据也是有差异,但只能说是万变不离其宗。
由于本人手上只有STC15W4K56S4,固件版本号7.3.7T和STC15W408AS,固件版本号的7.2.5T(还是早年从坛友那换来的),所以以下是基于这2款型号来废话。
先把STC15手册里c程序,简单copy出来,提取简单总结一下,方便理解。
- 主机MCU P3.0--RxD读←(发送)TxD写--P3.1 从机MCU
- P3.1--TxD写(发送)→RxD读--P3.0
- ①MCU上电,主机发送0x7F给从机
- 主MCU以串口模式3最低波特率(2400)发送→(8位数据0x7F+1位偶校验) →从机MCU
- ②从机收到后回复数据包给主机
- 协议数据包格式:
- 标头 标识 数据(包含数据长度和数据标识和具体数据 )
- 0x46 0xB9 0x68 0x00 RecvSum = 0x68 + dat; 内容放入
- RecvCount = dat - 6; RxBuffer[]
- RecvIndex = 0;
- RecvSum += dat;
- RxBuffer[RecvIndex++] = dat
- 校验和 标尾
- 高8位,低8位 0x16
- ③主机判断接收结束
- if (UartReceived)
- {
- arg = RxBuffer[4]; //取出从MCU机发送回来第5个数据
- fwver = RxBuffer[17]; // 取出第18个
- if (RxBuffer[0] == 0x50) break; //如果等于第0位等于0x50,则说明握手成功,且返回的数据包是从机MCU的选项信息
- return FALSE; //否则返回失败
- }
- ④主机发送设置参数数据包(设置从芯片使用最高的波特率以及擦除等待时间等参数)
- 协议格式:
- 标头 标识 数据包
- 0x46 0xB9 0x6A 0x00 长度= 6+site
-
- 校验和 标尾
- 高八位,低8位 0x16
- sum = size + 6 + 0x6a;
- sum=sum+UartSend(TxBuffer[i])
- 设置从芯片使用最高的波特率以及擦除等待时间等参数
- TxBuffer[0] = 0x01;
- TxBuffer[1] = arg;
- TxBuffer[2] = 0x40;
- TxBuffer[3] = HIBYTE(RL(MAXBAUD));
- TxBuffer[4] = LOBYTE(RL(MAXBAUD));
- TxBuffer[5] = 0x00;
- TxBuffer[6] = 0x00;
- TxBuffer[7] = 0xc3;
- CommSend(8);
- while (1)
- {
- if (TimeOut == 0) return FALSE;
- if (UartReceived)
- {
- if (RxBuffer[0] == 0x01) break; //如果等于0x01则说明设置参数成功,从机MCU收到指令后,以相同的命令字回复主机。
- return FALSE;
- }
- }
- ⑤主机MCU,设置相同最高波特率,发送准备数据包
- ⑥主机MCU发送擦除从机mcu的数据包
- ⑦主机写入用户代码的数据包
- if ((RxBuffer[0] == 0x02) && (RxBuffer[1] == 'T')) break; //T的码值0x54
-
- ⑦.1有需要可以写选项参数
- //TxBuffer[0] = 0x04; 写参数命令
- //TxBuffer[1] = 0x00;
- //TxBuffer[2] = 0x00;
- //TxBuffer[3] = 0x5a;
- //TxBuffer[4] = 0xa5;
- 其他参数在对应具体位设置取值,其他位用0xFF补上
复制代码
简单对比总结一下,与stcgal库中protocols.py源码与逆向doc文件夹中的相关protocol解析,通过三方对比看起来,握手之前都些差异。下图为stcgal库给出的大概流程
但实质最终都是要使host和mcu处在同一波特率上,而官方手册里给出的是直接双方使用最高波特率(按我理解双方同一波特率便可)。而这里stcgal库似乎有根据电脑波特率,进而校正mcu时钟数据过程,具体我没什么深入研究,主要是有点看不懂,有几个计算的函数有点吃不消了。
其次官方手册中设置从芯片使用最高的波特率以及擦除等待时间等参数时中的第七个参数不一样(STC8H,STC12H用的是0x97,STC15用的是0xC3),而stcgal库中用的是iap_wait,感觉是以手册里此处为参考?
最后准备与擦除环节,STC15要判断版本号,大于7.2版本的命令数据参数多几个字节数据,具体看手册便可。而STC12H和STC8H直接是使用了STC15大于7.2版本的参数(不难推断,这些8H,12H系列的出厂时间肯定要晚一些)。
其他没什么想写的了,剩下都是Flash按块写入数据。马克一下,在stggal库ihex.py是解析hex文件的,解析出来的数据应该是对应手册里的char code DEMO[256] 数组数据,那么应该就是程序Flash具体字节数据,那么也应该就是使用对官方的STC-ISP烧录程序时对应这个位置的字节数据。
二,其他步骤不好搞,但还是可以验证一下这个流程第一步。打开神奇的串口助手,溜一溜看看。基于STC15W4K56S4,固件版本号7.3.7T,使用内部IRC时钟。
①
host2mcu:以较低波特率2400,串口偶校验,8位数据+1停止位,以10ms的周期不停发送0x7F,冷启动。(实际10ms太快了,pc接收端有延迟,数据包被隔开不是很好看,可以调长点,100ms以内,一般都可以正常进入isp)
mcu2host :回复mcu的一些相关信息参数。
如果各种原因不能进入isp,重新上电启动时,mcu2host:回复0x00
来看下正常交互时回复的具体各字节数据代表什么含义。(其实从stcgal库中源码protocol和options相关多个文件里也可以看出什么含义,但不知是我在手机上看编码格式不对还是什么原因,它指示的位置有偏移,其次它解释的也有些错漏,再者型号不同有些功能单片机本身就没有,也就有差异。)
首先可以十分明确的是,包头,命令字,校验和,包尾。
再结合stcgal源码中struct.unpack()解包中的索引值,可以得到掉电唤醒定时器频率,版本号,内部振荡器的频率,型号等。从stcgal库中model.py中,对应的型号migic值,得出flash大小等参数,还真是魔法呀,这个果可以说是直接摘了就吃,又香又甜。
其实这数据包对应的就是检测MCU时这个位置给出信息。这不就简单了,下载程序的同时,修改选项信息中的某一条后,再来重复上面的发送0x7F的步骤,在对比修改前后2个数据包的差异,便知具体哪个字节哪一位的含义。
借手册一图
记录过程篇幅太长了,
还是简单总结一下如下图。
又一点小插曲,如果不用外部晶振,就别乱接上电路,再次切换回内部IRC时钟时,如果2者频率相差很大可能导致IRC时钟频率校准不回来,或检测不到mcu等问题,这点手册里也相关信息,反正没事多看手册有好处,印象中以前好像有一次也遇到晶振引脚这个坑,不太记得了,不长记性。
新出厂芯片,实际频率数据处为FF,这点stcgal源码里也有。STC15W408AS新芯片测试
三,CH340官网有安卓的驱动与demo.apk源码,开发文档等,但这个demo.apk串口助手不能自动发送,一直想要自己开发,并加入STC-ISP通讯流程,这个坑太深了,目前stcgal通信协议流程握手前calibrate()还是不太没太理解,我的脑瓜目前还没有这能力,只能说,埋下深坑等虎豹,拋下鱼饵钓金鳌了,有事没事学学安卓开发也挺好,没事拆那么多垃圾没意思了。或者如同网友所说,一个win平板就能解决问题不比你这研究来研究去简单,什么说呢,毕竟万物皆推app的年代,就连"老妖"也学精明了,最新版的烧录软件都改叫AIapp-ISP,你看又Ai又app的,显得多牛13呀,嘿嘿。
后话如何,尚可未知,就这样,谢谢观看。
最后:参考阅读,几个链接,万一有人喜欢看呢
STC8A,STC8G,STC8H系列的IRC内部振荡源频率调节
STC8PROG - Linux下的 STC8A, STC8F, STC8G, STC8H 烧录工具
STC-ISP软件检测单片机50个数据的含义
手动修正STC单片机内部时钟频率
CHIPID应用,STC32只读特殊功能寄存器中等重要参数不要用无外部晶振的USB转串口来校准 STC的内部HIRC频率 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
打赏
-
查看全部打赏
|