人人做人人澡人人爽欧美,国产主播一区二区,久久久精品五月天,羞羞视频在线观看免费

當前位置:蘿卜系統 > 網絡技術教程 > 詳細頁面

小米路由器如何向spi中寫入文件,BootLoader莫得了

小米路由器如何向spi中寫入文件,BootLoader莫得了

更新時間:2023-08-22 文章作者:未知 信息來源:網絡 閱讀次數:

網絡故障(network failure)是指由于硬件的問題、軟件的漏洞、病毒的侵入等引起網絡無法提供正常服務或降低服務質量的狀態。

它是做什么用的?

手邊有兩個路由器,一個是小米r3gv2(磚狀,沒有BootLoader),另一個是Phicomm K3(磚狀,nand閃存中的BootLoader也不可用)。對于小米路由器,請焊接spi閃存,然后,只需使用編程器將其閃爍即可。對于PHICOMM K3,SPI閃光墊也保留在PCB上。您可以更改SPI引導,然后將CFE(一種BootLoader)閃存到nand閃存中。

不幸的是,由于這種流行病,程序員并沒有被運送出去,所以我想了很久,最后想到我可以使用具有SPI功能的可編程設備來制作程序員。至于如何將文件寫入spi,是不是sscom?您可以直接通過串行端口發送文件,然后在Arduino中創建一個串行端口以接收SPI寫入。

SPI閃存

有許多SPI閃存,GD或Winbond品牌,其中大多數是8PIN,可以在路由器和機頂盒中隨處可見。小米路由器使用128Mbit(16M)。以winbond為例,命名為W25QXX,圖片如下:

在這里插入圖片描述

不同品牌的此類芯片在引腳定義和讀取命令方面幾乎兼容。在Arduino Mega 2560中,默認情況下SPI引腳為50、51、52和53。

在這里插入圖片描述

SPI讀寫

spi閃存的基本特征之一是必須在寫入之前將其擦除。被擦除的位置是0xFF。在編寫SPI Flash的過程中,我們主要使用的是讀取ID(檢查程序是否正確),芯片擦除,頁面編程(寫入數據)和數據讀。〝祿炞C)三個命令。

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

程序功能功能

#include 
#define WB_WRITE_ENABLE       0x06
#define WB_WRITE_DISABLE      0x04
#define WB_CHIP_ERASE         0xc7
#define WB_READ_STATUS_REG_1  0x05
#define WB_READ_DATA          0x03
#define WB_PAGE_PROGRAM       0x02
#define WB_JEDEC_ID           0x9f
//打印256字節的數據(16x16)
void print_page_bytes(byte* page_buffer) {
    char buf[10];
    for (int i = 0; i  16; ++i) {
        for (int j = 0; j  16; ++j) {
            sprintf(buf, "x", page_buffer[i * 16 + j]);
            Serial.print(buf);
        }
        Serial.println();
    }
}
void get_jedec_id(void) {
    Serial.println("command: get_jedec_id");
    byte b1, b2, b3;
    _get_jedec_id(&b1, &b2, &b3);
    char buf[128];
    sprintf(buf, "Manufacturer ID: xh\nMemory Type ID: xh\nCapacity ID: xh",
        b1, b2, b3);
    Serial.println(buf);
    Serial.println("Ready");
}
void chip_erase(void) {
    Serial.println("command: chip_erase");
    _chip_erase();
    Serial.println("Ready");
}
void read_page(unsigned int page_number) {
    char buf[80];
    sprintf(buf, "command: read_page(xh)", page_number);
    Serial.println(buf);
    byte page_buffer[256];
    _read_page(page_number, page_buffer);
    print_page_bytes(page_buffer);
    Serial.println("Ready");
}
void read_all_pages(void) {
    Serial.println("command: read_all_pages");
    byte page_buffer[256];
    for (int i = 0; i  4096; ++i) {
        _read_page(i, page_buffer);
        print_page_bytes(page_buffer);
    }
    Serial.println("Ready");
}
void _get_jedec_id(byte* b1, byte* b2, byte* b3) {
    digitalWrite(SS, LOW);
    SPI.transfer(WB_JEDEC_ID);
    *b1 = SPI.transfer(0xFF); // manufacturer id
    *b2 = SPI.transfer(0xFF); // memory type
    *b3 = SPI.transfer(0xFF); // capacity
    digitalWrite(SS, HIGH);
}
void _chip_erase(void) {
    digitalWrite(SS, LOW);
    SPI.transfer(WB_WRITE_ENABLE);
    digitalWrite(SS, HIGH);
    delay(10);
    digitalWrite(SS, LOW);
    SPI.transfer(WB_CHIP_ERASE);
    digitalWrite(SS, HIGH);
    delay(10);
    digitalWrite(SS, LOW);
    SPI.transfer(WB_WRITE_DISABLE);
    digitalWrite(SS, HIGH);
    not_busy();
}
void _read_page(word page_number, byte* page_buffer) {
    digitalWrite(SS, LOW);
    SPI.transfer(WB_READ_DATA);
    SPI.transfer((page_number >> 8) & 0xFF);
    SPI.transfer((page_number >> 0) & 0xFF);
    SPI.transfer(0);
    for (int i = 0; i  256; ++i) {
        page_buffer[i] = SPI.transfer(0xFF);
    }
    digitalWrite(SS, HIGH);
    not_busy();
}
void _write_page(word page_number, byte* page_buffer) {
    digitalWrite(SS, LOW);
    SPI.transfer(WB_WRITE_ENABLE);
    digitalWrite(SS, HIGH);
    delay(10);
    digitalWrite(SS, LOW);
    SPI.transfer(WB_PAGE_PROGRAM);
    SPI.transfer((page_number >> 8) & 0xFF);
    SPI.transfer((page_number >> 0) & 0xFF);
    SPI.transfer(0);
    for (int i = 0; i  256; ++i) {
        SPI.transfer(page_buffer[i]);
    }
    digitalWrite(SS, HIGH);
    
    digitalWrite(SS, LOW);
    SPI.transfer(WB_WRITE_DISABLE);
    digitalWrite(SS, HIGH);
    not_busy();
    
}
uint8_t read_status(void)
{
    digitalWrite(SS, LOW);
    SPI.transfer(WB_READ_STATUS_REG_1);
    uint8_t data = SPI.transfer(0xFF);
    digitalWrite(SS, HIGH);
    return data;
}
void not_busy(void) {
    while (read_status() & 0x01)
    {
        delay(1);
    }
}

極路由1s flash_flash怎么編程復制元件_編程器刷路由器flash

串行端口將數據轉發到SPI

每次讀取一個字節,但讀取速度要慢256個字節,然后通過spi寫入閃存,然后通過指定文件大小來確定閃存是否結束。少于一頁的剩余數據為0xFF。由于某些BootLoader文件的末尾為0xFF,因此您可以指定文件大小以提前結束寫入過程,從而節省時間。可以通過winhex查看要寫入的二進制文件。

寫入頁面后,請閱讀此頁面并檢查寫入的數據。如果出現錯誤,程序將返回并停止運行。

由于是從串行端口逐字節讀取的,因此串行端口的波特率不應太大,否則會丟失數據。 9600bps更合適。調試時,您可以將FILE_SIZE更改為256,并刪除打印頁面數據上的注釋。

如果沒有問題,請使用通過sscom發送文件的功能。擦除芯片幾秒鐘后,單擊發送文件,串行端口將輸出當前寫入頁面的序列號。

#define FILE_SIZE 524288 //512KB
void setup()
{
    SPI.begin();
    SPI.setDataMode(0);
    SPI.setBitOrder(MSBFIRST);
    digitalWrite(SS, HIGH);
    Serial.begin(9600);
    Serial.println("Ready");
    init_printf();
    not_busy();
    get_jedec_id();
    chip_erase();
    while (Serial.read() > 0);
}
void loop()
{
    if (!writed && Serial.available() > 0) 
    {
        bytes++;
        page[currentPos] = Serial.read();
        currentPos++;
        if (currentPos == 256) 
        {
            Serial.println("Receive Page:" + String(currentPage));
            //print_page_bytes(page);
            _write_page(currentPage, page);
            delay(10);
            byte page_temp[256];
            _read_page(currentPage, page_temp);
            //Serial.println("Read Page:" + String(currentPage));
            //print_page_bytes(page_temp);
            for (int k = 0; k  256; k++)
            {
                if (page_temp[k] != page[k])
                {
                    Serial.println("Error!");
                    return;
                }
            }
            if (bytes >= FILE_SIZE)
            {
                writed = true;
                Serial.println("WRITE FINISH!!!");
            }
            memset(page, 0xFF, 256 * sizeof(byte));
            currentPos = 0;
            currentPage++;
        }
        else if (bytes >= FILE_SIZE)
        {
            Serial.println("Receive Page:" + String(currentPage));
            //print_page_bytes(page);
            _write_page(currentPage, page);
            delay(10);
            byte page_temp[256];
            _read_page(currentPage, page_temp);
            //Serial.println("Read Page:" + String(currentPage));
            //print_page_bytes(page_temp);
            for (int k = 0; k  256; k++)
            {
                if (page_temp[k] != page[k])
                {
                    Serial.println("Error!");
                    return;
                }
            }
            writed = true;
            Serial.println("WRITE FINISH!!!");
        }
    }
    if (writed)
    {
        Serial.read();
    }
}

如果遇到不正確的寫入數據,隨機錯誤,重復錯誤或很多0x00,則問題的80%是電壓。我使用3. 3V,操作GD Flash沒問題。編寫Winbond Flash。它不能被寫入,并且閱讀混亂。然后,在擦除閃存之后,切斷芯片的電源,并且寫入就可以了。


本文來自本站,轉載請注明本文網址:
http://www.pc-fly.com/a/tongxingongju/article-372886-1.html


當今,越來越多的業務應用運行于網絡架構之上,保障網絡的持續、高效、安全的運行,成為網絡管理者面臨的巨大挑戰。

溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統下載排行

網站地圖xml | 網站地圖html
主站蜘蛛池模板: 邯郸市| 南乐县| 延寿县| 布尔津县| 北川| 德州市| 榆树市| 长春市| 噶尔县| 辽阳市| 马尔康县| 榆中县| 厦门市| 扎赉特旗| 永州市| 温宿县| 连平县| 浑源县| 电白县| 乌苏市| 普定县| 汾西县| 辽宁省| 资中县| 德清县| 五台县| 利川市| 佛冈县| 监利县| 陕西省| 深圳市| 阳江市| 扬州市| 莱州市| 卓资县| 连南| 潍坊市| 达孜县| 扎鲁特旗| 故城县| 巩义市|