這個項目差點就爛尾了...
這個項目不是什么很牛逼的大項目,是一個基于全志的一款SOC的項目。中間遇到過不少問題,差點就爛尾了,索性最后堅持下來了。
起源
這次為什么要做這個小項目呢?
因為去年剛學(xué)了一下一個開源的EDA軟件 —— KiCad。然后為了練一下手,所以就一時興起打算做一個Linux小板;開始畫PCB,買物料,自己焊接,不亦樂乎,不過中間也有很多辛酸。
因為大家知道,一般的SOC,因為產(chǎn)品尺寸有要求,集成度很高,所以通常是BGA封裝,另外片外還需要加ddr和emmc,就是ram和rom了,同樣的,這兩者往往也是BGA封裝,所以焊接難度也很大;
于是我就在想,有沒有對我這樣的手殘黨友好一點的方案呢?
然后我找了一段時間,后來想起之前網(wǎng)上老外的一個項目 linux business card的一個項目,看了一下是全志的F1C100S,內(nèi)置32M的ddr,有lqfp和qfn的封裝,可以外接spi的nor flash或者從sd進行啟動。


這?簡直是手殘黨的福音啊。
第一版的時候,我用Kicad畫好原理圖和PCB,還用keyshot很裝逼地渲染了一下PCB,雖然效果差強人意,但是自我感覺逼格比之前高了很多;
下面是第一版PCB的效果的視頻;
首戰(zhàn)失利
不知道為什么腦子抽了一下,直接采購的是qfn封裝的芯片,強行給游戲增加了難度;然后買了一個廉價的熱風(fēng)槍(可以吹出300℃—450℃熱風(fēng)的設(shè)備);
春節(jié)在家是極其簡陋的焊接環(huán)境,就開干了;
順便說一下焊錫絲里是含有鉛的,這幾天手工焊電路板,聞多了,感覺都要提前變成老年癡呆了;

實際焊了一些QFN的芯片,感覺也不是很難,先用電烙鐵在焊盤上涂上錫,然后用風(fēng)槍吹一下就好了,后面再補錫,防止有的地方虛焊;
焊好了第一塊電路板,只焊好了電源管理部分,還有主芯片,然后問題就來了;

芯片需要三路電源,3.3V,2.5V,1.1V;
3.3V是系統(tǒng)電源,2.5V是給內(nèi)部DDR供電的,1.1V是IO電源;
然后我測試的時候發(fā)現(xiàn),在焊上主芯片之后,2.5V電源的輸出就是0V;
奇怪的是,我把主芯片拆下來,這三路電壓輸出又恢復(fù)正常了,因為我是先把電源部分的電路焊好的,并且測試輸出正常之后,才焊的芯片;
我懷疑可能這部分沒有焊好,存在引腳的虛焊或者連焊;
之后,我又做了兩塊板子,發(fā)現(xiàn)原來的問題還是存在。
到底是什么問題呢?這期間也有請教了一些硬件方面的大佬,也嘗試了很多的測試方法,好幾次心灰意冷。
后面又調(diào)試了一段時間,沒有實質(zhì)性的進展,決定放棄當(dāng)前版本。
準(zhǔn)備改版;

屢敗屢戰(zhàn)
中間擱置了一段時間后,重新設(shè)計了第二版的PCB,我把原來的PMIC方案換了,參考開源的荔枝派,直接單芯片輸出三路3.3V,2.5V和1.1V
順便板子顏色換成了藍色,總體感覺比綠色和黑色的阻焊漆更好;
工欲善其事必先利其器,順便還改善了一下工作環(huán)境,接下來就繼續(xù)戰(zhàn)斗吧。第二次次焊起來比第一次順手多了;

不過在調(diào)試PMIC的時候,使用萬用表測量輸出電壓,不小心把一個地方弄短路了,導(dǎo)致一個電感短到3.3V上,直接燒毀冒煙了。
內(nèi)心很慌,后來排查了并不是硬件設(shè)計上的問題,終于三路輸出的電壓都正常了,長舒一口氣,也算是一個小插曲。
下一步就是燒錄固件了,板子接到電腦上,板子是作為usb device,電腦作為host。
板子這邊是usb otg的接口(既可以作為device,也可以作為host),usb的引腳一般包括VCC,GND,D+和D-,還有一個usb_id;
usb_id根據(jù)引腳的上下拉,來區(qū)別當(dāng)前的工作狀態(tài)(是host還是device);通常作為usb device時候,這個引腳要進行上拉,作為主機的時候,要進行上拉;
不巧的是,我默認給板子的usb_id下拉了,所以,通過sunxi-tool去枚舉usb設(shè)備的時候,就出現(xiàn)了錯誤提示;

沒有辦法,最后經(jīng)過飛線,可以成功識別到USB設(shè)備了;

最終焊完的板子,背面貼了一塊屏幕;

后面,編譯了一份uboot,但是燒寫的時候又出問題了,提示usb傳輸錯誤,這下可把我難道了,心中的猜測:
硬件的問題,然后把flash的引腳都補錫補了一遍,主芯片的spi接口引腳用烙鐵刮了一遍,然后重新補了一下錫,確保沒有虛焊和連焊,然后,問題依然沒有解決; 軟件的問題,排查了libusb的問題,我先后在Linux上重新安裝了這個庫,依然沒有解決這個問題;順便在Windows系統(tǒng)重新搭建了測試環(huán)境,依然存在問題。
我陷入了困境,并且不知道如何解決這個問題,差點爛尾。
當(dāng)時想過要放棄:“這個版本如果再不行,這個項目就不搞了”。
然后我安慰自己,再嘗試一下別的辦法,說不定就解決了。
于是我測試了PMIC的輸出,3.3V,這是實際只有3.1V—3.2V左右,然后懷疑:會不會電壓太低造成的呢?
抱著疑問,調(diào)了一下DCDC的電阻,改變了一下電源的輸出,穩(wěn)定在3.4V左右;歪打正著,經(jīng)過測試,發(fā)現(xiàn)問題就這樣解決了,后面工作都比較穩(wěn)定。
于是可以正常燒錄固件了;

系統(tǒng)移植
硬件的坑才是大問題,移植方面因為有不少開源的案例,所以也相對比較輕松;
總結(jié)一下是四個步驟;
環(huán)境搭建; uboot的移植;linux kernel的移植;文件系統(tǒng);
燒錄uboot,就是要把程序燒寫到flash中,絕大多數(shù)都是從 0 地址開始執(zhí)行;
對于大部分的 SoC 而言,芯片執(zhí)行其內(nèi)部的固化 i-bootloader 之后就會從外部的 flash 來執(zhí)行 bootloader,然后就芯片就會執(zhí)行我們所燒錄的 uboot 了。
這個是uboot正常燒錄之后的串口終端輸出的log,還沒有燒kernel;

uboot是芯片最開始會執(zhí)行的程序,比如x86的電腦的BIOS,差不多的道理;不過芯片內(nèi)部都會固化一段啟動代碼,F(xiàn)1C100S也不例外;

uboot啟動之后,就要開始啟動內(nèi)核了;
這里簡單介紹一下bootargs 和 bootcmd ;
bootcmd一般都會包含 bootm 或者 bootz 指令 ;
bootz:因為kernel和rootfs都保存在flash中,所以要先將他們搬運到ram中; bootm:搬運完之后開始啟動內(nèi)核;
然后根據(jù)bootargs這個環(huán)境變量,向內(nèi)核傳遞參數(shù);
參考如下;
bootargs=console=ttyS0,115200 panic=5 rootwait root=/dev/mtdblock3 rw rootfstype=jffs2
其中
console=ttyS0,115200:表示控制臺終端定向到串口0,波特率為115200;
panic=5:表示傳遞參數(shù)錯誤的時候,程序會進入死循環(huán),并在5秒后重啟內(nèi)核;
rootwait:表示是讓內(nèi)核進入無限等待,因為啟動時間無法預(yù)估,就讓內(nèi)核無限等待直到啟動完成;
root=/dev/mtdblock3:表示文件系統(tǒng)掛載到mtd設(shè)備的分區(qū)3上;
rw:表示當(dāng)前文件系統(tǒng)是可讀可寫的;
rootfstype=jffs2:文件系統(tǒng)類型,在配置內(nèi)核時選擇支持該類型;kernel啟動成功了,但是文件系統(tǒng)也掛載成功了,但是沒有成功,提示
/bin/sh exists but couldn't execute it

用buildroot編譯的根文件系統(tǒng),上面的問題在我努力排查下也順利解決了,主要是rootfs中的文件沒有可執(zhí)行權(quán)限;



總結(jié)
整體過程還是很好玩的,雖然遇到意料之外的問題很虐心,但是問題一個個解決之后,感覺還是很棒,因為做這個東西不需要取悅?cè)魏稳耍约嚎鞓肪托辛耍凰裕瑒谫Y屏幕就先不調(diào)了。
最后,無論是生活中,還是工作中,難免都會遇到困難和挫折,不要輕易放棄,堅持到最后,一定能成功,共勉!!!

