2013-05-04 84 views
1

首先,我在這裏按照這個教程(http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/)。Raspberry Pi:嵌入式編程練習,入門

在第一個練習中,您將瞭解如何尋址負責打開綠色好LED的GPIO引腳。我有Raspberry pi的rev C,據我所知,它使用Broadcom(BCM2835)微處理器,它的外設有以下數據表:(http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/downloads/SoC-Peripherals.pdf)。

我已閱讀數據表的第89至104頁,但仍然丟失。即使提供了交叉編譯器構建鏈,作者提供的程序似乎也不運行。條帶化的意見了由作者我所提供的源:

.section .init 
.global _start 
_start: 
    ldr r0, =0x20200000 

    /* Enable output on the 16th pin */ 
    mov r1, #1 
    lsl r1, #18 
    str r1, [r0, #4] 

    /* Turn the pin off to turn LED light on */ 
    mov r1,#1 
    lsl r1,#16 
    str r1, [r0, #40] 

loop$: 
    /* Keep the system running */ 
    b loop$ 

我在哪裏卡住了,在數據表中我看到任何關於地址0x20200000。從表6-2的91頁開始,我們看到描述前32位的表格。在表6-1中,我們看到一個寄存器描述。第一個寄存器的地址是0x7E200000。我試圖在這個地方使用這個地址,但我仍然沒有運氣讓燈亮起來。

底線LED燈不亮,所以我可以學習,我應該去哪裏獲得有關如何調試的信息?其次,我錯過了什麼?

如果它很有用,這是一個img文件的hexdump,我dd'ing到SD卡。

[email protected]:~/Devel/scripts/assembly/raspberry-pi-mini-os/example1$ make clean all 
rm -f build/*.o 
rm -f build/output.elf 
rm -f kernel.img 
rm -f kernel.list 
rm -f kernel.map 
../arm-2008q3/bin/arm-none-eabi-as -I source/ source/main.s -o build/main.o 
../arm-2008q3/bin/arm-none-eabi-ld --no-undefined build/main.o -Map kernel.map -o build/output.elf -T kernel.ld 
../arm-2008q3/bin/arm-none-eabi-objcopy build/output.elf -O binary kernel.img 
../arm-2008q3/bin/arm-none-eabi-objdump -d build/output.elf > kernel.list 
[email protected]:~/Devel/scripts/assembly/raspberry-pi-mini-os/example1$ 

hexdump -C ./kernel.img 
00000000 18 00 9f e5 01 10 a0 e3 01 19 a0 e1 04 10 80 e5 |................| 
00000010 01 10 a0 e3 01 18 a0 e1 28 10 80 e5 fe ff ff ea |........(.......| 
00000020 00 00 20 20          |.. | 

編輯
這裏是.LIST文件

00000000 <_start>: 
    0: e59f0018 ldr r0, [pc, #24] ; 20 <loop$+0x4> 
    4: e3a01001 mov r1, #1 ; 0x1 
    8: e1a01901 lsl r1, r1, #18 
    c: e5801004 str r1, [r0, #4] 
    10: e3a01001 mov r1, #1 ; 0x1 
    14: e1a01801 lsl r1, r1, #16 
    18: e5801028 str r1, [r0, #40] 

0000001c <loop$>: 
    1c: eafffffe b 1c <loop$> 
    20: 20200000 .word 0x20200000 

如果顛倒你看到了排隊與.LIST文件hexdump都的字節序。

e59f0018 
e3a01001 
e1a01901 
e5801004 
e3a01001 
e1a01801 
e5801028 
eafffffe 
20200000 
+0

@dwelch一秒重新啓動,我會把它給你。 – 2013-05-04 19:12:24

+0

我仍然困惑常量去了哪裏,嘗試改變ldr r0,= 0x2020000兩行mov r0,#0x20000000; orr r0,r0,#0x00200000 – 2013-05-04 19:35:19

+1

broadcom文檔描述了gpio,您將看到包含外設的內存空間從0x7E000000開始,映射到0x20000000處的ARM內存空間。所以0x7E20000的外設是arm內存空間的地址0x20200000。 – 2013-05-04 19:37:11

回答

3

從原理圖(以及在哪裏找到的代碼,你的鏈接頁面)GPIO 16連接到狀態指示燈

我在哪裏卡住時,在數據表中我看到避談地址 0x20200000

事實並非如此時,BCM手冊第6頁:

物理地址範圍從0×20 000000至0x20FFFFFF用於外設。外設的總線地址被設置爲映射到從0x7E000000開始的外設總線地址範圍。因此,這裏在總線地址0x7Ennnnnn處公佈的外設可用於 物理地址0x20nnnnnn。

隨着稱取從例如程序0x20200000變得0x7E200000是GPIO寄存器的信息,

具體0x7E200004是GPFSEL1

爲GPFSEL1的描述中提到了位模式001使得銷的輸出,並且它顯示該寄存器中gpio 16的位是18-20位,因此我們希望將位模式001置於位18,因此1寫入0x7E200004

40十進制是28十六進制,所以第二個感興趣的寄存器是0x7E200028這是GPCLR0

GPCLRn說明說,如果設置了一位,則會清除gpio輸出。因此,寫一個1 < < 16到那個寄存器來將輸出拉到零,這導致LED導通

然後進入一個無限循環,所以沒有其他事情發生(到/從ARM)。

你的十六進制文件(更新/編輯)很好。你想在SD卡上或者至少在第一個分區的根目錄下的唯一文件是bootcode.bin和從http://github.com/raspberrypi的固件目錄的start.elf不需要/從那裏獲得任何其他文件。你的二進制文件kernel.img也在SD卡上。沒有其他的。插上SD卡,插上樹莓派。如果它不能正常工作,請拔下並重新插入(有可能發生的緩存事件),並且應該第二次運行。如果這不起作用,重新分區和重新格式化SD卡,然後再試一次,我曾經發生過多次的事情,以防止SD卡在樹莓派中工作。

編輯:

下來,你可能會碰到麻煩的鏈接描述顯然是建立你的二進制的道路上地址爲0x0000,而不是爲0x8000爲基礎。您可以將一個config.txt文件放在sd卡的根目錄中,並且在一行允許傳統內核模式的行內,或者告訴GPU將kernel.img加載到地址0x0000而不是0x8000的地方,或者修改鏈接器腳本.text(和其他所有內容)從0x8000開始。具體的OK01示例程序恰好是位置獨立的,因此它可以從任何地址運行,所以最小的三個文件(bootcode.bin,start.elf,kernel.img)將起作用。