天天看點

linux點亮led程式,嵌入式linux------編寫C語言程式點亮led燈

使用c語言替代彙編的原理也是往寄存器位址寫數值,通路寄存器位址和通路記憶體是一樣的。給出C語言程式:

int main()

{

unsigned int *pGPFDAT = (unsigned int*)0x56000050;

unsigned int *pGPFCON = (unsigned int*)0x56000054;

*pGPFDAT = 0x400;

*pGPFCON = 0;

return 0;

}

對于main函數的調用:

.text

.global _start

_start:

ldr sp,=4096

//ldr sp,=0x40000000+4096

bl main

halt:

b halt

其中bl表示在棧中調用main函數,傳回值給到halt中。ldr是兩種啟動的程式複制到的最開始的位址。

燒寫oflash  xxx.bin

0  1  0  0  0

測試。

原理分析:

start.S 可以用來設定棧,因為c函數要使用,儲存局部變量和lr等寄存器。同時調用者還可以向被調用者傳參數和接受傳回值。

為了使C語言和彙程式設計式之間能夠互相調用,必須為子程式間的調用指定規則,在ARM處理器中這個規則被稱為ATPCS:ARM程式和Thumb程式中子程式調用規則。基本的ATPCS規則包括寄存器使用規則、資料棧使用規則、參數傳遞規則。ARM處理器中有r0-15共16個寄存器,r0到r3用來參數傳遞,r4到r11可能在函數中被使用,是以在函數入口儲存,在函數的出口恢複。

對Nand啟動來說,硬體上會把nand flash前4k的内容完全拷貝的片内的4k記憶體,如何區分是哪種啟動?

// 設定記憶體:sp棧

ldr sp,=4096  

ldr sp,=0x40000000+4096

是以分辨的方方法就是寫0到0位址再讀出來,如果得到0表示nand flash啟動:

mov r1,#0 //給r1指派為0

ldr r0,[r1] //把原來0位址的值取出來備份給r0

str r1,[r1] //給0位址寫入0

ldr r2,[r1] //把0位址再讀出來

cmp r1,r2 //比較讀出來的數值r2是不是0

ldr sp,=0x40000000+4096 //預設當成nor啟動調到sp

moveq sp,#4096 //如果r1等于r2的話,說明是nand flash啟動

streq r0,[r1] //再把備份的r0數值放回到0位址中