切换到宽版
  • 15372阅读
  • 96回复

[ARM]从头开始做个stm8的swim调试编程器,兼容stlink(开源,首发数码之家) [复制链接]

上一主题 下一主题
离线2545889167
 

发帖
11475
M币
46079
专家
223
粉丝
4473
— 本帖被 香瑶 设置为精华,作者+3000M币+5专家(2017-09-11) —
这货大概花了2周多的时间来完成,从开始研究手册到最终能用。
本作的功能是:实现了兼容官方上位机的能对stm8单片机进行调试、下载的设备

研究一个兼容stlink的编程器,主要是因为原装的stlink的固件只能在stm32f103c8上使用,换到stm32f103rc或者gd32上面都是不能正常工作的。这可是有些蛋疼。
如果说10多元就能在淘宝上买一个stlink的话,另外一个主要动机是想练练手了,本次折腾学到了好多关于stm32的定时器的高级用法,也对usb模块更熟练了。

还有就是,要感谢坛友 @jcdzxh   的大力帮助,给提供了很多的知识

成果展示如图硬件部分,


设备管理器查看设备被成功枚举为stlink



使用st官方的flash编程器STVD工具对目标板进行flash读、flash写、数据eeprom读、数据eeprom写、选项字节读、选项字节写、芯片上锁解锁  都是没有问题的


使用iar进行在线仿真调试
没有问题

逐行执行





逻辑分析仪抓取的一段读flash操作发生的波形
0通道为swim
1通道为rst
4.5通道为usb的d+和d-



硬件接线示意图



调试的时候,用了这些

由stm32核心板(板子上焊接的是gd32)作为调试器主机,stm8核心板是目标板。
jlink是用于给stm32调试器编程,逻辑分析仪负载分析swim接口波形和usb数据

----------------------------------分割线----------------------------------
本次主要参考的手册是st官方提供的um0470手册
STM8-SWIM通信协议和调试模块


STM8 的调试系统接口允许一个调试或编程工具,通过一根基于开漏接口的单总线双向(bidirectional)通信线连接到 MCU。

SWIM 是一个基于异步(asynchronous),强灌电流(high sink)(8mA),开漏,双向通信(bidirectional communication)的单总线接口。
当 CPU 正在运行,出于调试目的,SWIM 允许非抢占式(non-intrusive)读写访问,去执行 on-the-flay 到 RAM 和外设寄存器。
此外,当 CPU 停止(stalled),SWIM 允许读写访问,去执行 MCU 存储空间的其它部分(数据 EEPROM 和程序存储器)。
CPU 寄存器(A,X,Y,CC,SP)也可以被访问。这些寄存器被映射在存储器中,而且可以以相同的方式去访问





对于芯片编程,首先要对目标芯片写进入入口时序,用于激活目标芯片的swim调试模块
POR(上电复位)后,SWIM 一直处于 OFF 模式,SWIM 引脚采样用于检测入口序列。要实现这一机制,内部低速 RC 时钟在 POR 后自动运行,并且在 SWIM 处于 OFF 模式下一直保持。


SWIM 激活时序图如所示,图中每一段的描述如下。
1. 为了激活 SWIM,SWIM 引脚必须强制拉低 16μs(在 HSI 下最少 64 个脉冲)。
2. 第一个脉冲后(总线当前为 0),在 SWIM 的 ACTIVE 状态入口处,SWIM 检测一个特殊序列以保证鲁棒性(guarantee robustness).SWIM 入口序列式:4 个 1KHz 的脉冲,紧接着 4 个 2KHz 的脉冲。序列的频率很容易被内部 RC 检测到。入口序列如所示。注意序列以 SWIM 引脚拉高作为开始和结束标志。

3. 入口序列后,SWIM 进入 ACTIVE 状态,HSI 振荡器(oscillator)自动开启。

4. 延时过后,SWIM 发出一个同步帧给主机。
同步帧描述:MCU 的 SWIM 总线输出低电平,维持 128 个 SWIM 时钟脉冲表示发出一个同步帧,用于调试主机对RC时钟频率的测量。一个高级调试主机可以重新校准(re-calibrate)它的时钟,来适应(adapt)MCU 内部 RC 的频率。
5. 开始 SWIM 通信之前,SWIM 线必须释放为高电平,以保证 SWIM 准备好通信(至少维持 300ns)。
6. 写 0A0H 到 SWIM_CSR 寄存器:
Bit5 置一,允许访问整个存储器和 SRST 命令
Bit7 置一,掩盖内部复位源
7. 释放加载配置字节的序列的复位。等待 1ms 以保持稳定。


其中
HSI = 16MHz   SWIM 时钟为 HSI/2 = 8MHz

用逻辑分析仪抓取入口时序以后的效果如图
图上可见强制拉低 至少16μs(这里远多于16us)
4 个 1KHz 的脉冲,紧接着 4 个 2KHz 的脉冲



从机发送的同步帧给主机
如果rc时钟足够精确的话,这里应该是16us,显然手上的这片stm的时钟频率有些误差
紧接着的同步帧以后,是一个软件复位指令


写 0A0H 到 SWIM_CSR 寄存器







[ 此帖被2545889167在2017-09-15 00:45重新编辑 ]
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共36条打赏M币+478专家+6
411183343 M币 +9 謝謝分享 10-22
cushion 专家 +1 優秀文章 10-22
cushion M币 +1 優秀文章 10-22
网络孤客 专家 +1 優秀文章 10-08
网络孤客 M币 +20 優秀文章 10-08
gnimuh M币 +20 - 09-18
lyx5678 M币 +30 原創內容,優秀文章 09-16
newnet1234 M币 +20 謝謝分享 09-14
taoshptao 专家 +1 原創內容 09-14
taoshptao M币 +13 原創內容 09-14
离线2545889167

发帖
11475
M币
46079
专家
223
粉丝
4473
只看该作者 1楼 发表于: 09-11


继续写swim接口

通讯位格式采用的是一种归零格式(Return-To-Zero format),它允许位同步。
swim接口有两个通信速率可选。在 SWIM 激活状态下,选择的是低速通信速率。
通过设置 SWIM_CSR 寄存器的 HS 位置一,选择高速通信速率。



高速模式:

10 个 SWIM 时钟生成一位。
位格式为:
2 个时钟脉冲的 0 电平,接着 8 个时钟周期的 1 电平----表示数据1。
8 个时钟脉冲的 0 电平,接着 2 个时钟周期的 1 电平----表示数据0。
当 SWIM 收到一包数据时,它将解码:
1:检测到小于或等于 4 个连续低电平。
0:检测到大于或等于 5 个连续低电平。



高速模式:
22 个 HSI 振荡器脉冲生成一位。
位格式为:
2 个时钟脉冲的 0 电平,接着 20 个时钟周期的 1 电平----表示数据1。
20 个时钟脉冲的 0 电平,接着 2 个时钟周期的 1 电平----表示数据0。

当 SWIM 收到一包数据时,它将解码:
1:检测到小于或等于 8 个连续低电平。
0:检测到大于或等于 9 个连续低电平。


仔细观察这个协议,虽然是单总线,但是并不怎么难,个人认为至少比18b20的要简单一些,但是实际操作起来并不是那么简单,毕竟速度不低,而且如果要波形好看也不容易。
还有个蛋疼的问题是,在接收从机回来的数据的时候,从机是不给主机等待的时间的,也就是说,从机回复的速度相当的快,给主机做从输出到输入的切换的时间相当短。
这段时间,据jcdzxh大神测试,不出意外从主机发送结束到收到从机的ack时间间隔只有12个主机时钟,这,相当有挑战。最终jcdzxh大神用了几天时间优化汇编搞定了这个问题,不过我用了另外一种思路,也折腾了小一个星期,终于解决。后面说怎么实现的。

观察这个波形以后,冥思苦想了一段时间以后想出了一种方法。这个时序,其实是一种占空比在改变的pwm波,数据1就是一个占空比为80%-90%的pwm,数据0就是占空比为10%-20% 。那么思路就明确了,用定时器的输入捕获模块来实现功能。
9

首先是输出,用定时器3的输入捕获通道1作为pwm输出功能。pwm的周期是规定的22个或者10个swim时钟(8M),占空比的调整方法是,先计算好所有位的pwm位宽,在每个pwm波形开始的时候,触发dma吧下一位数据的占空比搬运到捕获比较寄存器,当一组数据搬运玩以后,给捕获比较寄存器再赋值0,那么,pwm输出会自动停止,总线恢复高。这样就能产生漂亮的输出波形。(说的过程原理简单,实际上背后一把辛酸泪)
低速 输出一个0


低速,输出一个1


高速 输出一个0

高速 输出一个1

可见波形相当的工整频率,不多也不缺,时间正好合适(这上面花了大量时间来实现)



接着是输入,比输出要更复杂一些。输入使用了定时器4的1,2通道做pwm输入捕获操作。定时器的2通道使能下降沿捕获,1通道使能上升沿捕获。
同时设定,2通道下下降沿的同时自动清空定时器计数器,1通道上升沿捕获的瞬间,会记录下此时定时器的计数器值,并使能dma将数据搬运到缓存区,这样一来,就能记录 一个低脉冲持续的时间,计算这个低脉冲时长是是否大于数据时钟(高速10ck,低速22ck)的一半,就能判断这个数据位是0还是1

那么问题来了,因为从机需要在收到数据正确以后回复ack位,ack位回复的相当快,就导致了输出切换到输入的时间相当短,几乎不可能实现的切换。
那么换个思路,如果我在主机发送数据之前,就先吧接收捕获打开,我吧主机发出去的内容也一起捕获进来,最后丢弃不管,只看从机的内容,这不就免了切换了吗?实验后效果确实很好,完成功能。(说的过程原理简单,实际上背后一把辛酸泪,这上面花了更加大量时间来实现)


SWIM 通信协议
每一个字节或命令之前都有一位包头,用于仲裁主机和设备发起的通信。
主机的头是“0”,由于是开漏结构,可用于在仲裁时取得优先权。若无数据传输,主机
就可以开始传输。



主机发送的每个命令有以下组成:
1 个命令(ROTF,WOTF or SWRST)包含:
头:1Bit“0”
b2-b0:3-bit 命令
pb:奇偶位(parity bit):b(i)异或
ack:应答位(1bit“1”),由从机回复主机。若检测到错误或为准备好,接收者必须发送非应答(NACK:1bit“0”)

若干数据包(WOTF 下)包含:
头:1Bit“0”
b7-b0:8-bit 数据
pb:奇偶位(parity bit):b(i)异或
ack:应答位(1bit“1”)。

从机发送的每个命令有以下组成:
头:1Bit“1”
b7-b0:8-bit 数据
pb:奇偶位(parity bit):b(i)异或
ack:应答位(1bit“1”)由主机回复从机

命令只有三,复位、读、写。简单又粗暴


SRST : 系统复位
格式:一个命令从主机到目标板
参数:无
只有 SWIM_CSR/SWIM_DM 位置一,SRST 命令产生一个系统复位。


ROTF  读  格式:一个命令+要读的字节数+三个字节的地址。
参数:
N 8 位的将要读取的字节数(1~255)
@E/H/L 即将访问的 24 位地址
D[…] 从存储空间读取的字节




WOTF 写  格式:一个命令+要写的字节数+三个字节的地址
参数:
N 8 位的将要写的字节数(1~255)
@E/H/L 即将访问的 24 位地址
D[…] 将要写到存储空间的字节

现在再来看刚才那个往0x007f80寄存器写数据的操作,是不是就很清晰了







[ 此帖被2545889167在2017-09-11 01:51重新编辑 ]
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共15条打赏M币+191专家+2
柱栅管 M币 +1 優秀文章 09-20
飞向狙沙 专家 +1 对于这种牛气的技术贴,只加分,不评价 09-19
飞向狙沙 M币 +20 对于这种牛气的技术贴,只加分,不评价 09-19
hover_730 M币 +13 謝謝分享 09-14
无语·回忆 M币 +20 讲的很详细,Mark一下,仔细拜读 09-13
链接 M币 +13 謝謝分享 09-12
yi0819 M币 +22 謝謝分享 09-12
snowrose2000 专家 +1 謝謝分享 09-11
snowrose2000 M币 +13 謝謝分享 09-11
潜隆 M币 +13 謝謝分享 09-11
12
离线2545889167

发帖
11475
M币
46079
专家
223
粉丝
4473
只看该作者 2楼 发表于: 09-11
好了,swim通讯完成以后,就要来考虑如何兼容st官方的上位机和usb驱动
毕竟自己写一个上位机体系工程量实在是,太大太大了,没那么多时间精力去搞,所以搞个指令兼容就行了。

第一步是usb设备的枚举
这里用到了一个小工具 UsbTreeView
插上usb设备后,就能通过这个软件来查看到这个设备所有的设备描述符
根据这些描述符,就能枚举出一个和原装stlink设备描述一模一样的设备来


简单修改usb_desc.c文件就行
其中

设备的vid:0x0483 代表的是意法半导体公司
设备的pid:0x3748 代表的产品是stlink


详见网址 http://www.linux-usb.org/usb.ids




设备枚举成功以后,就是解析stlink的上位机指令了
这里找出另外一款神器bus hound
对通讯过程进行抓包,然后脑洞+推敲猜测得出上位机的指令方式


花了一晚上总结整理得以下指令,其实不咋难



然后对照命令进行操作就行了,细节不在赘述,这块难度不大,详情见附件



[ 此帖被2545889167在2017-09-11 02:09重新编辑 ]
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共6条打赏M币+115
链接 M币 +13 謝謝分享 09-12
yi0819 M币 +22 只有高手才能这么玩,屌丝只有看看的份 09-12
huaweiwx M币 +20 以資鼓勵 09-11
snowman007 M币 +20 - 09-11
yhky M币 +20 - 09-11
msi12 M币 +20 - 09-11
离线2545889167

发帖
11475
M币
46079
专家
223
粉丝
4473
只看该作者 3楼 发表于: 09-11
最后一楼,发固件和源代码
固件:(这个固件有bug,下载楼下最新的)



源代码:
解压密码:mydigit-2545889167
工作不容易,所以设置了售价,谢谢




特别感谢:坛友 @jcdzxh  
参考连接:
www.st.com/content/ccc/resource/technical/document/user_manual/ca/89/41/4e/72/31/49/f4/CD00173911.pdf/files/CD00173911.pdf/jcr:content/translations/en.CD00173911.pdf

https://sourceforge.net/projects/stm32f100tostm8s105swimlibrary

https://github.com/vdudouyt/stm8flash

www.stmcu.org/module/forum/thread-580972-1-1.html

[ 此帖被2545889167在2017-09-12 23:47重新编辑 ]
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共18条打赏M币+242
trg13 M币 +20 - 09-14
无语·回忆 M币 +20 精品文章,无私奉献,谢谢楼主! 09-13
链接 M币 +13 謝謝分享 09-12
zhaocz M币 +8 優秀文章 09-12
girlstorm M币 +20 優秀文章 09-12
rallyezhang M币 +20 原創內容 09-12
杨小伟 M币 +9 優秀文章 09-11
ijelkam M币 +3 謝謝分享 09-11
qiang7260 M币 +8 優秀文章 09-11
cao57508 M币 +8 经鉴定,这是精品文章 09-11
12
离线2545889167

发帖
11475
M币
46079
专家
223
粉丝
4473
只看该作者 4楼 发表于: 09-11
bug和更新日志

9月11日早
bug:iar下不能使用调试功能,原因为两次进入时序冲突。正在研究对策。

9月11日 夜
更新固件:修复iar不能调试的问题
bug:usb stall


9月13日 夜
更新固件:修复usb stall
提供8mhz晶振和12mhz晶振固件
[ 此帖被2545889167在2017-09-13 20:00重新编辑 ]
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共4条打赏M币+16专家+1
xixiandcc M币 +2 謝謝分享 09-15
cushion M币 +1 我试了STM32的配0911成功率比GD32高一倍,特别USB3.0好很多。 期待加灯的完美版本! 09-13
链接 专家 +1 謝謝分享 09-12
链接 M币 +13 謝謝分享 09-12
离线cao57508

发帖
2061
M币
3598
专家
7
粉丝
66
只看该作者 5楼 发表于: 09-11
半夜发文,这完全没发抢沙发。
本帖最近打赏记录:共1条打赏M币+20
2545889167 M币 +20 - 09-11
离线ookfei

发帖
1680
M币
5548
专家
-1
粉丝
34
只看该作者 6楼 发表于: 09-11
占位前排 混眼熟,  口水楼主这么折腾
本帖最近打赏记录:共1条打赏M币+5
2545889167 M币 +5 - 09-11
离线shi988

发帖
511
M币
939
专家
2
粉丝
17
只看该作者 7楼 发表于: 09-11
厉害了大神,要跟着大神的脚步走。。。。。。。。。。。。。
本帖最近打赏记录:共1条打赏M币+20
2545889167 M币 +20 - 09-11
离线msi12

发帖
1471
M币
498
专家
17
粉丝
10844
只看该作者 8楼 发表于: 09-11
目测好大的工程量,还有逻辑分析仪立功了
本帖最近打赏记录:共1条打赏M币+13
2545889167 M币 +13 - 09-11
离线yhky

发帖
7188
M币
4848
专家
18
粉丝
75
只看该作者 9楼 发表于: 09-11
USB协议用这个逻辑分析仪,USB1.x吧
本帖最近打赏记录:共1条打赏M币+20
2545889167 M币 +20 - 09-11
快速回复
限80 字节
如果您提交过一次失败了,可以用”恢复数据”来恢复帖子内容
 
上一个 下一个