如何為BBB製作cape(或:如何在系統啟動時自動載入dtbo)
阿新 • • 發佈:2019-01-08
原文地址:bbs.eeworld.com.cn/thread-432698-1-1.html,感覺有用先存著,感謝作者分享!
如果你買來BBB是為了搞跟硬體相關的專案,那你八成需要製作一個cape。cape是BBB官方的叫法,其實就是指BBB的軟體和硬體外設。通過學習device tree我們瞭解到BBB是使用capemgr和device tree來控制cape的,通過向$SLOTS傳入dtbo檔案來載入某個cape,像這樣:
- echo BB-ADC > $SLOTS
要做到開機自動啟動,你只需要增加一個eeprom(官方推薦的型號是CAT24C256),並把它接到特定的引腳上,裡面寫上符合規定格式的內容就行了。系統在啟動時會檢查特定引腳上有沒有符合規定格式的eeprom,如果有的話,就按照eeprom裡面的內容自動載入相應的dtbo檔案。
還記得我們 cat $SLOTS 看到了什麼嗎?
- cat /sys/devices/bone_capemgr.*/slots
- 0: 54:PF---
- 1: 55:PF---
- 2: 56:PF---
- 3: 57:PF---
- 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
- 5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
二、eeprom的連線
這裡的知識比較零散,我將分點闡述:
- eeprom的地址必須在0x54到0x57之間,否則系統不會載入。
- eeprom必須連線到BBB的I2C2_SCL和I2C2_SDA引腳上(在系統中看到的是i2c-1)。因為I2C2這兩個引腳的預設功能就是i2c功能。這也告訴我們,程式中儘量不要永久改變這兩個引腳的功能複用,否則就沒法載入cape了。
- BBB最多隻支援同時插4個eeprom,它們的地址必須互不相同。
- 如果一次插入多個eeprom,會依次讀取之。準確來說,讀取順序就是從0x54到0x57的順序。為什麼如此強調overlay的載入順序呢?因為一旦前面載入的overlay佔用了某些片上資源,其他overlay就不能再用了。比如我要做的LCD使用的引腳跟預設載入的HDMI用的引腳是有重疊的,當系統啟動時首先載入了LCD的overlay,那麼HDMI就不能再載入了。
- eeprom上WP引腳是防寫用的,一旦上拉,就不能進行寫入了。所以自己做電路的時候可以把它懸空或者拉低。
三、eeprom的讀寫
下面先介紹如何進行讀寫,再介紹該寫入什麼東西。
首先確定eeprom的地址。由A0,A1,A2三個引腳的電平確,按照上面剛剛說的,比如我把A0,A1接地,A2拉高,地址就是0x54。
然後在命令列操作:
- cd /sys/bus/i2c/devices/1-0054/ #到eeprom目錄中
- cat eeprom | hexdump -C #讀取eeprom內容並以字元形式顯示
- echo -e "\xaa\x55\x33\xeeA1Beaglebone LCD4 Cape\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0000A1BeagleboardToys\x00BB-BONE-LCD4-01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" > eeprom #寫入內容
- cat eeprom | hexdump -C #確認是否寫入成功
寫入內容時,要按照SRM裡的標準(如下圖),最重要的是要把頭6個位元組\xaa\x55\x33\xeeA1以及後面的版本號00A1和要呼叫的dtbo檔名BB-BONE-LCD4-01寫對,其他的比Number of Pins什麼的都無所謂。空餘的地方必須用\x00補全,用其他字元會產生錯誤。
經過上面的方法配置好eeprom後,系統就能在啟動時自動載入對應的dtbo檔案了。但是這裡還是再強調一下dts檔案編寫的注意事項。
四、編寫dts檔案的注意事項
- 檔名必須是 boardname-version.dts 的形式,比如 BB-BONE-LCD4-01-00A0.dts。這裡面BB-BONE-LCD4-01就是boardname,00A0就是version號。(其實dts的名字無所謂了。。關鍵是編譯出來的dtbo名字必須是它,為了統一,就都這麼規定吧)。
- version必須是00AX的形式,X從0開始按版本依次增加,而且,想命名00A1,必須有00A0的存在才行!不能跨越版本!
- dts檔案裡面會有part-number和version這兩項,其內容必須跟檔名相符!part-number就是boardname。
- 編譯完的dtbo檔案必須放到 /lib/firmware/ 目錄中才可以載入。
OK,上面介紹了所有cape通用的內容。具體某個cape需要載入特定的驅動,那就是如何寫dts檔案和配置驅動的問題了,在此就不做討論啦。
五、其實不用eeprom也能做——uEnv.txt
其實不用eeprom的話,也可以通過修改uEnv.txt檔案來實現自動載入dtbo檔案。USB連線好BBB以後在電腦裡會出現一個碟符,裡面有一個叫做uEnv.txt的檔案。通過它可以設定系統啟動時載入或禁止載入的dtbo。比如我想在系統啟載入BB-ADC。我們就可以開啟它,在下面新增一行:
- optargs=quiet capemgr.enable_partno=BB-ADC
我們知道BBB啟動會自動載入HDMI,而HDMI與LCD公用了部分引腳。如果我們想啟動後再插上LCD,然後 echo BB-BONE-LCD4-01 > $SLOTS 來載入LCD cape的話,會提示你File exists,就是因為HDMI已經首先載入了,那些引腳就不能再動了。但我們可以配置uEnv.txt使得啟動時不自動載入HDMI,方法是在uEnv.txt中新增一行:
- optargs=quiet capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN
注意,如果想同時實現上面兩個,即禁用HDMI並載入ADC的話,不能簡簡單單把上面兩句話寫進去,應該合併成一句話:
- optargs=quiet capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN capemgr.enable_partno=BB-ADC
所以,使用eeprom的意義就在於方便啦。什麼也不用配置,買回來插上就能用。如果你愛折騰的話,那麼實現方法就多了去啦。
六、其實不用eeprom也能做——systemd
上面說的修改uEnv.txt的方法其實跟用eeprom的效果是差不多的——一個不能用的話另一個也不能用= =!
6月的Angstrom系統(終端輸入 uname -a 檢視你的BBB裡裝的是哪個版本的系統)有bug,如果你自己編譯了一個dtbo檔案,即便放進 /lib/firmware 目錄下也不能自動載入(/lib/firmware裡原本就有的可以載入是因為它們已經被編譯進核心了)。所以除非你自己編譯一遍系統,否則不能用這個辦法在啟動時自動載入自己的cape。剛說了用uEnv.txt跟用eeprom差不多……所以也不行。
9月的Angstrom系統稍微修改了這個bug,但還是不好用——系統啟動時會在載入cape那步停留60秒才繼續……本來Angstrom是以啟動速度快見長的,只需10秒。這一下拖了太多後腿了。(而且9月的Angstrom系統增添了新的bug——LCD電阻觸控式螢幕指標會漂移!想自己解決這個問題當然依舊只能重新編譯系統——不是每個人都有耐心編譯系統玩的!所以即便它是新系統,我還是果斷使用6月的吧,至少觸控式螢幕正常。)
總之,無論哪個版本的Angstrom系統,eeprom和uEnv.txt法都不太好使,下面就介紹一個完全不同的招數:使用systemd。
Step by step教學:
Step 1.
在/etc/systemd/system目錄下新建一個檔案,命名mystartup.service(名字可以自定),內容如下:
- [Unit]
- Description=My script
- [Service]
- ExecStart=/home/root/mystartup.sh
- [Install]
- WantedBy=multi-user.target
注意:不能寫成ExecStart=/bin/sh /path/to/script.sh這樣的,直接按上面給出的例子寫就好了。
Step 2.
然後在 /home/root 目錄新建一個mystartup.sh,內容如下:
- #!/bin/sh
- echo BB-YOUR-CAPE > /sys/devices/bone_capemgr.8/slots
1、這裡必須用sh指令碼,不能用bash指令碼。
2、sh指令碼中不能使用bone_capemgr.*這樣的萬用字元,必須是bone_capemgr.8或者.9(根據你的系統來寫)
3、當然,dtbo檔案還是必須得放在 /lib/firmware 下才行。
Step 3.
最後執行命令:
- systemctl enable myscript.service
如果你執行dmesg | grep capemgr,會發現載入dtbo的時間點跟用eeprom或uEnv.txt不同,所以跟啟動以後手動輸入 echo 命令的效果類似。
七、結束
我當然推薦第六種方法。預計在找到更好的辦法之前,這就是我將來在Development Kit裡採用的辦法了。想要使用我的Kit的話建議掌握這個小技巧。
最後這句寫給能看懂的人,看不懂就不必深究了:crontab @reboot 在BBB的Angstrom裡不好使,不用嘗試了。似乎會被系統kill掉。