程序在nor flash中真的可以運行嗎?


     程序在nor flash中可以運行,但是是有限制的,它不能像RAM那樣隨意的寫(盡管它可以隨意的讀)。在norflash上,不能運行寫存儲器的指令,不過排除寫的地方是RAM類。實驗中的三個文件如下所示:
Makefile如下:

led_on.bin : crt0.S leds.c
 arm-linux-gcc -g -c -O2 -o crt0.o crt0.S
 arm-linux-gcc -g -c -O2 -o leds.o leds.c
 arm-linux-ld -Ttext  0x0 crt0.o leds.o  -o led_on_elf
 arm-linux-objcopy -O binary -S led_on_elf led_on.bin
 arm-linux-objdump -D -m arm  led_on_elf > led_on.dis
clean:
 rm -f led_on.dis led_on_elf *.o led_on.bin 


crt0.S如下:

@******************************************************************************
@ File:crt0.S
@ 功能:通過它轉入C程序
@*****************************************************************************      
.text
. global _start
_start:
            ldr     r0, = 0x53000000     @ WATCHDOG寄存器地址
            mov     r1, # 0x0                     
            str     r1, [r0]        @ 寫入0,禁止WATCHDOG,否則CPU會不斷重啟
            ldr     sp, = 0x00001000     
            bl      main                @ 調用C程序中的main函數
halt_loop:
            b       halt_loop
leds.c如下所示:

#define GPBCON      (*(volatile unsigned long *)0x56000010)
#define GPBDAT      (*(volatile unsigned long *)0x56000014)
/*
 * LED1,LED2,LED4對應GPB5、GPB6、GPB7、GPB8
 
*/
#define GPB5_out (1<<(5*2))
#define GPB6_out (1<<(6*2))
#define GPB7_out (1<<(7*2))
#define GPB8_out (1<<(8*2))
void  wait( volatile unsigned  long dly)
{
  for(; dly >  0; dly--);
}
int main( void)
{
 unsigned  long i =  0;
  //  LED1,LED2,LED4對應的4根引腳設為輸出
 GPBCON = GPB5_out | GPB6_out | GPB7_out | GPB8_out;
  while( 1){
  wait( 30000);
  GPBDAT = (~(i<< 5));   //  根據i的值,點亮LED1,2,3,4
   if(++i ==  16)
   i =  0;
 }
  return  0;
}


    實驗結果:這樣的代碼編譯出來的程序在steppingstone(SRAM)中可以運行,但是下載到norflash中不能運行。
    修改代碼:
crt0.S如下:

@******************************************************************************
@ File:crt0.S
@ 功能:通過它轉入C程序
@*****************************************************************************      
.text
. global _start
_start:
            ldr     r0, = 0x53000000     @ WATCHDOG寄存器地址
            mov     r1, # 0x0                     
            str     r1, [r0]        @ 寫入0,禁止WATCHDOG,否則CPU會不斷重啟
            ldr     sp, = 0x40001000     
            bl      main                @ 調用C程序中的main函數
halt_loop:
            b       halt_loop


實驗結果:這樣的代碼編譯出來的程序在norflash中可以運行。


原因分析:
由於要跳轉到main()函數中去執行,即C函數中去,就需要使用堆棧。代碼“ldr     sp, =0x00001000”由於使用堆棧的地址位於norflash中,而當跳轉到main()函數中去執行時,就會寫norflash,而norflash不能像RAM那樣隨意寫,所以不能成功執行。代碼“ldr     sp, =0x40001000”由於使用堆棧的地址是0x40001000,使用的是(0x40000000—0x40001000),即是S3C2440的片內SRAM。這樣跳轉到main()函數時,用到的     就是片內SRAM,所以能夠成功執行。


寫內存的時機:
程序在運行過程中大多時候是在讀內存,例如取指令、加載數據等等,寫內存的時機大概這么幾種情況:
1.寫特殊功能寄存器(其實這個可以排除出去)
2.修改全局變量的值
3.講數據壓入堆棧保存。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM