Arduino作为编程器读写BIOS、bootloader、uboot或者breed
来源:互联网 发布:四知文言文阅读答案 编辑:程序博客网 时间:2024/06/06 20:02
极路由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/8MHz Reference: http://www.instructables.com/id/How-to-Design-with-Discrete-SPI-Flash-Memory/?ALLSTEPS Reference2: 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();
// 擦除flash EraseChip(); 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 { // 如果读取不足一页证明已经到文件末尾了,这个时候数据要全部写入flash for(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 data digitalWrite(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保存吧我就不写了
另外需要写入对应起始地址的话也需要自行修改
可惜最后还是没有救活,我焊工太差了电路板挂了
0 0
- Arduino作为编程器读写BIOS、bootloader、uboot或者breed
- BIOS、BootLoader、uboot对比
- BIOS、BootLoader、uboot对比
- 斐讯k1路由器刷Breed BootLoader(不死UBoot)
- 【整理】BIOS、BootLoader、uboot对比
- 【整理】BIOS、BootLoader、uboot对比
- 【整理】BIOS、BootLoader、uboot对比
- Bootloader和BIOS、Grub、uboot概念
- Arduino烧录bootloader,并作为ISP进行下载程序
- bootloader/ uboot
- bootloader---27.uboot中SD初始化及读写分析
- 斐讯 PSG1208 K1 免拆机刷breed 不死uboot
- 使用arduino作为programer对新的mcu烧录bootloader
- 浅谈arduino的bootloader
- Arduino烧写bootloader
- 浅谈arduino的bootloader
- Bootloader VS BIOS
- BSP、BIOS、Bootloader介绍
- 安卓开发中文乱码
- SqlServer 表数据统计,相同属性的汇总到一列,并用逗号隔开
- PAT (Top Level) Practise 1007 Red-black Tree (35)
- JavaScipt学习中的高阶函数
- 排序算法
- Arduino作为编程器读写BIOS、bootloader、uboot或者breed
- VNC view 连接后闪退
- 23种设计模式详解(Java示例)->适用于所有OO语言
- Runloop 理解
- 公司用的读文件,写文件,追加文件内容,删除文件
- hadoop系列文档2-hdfs文件系统命令诠释
- 机器学习笔记(二)——多变量最小二乘法
- Faster R-CNN是如何添加ROIPoolingLayer和SmoothL1LossLayer的?
- BZOJ 1996 HNOI 2010 chorus 合唱队 区间DP