單片機
返回首頁

s3c2440學習之路-004 區分nand/nor 啟動

2021-09-09 來源:eefocus

硬件平臺:jz2440

軟件平臺:Ubuntu16.04 arm-linux-gcc-3.4.5

源碼位置: https://github.com/lian494362816/C/tree/master/2440/005_leds/002


1.原理分析

1.1問題的由來

前面篇文章 https://blog.csdn.net/lian494362816/article/details/84642425 提到了SP的設置,但是當使用nand flash 和 nor flash啟動時,2440內部的sram位置是不同的, SP的設置也不同。使用nor flash時,內部sram起始位置為0x40000000, 而使用nand flash時,內部sram起始位置為0x00000000。為了更好的使用,需要讓代碼區分nand 還是nor啟動。總不能準備2份代碼, 一份給nor使用,一份給nand使用吧。

在這里插入圖片描述

在這里插入圖片描述

1.2 解決方法

編程時,可以根據nor flash的特性和2440在使用nand flash啟動時的特性來區分是nor 啟動還是nand啟動。


如果是nor 啟動, 2440會直接從nor flash 去讀指令,如果是nand 啟動,2440會把nand 前4K的內容拷貝到sram里面,從內部的sram去讀取指令。


nor flash是可以隨意讀取數據的,但是如果需要往nor flash里面寫數據,則需要先發送一些特殊的命令才可以,所以說nor flash是可以隨意讀但是不可以隨意寫。但是內部的sram是可以隨意讀寫的。


2主要流程

根據前面提到的2點,可以在程序一開始往0地址寫一個數據(特殊一點即可,這里寫0),再讀取0地址的數據。


如果是nor 啟動,應該會寫失敗(寫必須先發特定命令),所以再次讀取0地址的數據不等于之前所寫的數據。


如果是nand啟動,因為程序是在內部的sram運行(2440自動把nand 數據拷貝到sram),所以寫是會成功的,再次讀取0地址的數據就等于之前所寫的數據。

在這里插入圖片描述

3源碼

start.s


.global _start

_start:


    /* aoto switch nand or nor flash */

    /* write 0 to address[0] and read it

     * if address[0] is equal 0, it is nand

     * because nand can wirte easy, but nor need send

     * write-commond before wirte data, so write 0 to

     * nor address[0] will fail, and get nor address[0]

     * data is not equal 0

     */

    mov r1, #0

    ldr r0, [r1] /* r0=[0] store address[0] data*/

    str r1, [r1] /* 0->[0] */

    ldr r2, [r1] /* r2=[0] */

    cmp r1, r2

    ldr sp, =0x40000000 + 4096/* for nor */

    ldreq sp, =4096  /* for nand */

    streq r0, [r1] /* recover address[0] data */


    /* stop watch dog */

    ldr r0, =0x53000000

    mov r1, #0

    str r1, [r0]


    bl main


loop:

    b loop


匯編代碼流程很簡單

1)把R1賦值為0

2)將0地址數據保存到R0

3)往0地址寫0

4)把0地址數據讀到R2

5)SP先設置為0x40000000+ 4096

6)如果R2等于R1, 即R2=0,那么說明是nand啟動, SP設置成4096

7)把R0的值寫回0地址


這里不需要擔心,萬一程序一開始0地址的數據就是0,那么在往0地址寫0再取出來,就會誤被判定為成功。 程序最終會編譯成機器碼, 而機器碼組成的指令有特定的格式,不會出現一條指令全是0組成。 通過反匯編可以知道,程序的第1條指令就是“ mov r1, #0”, 這條指令的機器碼是e3a01000, 所以0地址的值,一開始不會等于0。

在這里插入圖片描述

led_on.c


int main(void)

{

    int i = 0;

    /* clear mode */

    GPFCON &= ~((3 << 8) | (3 << 10) | (3 << 12));

    /* set to output mode */

    GPFCON |= ((1 << 8) | (1 << 10) | (1 << 12));

    /* all led off */

    GPFDAT |= (7 << 4);


    while (1)

    {

        GPFDAT |= (7 << 4);

        GPFDAT &= ~(i << 4);

        i++;


        if (8 == i)

        {

            i = 0;

        }

        delay(100000);

    }


    return 0;

}


main函數是寫做一個流水燈的功能, 具體的細節不說,因為今天主要講的是區分nand flash 和nor flash。把這份代碼分別燒到nand 和 nor 都可以正常啟動,并讓流程燈跑起來,但是會發現流水燈的執行速度不一樣。


燒到nand 會執行的更快一點, 因為使用nand時,程序是跑在內部的sram里面,而使用nor時,程序要從外部的nor flash讀取數據,因此會偏慢一點。

進入單片機查看更多內容>>
相關視頻
  • TI 新一代 C2000? 微控制器:全方位助力伺服及馬達驅動應用

  • MSP430電容觸摸技術 - 防水Demo演示

  • 直播回放: Microchip Timberwolf? 音頻處理器在線研討會

  • 新唐 8051單片機教程

  • 基于靈動MM32W0系列MCU的指夾血氧儀控制及OTA升級應用方案分享

  • 基于靈動MM32SPIN系列MCU的無感FOC便攜冰箱應用方案分享

    相關電子頭條文章
萝卜大香蕉