极路由1S(HC5661A)刷breed刷错了,身边没有编程器写flash芯片(型号25Q128CS),因此就萌生了使用Arduino作为编程器的想法

参考了ZLBG这篇文章写得很不错

都是标准ISP协议,其他flash可以参考读写

电路图请参考ZLBG的博客文章,我贴一下Arduino接线

Arduino代码如下:

/*communication with W25Q80BV (1 MBYTE SPI FLASH) using Arduino Pro Mini 3.3V/8MHzReference: http://www.instructables.com/id/How-to-Design-with-Discrete-SPI-Flash-Memory/?ALLSTEPSReference2: http://www.cnblogs.com/zlbg/p/4246721.html
*/// the SPI bus uses pins 10 (SS), 11 (MOSI), 12 (MISO), and 13 (SCK)/**
* 使用Arduino作为编程器将uboot写入flash(EEPROM)
* 注意uboot不要超过芯片存储容量
* 理论上支持所有EEPROM
*
* 测试机型:极路由1S(HC5661A),刷入breed
*/#include <SPI.h>#define READ_JEDEC_ID 0x9F
#define READ_STATUS_1 0x05
#define READ_DATA 0x03
#define WRITE_ENABLE 0x06
#define PAGE_PROGRAM 0x02
#define CHIP_ERASE 0xC7// uboot最后四个字节,用于判断写入已经结束
// 我们可以使用winhex打开uboot文件查看最后四个字节
static char END_CHARS[4] = {0x3B, 0x54, 0x05, 0x10};void setup()
{SPI.begin();SPI.setDataMode(SPI_MODE0);SPI.setBitOrder(MSBFIRST);Serial.begin(115200);ReadID();
    // 擦除flashEraseChip();Serial.println("inited");
}// 检测是否写入完成,当最后四个字节和结束字节一样的时候写入结束
bool isEnd(char check[4]) {if (check[0] == END_CHARS[0] && check[1] == END_CHARS[1] && check[2] == END_CHARS[2] && check[3] == END_CHARS[3]){return true;}return false;
}char buffer[64];        // 串口一次最多64字节
char page[256];         // eeprom每页有256字节
int currentPos = 0;     // 当前页当前位置
int currentPage = 0;        // 当前页数
bool writed = false;        // 写入完成标记
bool start = false;     // 开始写入标记
bool printed = false;       // 写入完成之后打印完成标记
void loop() {if(!writed && Serial.available() > 0) { // 如果写入未完成我们继续读取串口if(!start) {start = true;Serial.println("start write");}int size = Serial.readBytes(buffer, 64);if(size >= 0) {if(size == 64) {if(currentPos + size == 256) {      // 当读取恰好满一页时候我们写入flash一页for(int i=0; i<64; i++) {page[currentPos + i] = buffer[i];}WritePage(currentPage, page, 256);memset(page, 0, 256*sizeof(byte));currentPos = 0;currentPage++;// 这个时候要判断是不是末尾,是的话我们完成写入操作char check[4] = {page[252], page[253], page[254], page[255]};if(isEnd(check)) {Serial.println("WRITE FINISH!!!");writed = true;}} else {for(int i=0; i<64; i++) {page[currentPos + i] = buffer[i];}currentPos += 64;}} else {        // 如果读取不足一页证明已经到文件末尾了,这个时候数据要全部写入flashfor(int i=0; i<size; i++) {page[currentPos + i] = buffer[i];}WritePage(currentPage, page, currentPos + size);memset(page, 0, 256*sizeof(byte));currentPos = 0;currentPage++;// 完成写入操作Serial.println("WRITE FINISH!!!");writed = true;}// 每次读完串口缓冲都要清零memset(buffer, 0, 64*sizeof(byte));}}// 写完而且未打印时候我们把flash里面数据按页读出来// 我们可以复制黏贴串口调试助手里面的16进制数据到winhex// 然后保存到一个文档和原uboot作对比看看写入是否正确if(writed && !printed) {for(int i=0; i<currentPage; i++) {ReadPage(i, page, 256);for(int i = 0; i < 256; i++){Serial.print(char(page[i]));}memset(page, 0, 256*sizeof(byte));delay(20);}printed = true;}
}void CheckBusy()
{digitalWrite(SS, HIGH);digitalWrite(SS, LOW);SPI.transfer(READ_STATUS_1);while(SPI.transfer(0) & 0x01); digitalWrite(SS, HIGH);
}void ReadID()
{digitalWrite(SS, HIGH);digitalWrite(SS, LOW);SPI.transfer(READ_JEDEC_ID);byte manuID = SPI.transfer(0);byte memoType = SPI.transfer(0);byte capa = SPI.transfer(0);digitalWrite(SS, HIGH);Serial.print("Manufacturer ID: "); Serial.println(manuID, HEX);Serial.print("Memory Type: "); Serial.println(memoType, HEX);Serial.print("Capacity : "); Serial.println(capa, HEX);CheckBusy();
}void ReadPage(word pageNumber, char pageBuffer[], int length)
{// pageNumber: 16-bit datadigitalWrite(SS, HIGH);digitalWrite(SS, LOW);SPI.transfer(READ_DATA);SPI.transfer((pageNumber >> 8) & 0xFF);SPI.transfer(pageNumber & 0xFF);SPI.transfer(0);for(int i = 0; i < length; i++){pageBuffer[i] = SPI.transfer(0);}digitalWrite(SS, HIGH);CheckBusy();
}void WritePage(word pageNumber, char pageBuffer[], int length)
{digitalWrite(SS, HIGH);digitalWrite(SS, LOW);  SPI.transfer(WRITE_ENABLE);digitalWrite(SS, HIGH);digitalWrite(SS, LOW);  SPI.transfer(PAGE_PROGRAM);SPI.transfer((pageNumber >>  8) & 0xFF);SPI.transfer(pageNumber & 0xFF);SPI.transfer(0);for(int i = 0; i < length; i++){SPI.transfer(byte(pageBuffer[i]));}digitalWrite(SS, HIGH);CheckBusy();
}void EraseChip()
{digitalWrite(SS, HIGH);digitalWrite(SS, LOW);  SPI.transfer(WRITE_ENABLE);digitalWrite(SS, HIGH);digitalWrite(SS, LOW);  SPI.transfer(CHIP_ERASE);digitalWrite(SS, HIGH);CheckBusy();
}

接线完成之后打开串口调试助手sscom32,当串口显示begin时候选择breed文件发送到Arduino,Arduino会写到flash,写完之后会读取flash刚刚写入的数据到串口调试助手,这样子我们可以对比写入是否正确。

注意:写入之前建议备份flash,自己写read保存吧我就不写了

另外需要写入对应起始地址的话也需要自行修改


可惜最后还是没有救活,我焊工太差了电路板挂了

Arduino作为编程器读写BIOS、bootloader、uboot或者breed相关推荐

  1. 使用Arduino ISP编程AVR微控制器和Arduino开发板

    所有微控制器都需要某种机制来对它们进行编程,即使它们只编程一次.通常,程序代码写在主机上,然后编译或翻译,并使用电缆(通常是USB或RS232)将对象(机器可读)代码从PC("主机" ...

  2. 360路由器v2刷第三方固件_路由器不拆闪存,编程器刷机技巧,恢复出厂固件办法...

    前面写文章介绍了,品胜云路由刷breed第三方引导程序办法.文章中也介绍了,备份编程器办法,用winhex截取art路由器校准文件办法.编程器刷机时,正常的办法是把闪存芯片取下,放到编程器上读取编程器 ...

  3. USBISP/USBasp编程器给Atmega32U4下载Arduino bootloader引导程序

    用USBISP/USBasp编程器给ATmega32U4下载Arduino bootloader引导程序 ATmega32U4 bootloader引导程序是什么 引导程序下载接口与连接 配置熔丝位与 ...

  4. 用Arduino做SPI FLASH的编程器

    用来干什么 手上有两个路由器,一个小米的r3gv2(已砖,BootLoader莫得了),一个斐讯K3(已砖,nand闪存内的BootLoader也莫得了),对于小米的路由器,把spi flash焊下来 ...

  5. Arduino 控制RFID读写器读写 IC卡

    Arduino 控制RFID读写器读写 IC卡 一.IC卡的认识   IC卡可以通过频段进行划分,低频(125KHz~134kHz,典型工作频率是12KHz).高频(13.56MHz)和超高频(860 ...

  6. msi计算机主板,整套解决方案:MSI主板BIOS编程器_计算机硬件和网络_IT /计算机_信息...

    通常,当我们谈论BIOS时,我们指的是主板的BIOS系统,那么BIOS在哪里? BIOS是计算机的基本输入输出系统(Basic Input-Output System,基本输入输出系统),它是主板上集 ...

  7. linux dd 备份uboot,刷机前如何备份uboot、分区、编程器固件?路由器刷机备份命令使用方法...

    为安全着想,刷机前应该备份一下原机uboot 或者最好能备份出完整的编程器固件,以防万一. 可我手上没有ttl,听说可以通过后台来备份各个分区,于是我就试了试,但是遇到不少问题,理解不了,请各位指教. ...

  8. FlashPro2000.C2000.TDS510.TI编程 器支持大部分TI芯片读写2812.28335等

    FlashPro2000.C2000.TDS510.TI编程 器支持大部分TI芯片读写2812.28335等

  9. MW150R3Gv1 AR9331 8M OpenWrt编程器固件 不si的uboot

    转载:http://forum.anywlan.com/thread-223353-1-1.html 分享 MW150R3Gv1 8M OpenWrt编程器固件,uboot带httpd恢复模式 测试机 ...

  10. 和硕GT640显卡编程器BIOS

    和硕GT640 4G显卡编程器BIOS 主控:NVIDIA GF106-i50-A1 显卡缓存:三星(SAMSUNG)256M*16贴 BIOS链接:https://download.csdn.net ...

最新文章

  1. iOS 应用程序的启动流程及其代理
  2. 手把手教你从系统层面优化深度学习计算
  3. c语言地理坐标存储 转发,纬度/经度坐标的2个列表之间的地理距离
  4. python文件读取 ,json文件的存储
  5. STm32 使用 stm32cube GPIO 点亮 led 的
  6. python输出数字和字符串_(一)1-5Python数字和字符串
  7. ASP.NET 封装JS文件到DLL中并在页面中调用
  8. Spring Data Jpa使用篇
  9. 【简单易上手】姓氏头像制作生成头像组合微信小程序源码下载
  10. java实现QQ空间日志列表获取
  11. 文件搜索工具ProFind for Mac
  12. 【实用软件】多功能游戏工具箱-Watt Toolkit
  13. 提示BeanPostProcessorChecker:is not eligible for getting processed by all BeanPostProcessors的原因
  14. 微信小程序开发之——用户登录-搭建开发者服务器(2)
  15. 包含新房二手房租房功能的房产小程序开发方案
  16. SQL语句——基础篇
  17. 2020.7.22英谷实训日志
  18. Python numpy.corrcoef函数方法的使用
  19. Android动态权限详解
  20. 中国食物链?(看不上,看不起,瞧不起,狗眼看人低)

热门文章

  1. 劝学篇翻译软件测试,汪洙《神童诗劝学篇》原文与译文
  2. php revel,golang,revel_Revel 的路由问题,golang,revel - phpStudy
  3. vscode使用angular
  4. X310系列USRP使用LAN口MATLAB控制方法
  5. 对公司的建议_工作总结
  6. [Egret学习笔记 二]MovieClip的使用
  7. 公告栏模板php代码,destoon调用自定义模板及样式的公告栏
  8. python读取文件夹下所有图片并重命名_python 对文件夹下图片 批量重命名
  9. 堆载预压弹性变形怎样计算公式_支架载荷计算公式
  10. 如何简单的将中文翻译为英文