第一部分是玩pcduino3下的裸機,這個過程可以讓我們更好的理解嵌入式系統,熟悉我們使用的這個平台。
首先介紹下開發環境:
虛擬機器:VMware? Workstation 10.0.2 build-1744117
系統:Linux slackware 3.2.29-smp #2 SMP
交叉編譯器:arm-linux-gnueabihf- 版本號碼:gcc version 4.8.2 20130805 (prerelease) (crosstool-NG linaro-1.13.1-4.8-2013.08 - Linaro GCC 2013.08)
編輯器:Vim
硬體串連如下:
USB 5V電源線和USB轉TTL線串連到pcduino3上,
說是流水燈,其實我只用到兩個燈,這個板子的LED不多,並沒有專門的流水燈配置。我們下看一下原理圖:
我僅僅用到TX_LED和RX_LED兩個燈:
我們用到這裡的TX和RX兩個燈,重新回到原理圖看看哪兩個管腳來控制這兩個LED的:
PH15和PH16分別控制TX_LED和RX_LED。
在弄清楚硬體串連後,在正式編寫彙編代碼之前,我們先理清A20的boot順序,根據其datasheet上簡潔的介紹,它支援mmc啟動,也支援nand flash啟動,並且mmc啟動優先於nand flash啟動。A20的datasheet並沒有詳細寫出boot的硬體細節,大概的估摸出大概步驟如下:mmc啟動條件下,硬體會自動將mmc卡中位於位移量在8K和40K之間的資料搬移到內部的SRAM1和SRAM2中:
現在的uboot支援spl方式,就是位於前32k的部分首先在SRAM中運行,然後初始化DRAM和MMC介面,然後再搬移後續的uboot到記憶體中運行,再進行載入kernel的操作。
除了這一點,還要注意,MMC啟動時需要加上特定的頭,這裡我們要用到uboot/tools裡面的mksunxiboot工具加這個頭。這個頭由32個位元組的結構體boot_file_head定義,這個結構體裡面有MAGIC和check sum。然後產生一條跳轉代碼來跳轉到真正地代碼處進行執行。
代碼分為兩個彙編檔案:start.S和led.S。start.S設定棧指標,然後就跳到led.S中的主函數中。
start.S代碼如下:
.text.global _start_start:ldr sp, =0x00007f00blmainhalt_loop:bhalt_loop
led.S如下:
.equPH_CFG1, 0x01C20900.equPH_CFG3, 0x01C20904.equPH_PULL0, 0x01C20918.equPH_PULL1, 0x01C2091C.equPH_DAT, 0x01C2090C.global mainmain:ldrr0,=PH_CFG1ldr r1,=0x10000000strr1, [r0]ldrr0,=PH_CFG2ldr r1,=0x00000001strr1, [r0]ldrr0,=PH_PULL0ldrr1,=0x55555555strr1, [r0]ldrr0,=PH_PULL1ldrr1,=0x55555555strr1, [r0]ledloop:ldrr0,=PH_DATldrr1,=0x000f0000strr1, [r0]bl delayldrr0,=PH_DATldrr1,=0x0000f000strr1, [r0]bl delaybledloopdelay:ldrr3,=0xfffffdelay1:subr3,r3,#1cmpr3,#0x0bnedelay1mov pc,lr
代碼很簡單,編譯完後記得使用mksunxiboot工具處理一下,最後使用dd命令燒寫到8K位移處。
最後就可以看到兩個燈一閃一閃亮晶晶了,現在還沒有初始化時鐘,注意調整延時,不然效果不大對。