2012-02-04 115 views
10

我想要得到一個'你好世界'類型的程序運行在我的Beagleboard-xm rev。 C,通過從程序集調用C puts函數。你好世界,裸機Beagleboard

到目前爲止,我一直在使用這個作爲參考:http://wiki.osdev.org/ARM_Beagleboard

這裏是我到目前爲止,但沒有輸出。

的hello.c

volatile unsigned int * const UART3DR = (unsigned int *)0x49020000; 

void puts(const char *s) { 
    while(*s != '\0') { 
    *UART3DR = (unsigned int)(*s); 
    s++; 
    } 
} 

void hello() { 
    puts("Hello, Beagleboard!\n"); 
} 

boot.asm

.global start 
start: 
    ldr sp, =stack_bottom 
    bl hello 
    b . 

linker.ld

ENTRY(start) 

MEMORY 
{ 
    ram : ORIGIN = 0x80200000, LENGTH = 0x10000 
} 

SECTIONS 
{ 
    .hello : { hello.o(.text) } > ram 
    .text : { *(.text) } > ram 
    .data : { *(.data) } > ram 
    .bss : { *(.bss) } > ram 
    . = . + 0x5000; /* 4kB of stack memory */ 
    stack_bottom = .; 

} 

Makefile文件

ARMGNU = arm-linux-gnueabi 

AOPS = --warn --fatal-warnings 
COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding 

boot.bin: boot.asm 
    $(ARMGNU)-as boot.asm -o boot.o 
    $(ARMGNU)-gcc-4.6 -c $(COPS) hello.c -o hello.o 
    $(ARMGNU)-ld -T linker.ld hello.o boot.o -o boot.elf 
    $(ARMGNU)-objdump -D boot.elf > boot.list 
    $(ARMGNU)-objcopy boot.elf -O srec boot.srec 
    $(ARMGNU)-objcopy boot.elf -O binary boot.bin 

只需使用ASM文件中像這樣的作品。

.equ UART3.BASE,  0x49020000 
start: 
    ldr r0,=UART3.BASE 
    mov r1,#'c' 

這裏有一些的BeagleBoard /小型機相關信息:http://paste.ubuntu.com/829072/

任何指針? :)


我也試過

void hello() { 
    *UART3DR = 'c'; 
} 

我使用的小型機,並通過YMODEM發送的文件,然後我試圖與運行:

go 0x80200000 

硬件和軟件控制minicom中的流量關閉。

回答

3

應該爲您工作。下面是一些代碼,我從回來的路上挖出來的時候,沒有嘗試,只是確定它編譯,它在同一時間工作了的BeagleBoard今晚...

的Startup.s:

.code 32 

.globl _start 
_start: 

    bl main 
hang: b hang 

.globl PUT32 
PUT32: 
    str r1,[r0] 
    bx lr 

.globl GET32 
GET32: 
    ldr r0,[r0] 
    bx lr 

你好。C:

extern void PUT32 (unsigned int, unsigned int); 
extern unsigned int GET32 (unsigned int); 
void uart_send (unsigned char x) 
{ 
    while((GET32(0x49020014)&0x20)==0x00) continue; 
    PUT32(0x49020000,x); 
} 
void hexstring (unsigned int d) 
{ 
    //unsigned int ra; 
    unsigned int rb; 
    unsigned int rc; 

    rb=32; 
    while(1) 
    { 
     rb-=4; 
     rc=(d>>rb)&0xF; 
     if(rc>9) rc+=0x37; else rc+=0x30; 
     uart_send(rc); 
     if(rb==0) break; 
    } 
    uart_send(0x0D); 
    uart_send(0x0A); 
} 
int main (void) 
{ 
    hexstring(0x12345678); 
    return(0); 
} 

MEMMAP(連接腳本):

MEMORY 
{ 
    ram : ORIGIN = 0x82000000, LENGTH = 256K 
} 

SECTIONS 
{ 
    ROM : { startup.o } > ram 
} 

的Makefile:

CROSS_COMPILE = arm-none-eabi 

AOPS = --warn --fatal-warnings 
COPS = -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding 

all : hello.bin 

hello.bin : startup.o hello.o memmap 
    $(CROSS_COMPILE)-ld startup.o hello.o -T memmap -o hello.elf 
    $(CROSS_COMPILE)-objdump -D hello.elf > hello.list 
    $(CROSS_COMPILE)-objcopy hello.elf -O binary hello.bin 

startup.o : startup.s 
    $(CROSS_COMPILE)-as $(AOPS) startup.s -o startup.o 

hello.o : hello.c 
    $(CROSS_COMPILE)-gcc -c $(COPS) hello.c -o hello.o 

clean : 
    rm -f *.o 
    rm -f *.elf 
    rm -f *.bin 
    rm -f *.list 

看起來像我剛離開堆棧指針的地方引導程序有它。同樣,與您一樣,假設引導加載程序已初始化串行端口。

我假設你有串口訪問工作,你看到uboot,你可以鍵入命令,以便下載這個程序(xmodem,或其他)到電路板內存中?如果你不能這樣做,那麼它可能是你沒有連接到串行端口的權利。 beagleboards的串口很擰,可能需要製作自己的電纜。

+0

它的工作原理,謝謝。現在我需要弄清楚我做錯了什麼。這是第一塊代碼!= ASM,它實際上打印了一些東西。 – farnsworth 2012-02-05 11:26:43

+0

如果有人對此有任何疑問,請參閱此處。我修改了Makefile CROSS_COMPILE = arm-none-linux-gnueabi,因爲我正在使用linux的codesourcery toolchain。使用loady通過ymodem加載文件,而de memmap有它的原點在0x82000000我去agead並運行它與去0x80200000即使您將原點設置爲0x82000000。 – farnsworth 2012-02-05 11:28:45

+0

arm-none-linux-gnueabi和arm-none-eabi都來自codesourcery,如果你不做任何系統調用,那麼兩者都可以工作。據推測,如果你使用gcclib調用(使用除法或模或類似的東西),非linux版本會更好。 – 2012-02-05 11:52:51

2

你不能盲目地寫一串字符到UART - 你需要檢查每個字符的狀態 - 它在單個字符的例子中工作,因爲UART總是準備好第一個字符,但對於需要輪詢的第二個和隨後的角色(或者更好地使用ISR,但是在我們運行之前讓我們走)。

這裏也有一些很好的例子代碼在這裏:http://hardwarefreak.wordpress.com/2011/08/30/some-experience-with-the-beagleboard-xm-part-2/

+0

退房的LE做到了這一點。我也嘗試打印只有一個字符,我沒有得到任何輸出,好文章將檢查它是否解決問題,但我真的想知道我做錯了什麼,在哪裏。 – farnsworth 2012-02-04 18:23:11

+0

也許試試從上面給出的鏈接運行代碼,看看是否有效?如果它確實有效,那麼你可以與你的代碼進行比較,看看有什麼不同? – 2012-02-04 18:25:39

+0

嘗試過,不起作用。 – farnsworth 2012-02-04 18:41:08

2

我已經沒有足夠的repetation評論... 但我的answere到

仍然可以正常工作。現在奇怪的是,我可以用uart_send('c')打印個別 字符,但不能打印 字符串print_string(char * str){while(* str!='\ 0')uart_send (* STR ++); } print_string(「Test」); 。對此有何想法?

是:

你寫在輸出緩衝速度更快,因爲UART能夠發送.. 所以,你要檢查,如果輸出緩衝器是空的,你發送一個新的字符之前。

我的代碼在我的博客(http://hardwarefreak.wordpress.com/2011/08/30/some-experience-with-the-beagleboard-xm-part-2/

+0

我這樣做:),我也已經移動到.text文本但沒有在屏幕上,除非我做print_char('c'); – farnsworth 2012-02-06 14:22:35

+0

Mmh ..是否啓用中斷? 我可以看到您的代碼並與我的對比嗎? – Hardwarefreak 2012-02-06 14:33:36

+0

對不起,我搞砸了開始的地址,謝謝你的時間和你的偉大榜樣:) – farnsworth 2012-02-06 15:05:50