手上的嵌入式设备一多,尤其是路由器一多,就会发现时不时的要用到 SPI Flash 编程器。然而,市售的 SPI NOR Flash 编程器虽然价格已经非常便宜,但是速度不算给力,而且都是基于私有协议的,完全不能在 Linux 下用。虽然可以开虚拟机,但是咱还是希望方便点,不是吗?
好在后来无意中发现了 coreboot (原 LinuxBIOS )项目开发的 flashrom 工具居然带有离线编程功能,除了支持一票比较贵的专用编程器/基于 FTDIxxxxH 的编程器外,还支持一种叫做 serprog 的协议,可以通过串口操作单片机来给 SPI 闪存编程。这样一来就方便了。flashrom 的 wiki 里给了基于 Arduino 的 serprog 的固件源码,其实就是为 ATMEGA 系列 AVR 单片机设计的。
既然手头有片 ATMEGA8L ,那么就开始吧。首先布下板子。电路很简单。
由于 ATMEGA8L 似乎有频率上的限制,这里用了 12MHz 的晶体。实际上有 ATMEGA88A 的话可以用 16MHz 的晶体。
在面包板上测试成功。
固化到万用板上。顺便吐个槽,双面万用板真是闹眼子啊,正面背面都被过孔连在一起了还能叫双面么?!
用法也很简单,首先你的机器上要安装有 flashrom 。Ubuntu 的软件库里自带了:
sudo apt-get install flashrom
但是官方 SVN 仓库里的版本更新一些,而且支持 serprog 的 spispeed 选项。不怕麻烦的最好自己编译一下:
svn co svn://flashrom.org/flashrom/trunk flashrom cd flashrom make sudo make install
连接一个 USB to UART bridge ,装上 SPI 闪存,接上电脑,输入以下命令:
flashrom -p serprog:dev=/dev/ttyUSB0:2000000 -r somefile.bin flashrom -p serprog:dev=/dev/ttyUSB0:2000000 -E flashrom -p serprog:dev=/dev/ttyUSB0:2000000 -w somefile.bin
即可读/擦/写 SPI Flash 。写入的时候会自动查空、擦除、写入和校验。
当然,就像 wiki 里说的那样,这个简陋的编程器也有诸多问题:
- AVR 的 5V 工作电压导致其 IO 电平和 3.3V 的闪存不兼容;
- 速度慢( UART 只有 2Mbps ,最快 250KB/s );
- 诸多涉及到 UART 的麻烦,如波特率、转换器和连接等。
考虑到手头上的 STM32F103C8T6 核心板也是个闲得没事干的便宜货,而且还带了硬件 USB2.0 FullSpeed 接口,而且 ST 还有 USB 虚拟串口的例程,不如拉出来溜溜干点活。
STM32F103R8T6 有以下优点:
- 是最容易买到的 STM32F103 系列里最小的一款,而且也最便宜;
- 最高 36MHz 的 SPI 接口;
- 多通道 DMA 引擎;
- 硬件 USB 2.0 FullSpeed 控制器;
- 片上 20KB RAM 和 128KB Flash ,足够实现虚拟串口模拟;
- 有虚拟串口模拟就意味着不需要硬件 UART ,不需要转换器,不需要杜邦线,不需要设置波特率,不会被 UART 掐住速度和稳定性;
- 90DMIPS 的运算速度是编程器性能的有力保证;
- 纯天然的 3.3V I/O ,和 SPI Flash 的电气兼容性好。
经过一个星期的折腾,我终于得到了基于 STM32 的 serprog 的第一个可用版本。我把它叫作 serprog-stm32vcp 。这时它只有 200KB/s 到 300KB/s 的读取速度。
最初的硬件是用一块带 USB 的核心板配合面包板完成的。核心板是淘宝上买的,回流焊接的,价格不到 ¥30 。
接下来,我做了一系列优化,包括尽量成块地传送数据,提供 SPI 时钟设定以便更快地操作闪存,使代码在 SRAM 中执行以避免片上 Flash 的等待造成性能上的影响等等。此时 serprog-stm32vcp 的读取速度已经有 500KB/s 左右了。后来我就想,既然 STM32 带了 DMA 引擎,何必不利用一下呢?只可惜网上找的 DMA 例子都极具误导性,折腾了一整天总算搞定了,于是有了第二个版本的 serprog-stm32vcp 固件。此时 serprog-stm32vcp 的读取已经高达 850KB/s ,接近 USB2.0 FullSpeed 的极限了( 12Mbps )。
随后,有了一个固化的版本。这个板子也是淘宝上买的,也是回流焊接的,可能是最有用的 STM32 核心板了吧,价格 ¥35 。
以及……一些对付贴片芯片的专业好帮手——弹跳座。
我觉得开个专业修砖头的店问题不大了。
偷懒的同学,这里有编译好的固件,以及 github 上的仓库。
用法很简单,和基于 AVR 的 serprog 基本相同,只不过在最新的 flashrom 里可以加上 spispeed 参数:
flashrom -p serprog:dev=/dev/ttyACM0:4000000,spispeed=36000000 -r somefile.bin flashrom -p serprog:dev=/dev/ttyACM0:4000000,spispeed=36000000 -E flashrom -p serprog:dev=/dev/ttyACM0:4000000,spispeed=36000000 -w somefile.bin
ttyACM0 后面的 4000000 是波特率,因为这个编程器并没有用到任何物理上的 UART 所以可以随便填,只要你的系统允许既可,不会影响速度。影响速度的是后面的 spispeed 参数。
最后给点性能测试的结果:
闪存型号 | 闪存容量 | 读取速度 | 写入速度 | 擦除时间 | CH341A 参考速度 |
---|---|---|---|---|---|
EN25F16 | 2048 KiB | 855.5 KiB/s | 118.2 KiB/s | 20.4 秒 | – |
MX25L3205D | 4096 KiB | 795.3 KiB/s | 136.2 KiB/s | 62.2 秒 | 117.0 KiB/s |
MX25L6445E | 8192 KiB | 803.3 KiB/s | 144.6 KiB/s | 93.9 秒 | 117.0 KiB/s |
MX25L12845E | 16384 KiB | 797.7 KiB/s | 146.8 KiB/s | 224.7 秒 | 18.2 KiB/s |
注:CH341A 的参考速度为经销商或网友给出,未注明读取或写入,但是根据使用经验来说应该是读取。flashrom 对 MX25L12845E 的支持状态为“ UNTESTED ”。
今后的速度测试会在仓库里的 PERFORMANCE 文件里更新。
附:某种 CH341A 编程器的照片
顺便拆了锁紧座,看看里面啥结构。锁紧座这个东西还真是鸡肋。
真是个好东东,前几天为了写SPI,做了4个编程器,目前只有2个成功,一个是AVR EJTAG-ICE固件的,另一个是USBASP硬件+BRSPI固件,两个都是V-USB模拟,都超级慢,读一个2Mb居然要好几分钟……
请教一下,我有CH341的编程器
对你的这个编程器也感兴趣。请问电路板在什么地方可以买到
另外,这个编程器对有加密区域的SPI flash支持吗
最大支持多大的flash。淘宝上有点店里出售的ch341编程器支持32M(256mbit)
做这个玩意主要是配合 Linux 下的 flashrom 的。不过现在 Windows 版的 flashrom 也支持 serprog 了,所以问题应该不大。
flashrom 的闪存支持列表见 http://www.flashrom.org/Supported_hardware#Supported_chips 。
里面列举的 3.3V 的 SPI 闪存都支持,不过目前没做 256Mbit 的支持——其 serprog 协议用的仍然是 24 位地址,目前其开发者正打算将其扩展到 32bit 。
至于板子,在淘宝搜 STM32F103 ,价格 25-40 间带 USB 的基本都能用,注意看下别买 USB 只能供电或者做 ISP 的板子就行。弹跳座也有不少便宜的,但是图中三个座子加起来比板子本身贵多了。
按照说明,自己也做了一个,完全成功,读写速度飞快,感谢博主的分享。谢谢你。
我下载了一个windows版本的flashrom。我用的是stm32.已经安装好了windows下面的驱动。但是不知道windows版本的flash应该怎么使用?
Windows 下可能还需要 ST 的 VCP 驱动,另外只有最近的 flashrom 才对 Windows 有比较好的支持。在命令提示符里运行,语法估计跟 Linux 上的会有不同,可能需要把 /dev/ttyACM0 换成 COMx 之类的。
C:\flashrom-0.9.6.1-r1705-mingw>flashrom -p serprog:dev=COM8:4000000,spispeed=36
000000 -r 2.bin
flashrom v0.9.6.1-r1704 on Windows 6.1 (x86)
flashrom is free software, get the source code at http://www.flashrom.org
Calibrating delay loop… OK.
Warning: given baudrate 4000000 rounded down to 115200.
这是我的命令运行结果。为什么波特率会被限制在115200呢?我装的是VCP的驱动。命令是无尽的等待,没有任何反应
由于我没在 Windows 下试过,所以不清楚。固件被设计成忽略波特率的。可能是 VCP 驱动的问题吧。
嗯。可能是驱动问题了,没办法,还是用回虚拟机+ubuntu的方式好了
用的你预编译的固件 http://dword1511.info/dword/projects/serprog-stm32vcp/prebuilt/20130331.hex 写入到stm32f103c8t6的开发板里面了。
把开发板的usb接到windows主机,然后在设备管理器里面能看到 flashrom.org serprog-STM32VCP 字样。
然后按照这里 http://flashrom.org/Windows 用 libusb-win32 驱动起来了, 也编译了windows下的flashrom。
之后应该怎么使用呢,用libusb驱动的没有串口设备,应当使用的设备名是什么呢?
用stm的vcp倒是能驱动,但是使用的时候速度比较慢。
多谢
不好意思,本来是打算在 Linux 下用的,所以对 Windows 下的情况不清楚。在“ Making libusb-based driver for your device ”这一步的时候插上并选择了 stm32vcp 吗?
选了,不选的话不能驱动的
刚刚看了一下,serprog 似乎是不需要这个驱动的,只需要串口驱动就够了。可以试试指定 SPI 时钟频率: serprog:dev=[/dev/device]:[baud],spispeed=36M
另外你用的闪存和得到的速度大概是多少?
还没开始接闪存呢,先让flashrom识别吧。sop8转接板还没到
都弄好了,在windows下加上spispeed=36M读写速度差不多你是给你值的一半吧 MX25L3205D 。很不多了。多谢博主
彪悍的人生不需要解释,向您学习。
冒昧的问下如果用 gd32f103ret6 配合 12Mhz的晶振的板子, 怎么改程序呢。 我只改了
FLASH_SIZE = 512K
SRAM_SIZE = 64K
但是插上USB不识别。 多谢
USB D+ 有 1.5k 上拉吗?
应该是这个原因,D+ 和 板子上标 3V的地方之间电阻无穷大
usb识别了,原来我这个板子需要某个GPIO去上拉,很奇怪为什么不直接焊上上拉。 看到你重开了个新版的程序,那个对GD32支持的怎么样了呢?
你那个新版的支持GD32的程序,我改成用SPI2能读取到flash型号, 但是无法读取flash内容。Reading flash… 这里卡着不动, 而且没有建立读取的文件。
我改动的方式如下。
spi.c spi_setup函数开头增加 rcc_periph_clock_enable(RCC_GPIOB);
替换 spi.c spi.h 中的SPI1为SPI2 GPIOA 为 GPIOB
擦除操作有进度,但非常非常慢。
请问是有哪里改的不对么, 多谢
SPI的问题好像这里有说明
http://www.eeboard.com/bbs/thread-41753-1-1.html
但代码不是libopencm3的
这个是完整的stm32 gd32 移植说明, SPI部分位于 2.7
http://wenku.baidu.com/view/a2001a67763231126fdb1138.html?re=view
我也碰到了 GD32 上 SPI 的问题,不过目前暂时没时间研究。谢谢你提供的信息。
可能不是spi的问题,我发现在gd32f103上面libopencm3的最简单虚拟串口例子不能顺利运行。
https://github.com/libopencm3/libopencm3-examples/tree/master/examples/stm32/f1/stm32-maple/usb_cdcacm 就是这个例子, 具体表现为运行很短一段时间后, 回调函数cdcacm_data_rx_cb再也不被调用了。
也有人提到是gd32芯片的芯片问题 http://bbs.21ic.com/icview-724336-1-1.html
gd32烧写20151226.hex。用xtw100的驱动改了设备vid和pid可以驱动,但烧写软件不识别,可能和id有关。
目前在 GD32 上跑不起来,SPI 部分似乎不太一样。
您好,我现在用您的固件在gd上跑过,实际上用是可以用。
后来为了方便,我把用您的源代码(github上的老项目)重新建了个工程,修改了下能在spi2接口下也能用,然后无论在spi1或者spi2下(实验环境都是gd的片子,72mhz,flash用的MX25L3206E,windows),重新新建工程中,对spi和dma的配置都没有改动,vcp部分用了正点原子的枚举初始化,数据发送的endp1还是用您的代码,但是在大量的实验下有一些组实验会出现断流的现象,用bushuond看,主机发送了命令(0x13),没回复,就直接卡死在那了,单片机控制的指示忙的led灯也熄灭了,然后那次就失败了,只能关了重来。这个问题好像在提高spi速度后会有所缓解,但是还是会出现。因为对您的固件实验的次数也只有几次,暂未在您的固件上遇到这问题,所以还是不太具体清楚问题点具体在哪里,遂来请教。还有一个问题也想请教您就是,您在配置spi时用的是sck空闲是为低,第一上升沿采样,而大部分历程(包括st的demo中)都用了sck空闲是为高,第二上升沿采样,在您的配置的情况下能用,但是按大部分历程的方式就不能用,也想请问下原因是啥,谢谢。代码在这里https://github.com/posystorage/serprog-stm32-gd32
谢谢,等有时间了我仔细看一下
FLASHROM于0.99版本支持CH341A。
看来已经不需要了。
请问你那个最新的stm32-vserprog项目里电路图上那些分立元件的参数都应该取多少?我想做一个,但是(当年就没学好的)电路知识已经全还给老师了,悲催……
已在仓库中添加。
神速!多谢。
再问一下,电路图上画的是CBT6,跟文章里说的C8T6有什么区别啊?
闪存和 RAM 大小不一样。偷懒用了 CBT6 的库。实际上用的 C8T6 。没啥大区别。
楼主,你这个stm32-vserprog-v3的板子没有厂家生产销售吗?我最近想通过手机借助otg以及你这个编程器来测试看能不能用手机来给spi闪存烧录固件,但苦于没有搞到称心的编程器而没有继续折腾下去。。。
如果可以的话,我想从你这购置一个现成的试试看!
我预编译好的安卓手机端可用的上位机程序到时候用QQ发给你
支持otg功能的手机应该可以识别usb-cdc设备以及你这款编程器
哇,大佬是武汉的?我是在武汉软件工程职业学院读书,现在暑假在黄石这边社区实习,9月份开学时可以面基不?2333
现在在美国了。你可以去买块STM32F103的开发板,然后改改固件就能用了。或者可以把板子拿到淘宝上去打样,然后自己焊
我把你项目的文件和我预编译的针对安卓手机端的可执行程序打包了一下
https://drive.google.com/file/d/0ByNiLi-FgL1-UjFJaGJyTG1UcnM/view?usp=drivesdk
希望到时候手机也可以用!大佬有空的话帮我测试一下可以嘛?
最近比较忙,过两天吧
嗯嗯
不知道是否支持区块读写
谢谢你编译的安卓版本flashrom
已经用安卓4.4的手机 otg测试flashrom刷写
没有任何问题
我买的淘宝最便宜的基础开发版stm32f103c8t6
电路无需改动 飞线四根数据线 一根地线 三根3.3v 焊接一个插座 哈哈 从此安卓手机行天下编程器了
多谢了 也要感谢楼主的好项目
另外我焊接flash 的时候把WP 写保护引脚悬空了 貌似能用
板子上和LED相关的丝印有IDLE,BUSY,WPON三个,分别对应哪三种状态呀?
就绪,工作中,写保护跳线
我发现一个问题,就是楼主画的那个stm32-vserprog-v3的板子的pcb文件里没有标明主控芯片的脚位信息和焊接时的方向。。。
用的库比较垃圾,主控边上的 “ * ” 标记的是 1 脚。
今天一上手就废了块板子和一份元器件,c8t6的引脚上全是焊锡,没有风枪,能安全取下来的希望不大。。。
贴片LED在焊接时,其正负极分别对应焊盘的哪边呀?
朝右。用的库比较垃圾。。。
所有贴片LED的正极朝右还是负极朝右边焊盘呀?
负极朝右
用flymcu给主控编程失败。。。
连上去总是提示接收到7f ff ff ff…..
郁闷。。
大佬快帮帮我。。。
搞定了,原来编程器也要连电脑的usb端口才行,谢谢!
win10装了stm-vcp驱动后插上编程器,设备管理器没有显示相关设备?换句话问,这个编程器不支持windows吗?
在 Win10 下面试了下,系统自带的驱动没有问题
我这没反应。。。郁闷了
编程器闪灯吗
闪
IDLE灯在闪
USB 连接可能有问题,检查一下 pull-up
win7下装了驱动,但设备管理器里显示的是其他的未知设备,带黄色感叹号
一点扫描硬件检测改动就自动联网搜索驱动,但都提示找不到驱动程序
换了usb接口也不行
编程器正面USB接头一侧有4个贴片元器件,从上往下,其标识分别为
223
223
152
2
220 ,不是 223
你把你的原件清单发我一下吧。。基础元器件清单
我把R跟F开头的元器件标识参数列出来,C开头的我把对应参数发出来
GitHub 上有原理图
R1:标识102 参数1k
R2:标识223 参数22
R3:标识152 参数1k5
R4:标识223 参数22
R5:标识103 参数10k
R6:标识102 参数1k
R7:标识103 参数10k
R8:标识102 参数1k
R9:标识102 参数1k
F1:标识2 参数200mA
F2:标识2 参数200mA
C1:0.1u
C2: 0.1u
C3: 0.1u
C4: 22p
C5: 22p
C6: 10u
C7: 0.1u
C8: 0.1u
C9: 10u
C10: 0.1u
你帮我看下是不是有些地方的元器件需要更换一下
参数是BOM清单上的参数,标识是实际已经焊在编程器上的元器件标识
看起来没问题
R2和R4要换成标识为220的吗?另外R2跟R4的实际参数值是22欧还是22千欧呀?
22 欧
除了R2和R4要换成22欧的标识为220的贴片电阻之外还有什么其他地方需做更改呀?
应该没了
有人告诉我把那两个223电阻给短接不知道可不可行。
USB 线短的话可能可以
搞得想放弃了,烧了几百块钱,好不容易搞出来了两个编程器,到头来各种问题用不了。。
推荐你直接买10块钱的bluepill然后pullup改1.5k(r10),安装Linux主流发行版,按照作者的方法直接串口烧录或者自己用stlink v2烧录器编译一个stlink程序烧写也一样。
另外感谢作者,项目很棒很实用~
全部改好了之后如何使用这个bluepill板子连接闪存呢?具体的连线方法能否不啬赐教,谢谢!
其实,用1元pos机也可以搞定,连线非常简单,就四根数据线,两根电源线而已,推荐你上数码之家,去年就已经有成熟的固件和电路了。。。
呵呵
感谢博主分享这个好项目,与之前那个项目相比,这个版本速度稍有提升,但是稳定性不行,经常擦除完busy灯熄灭就没反应了,插拔后再刷一次才行。看了项目里的说明,可能是flashrom版本太老的缘故(测试用的096,097版本),flashrom1.0编译了几次都出错,不知道博主能否帮忙编译一个,谢谢!
猜想你的板子连线不可靠或者WP/RST线没有接软件控制。
这个编程器是不是非得接个spi闪存上去,再连上电脑才能被识别出来呀?我手边没有任何可以用来测试的spi闪存和外设,每次接到自己win10电脑上去时都没有任何动静,也装了stm32f-vcp驱动,不甘心。。。
非常不错,用10多元钱的stm32做了一个一次成功。
测试环境win7_x64+VirtualBox(ubuntu 18.04_64),使用USB xHCI模式。
为什么用xHCI 因为我测试过在其它项目中使用xHCI 模式比EHCI的通讯速度快不少。
测试芯片winbond 25Q32FVSIG (4MBye),下面的结果是多次测试取的平均值:
读:6.255秒 657KByte/s ,擦除 45.69s ,写50.10s 81.74KByte/s
补充下:
linux下的版本是flashrom1.2,自己静态编译的版本i386版本
(我发现在ub 16.04下动态编译的版本在ub18.04下尽然不能用)就索性编译了一个i386的静态flashrom。
下载地址:
http://lzdz.f3322.net:81/serprog-stm32vcp/flashrom1.2_i386_static.tar.gz
同样stm32flash也编译了一个,下载地址:
http://lzdz.f3322.net:81/serprog-stm32vcp/stm32flash_i386_static.tar.gz
windows 下也测试成功了,但是安装那个stm vcp费了点功夫,
看了帖子http://www.openedv.com/forum.php?mod=viewthread&tid=72803
才解决了stm vcp安装后驱动出现感叹号的问题
下载地址:
http://lzdz.f3322.net:81/serprog-stm32vcp/stm_vcp_usb缺少的文件.zip
stm_vcp1.4下载地址:
http://lzdz.f3322.net:81/serprog-stm32vcp/stm_VCP_1.4.zip
stm_vcp1.5下载地址:
http://lzdz.f3322.net:81/serprog-stm32vcp/stm_vcp_1.5_en.stsw-stm32102.zip
当然不会少了flashrom(别人编译的,版本1.1)下载地址:
http://lzdz.f3322.net:81/serprog-stm32vcp/flashrom_win v1.1.zip
使用方法-p serprog:dev=comX:115200,spispeed=36000000
但是我不知道怎么在win7 下计算时间,谁有办法,望告知