本文章為《STM32MP157 Linux系統(tǒng)移植開發(fā)篇》系列中的一篇,筆者使用的開發(fā)平臺為華清遠見FS-MP1A開發(fā)板(STM32MP157開發(fā)板)。stm32mp157是ARM雙核,2個A7核,1個M4核,A7核上可以跑Linux操作系統(tǒng),M4核上可以跑FreeRTOS、RT-Thread等實時操作系統(tǒng),STM32MP157開發(fā)板所以既可以學嵌入式linux,也可以學stm32單片機。
針對FS-MP1A開發(fā)板,除了Linux系統(tǒng)移植篇外,還包括其他多系列教程,包括Cortex-A7開發(fā)篇、Cortex-M4開發(fā)篇、擴展板驅動移植篇、Linux應用開發(fā)篇、FreeRTOS系統(tǒng)移植篇、Linux驅動開發(fā)篇、硬件設計篇、人工智能機器視覺篇、Qt應用編程篇、Qt綜合項目實戰(zhàn)篇等。
?
1.系統(tǒng)鏡像燒寫
FS-MP1A支持通過STM32CubeProgrammer工具鏡像鏡像的燒錄,此外還支持通過bootloader下的ums工具配合ubuntu操作系統(tǒng)進行單個鏡像更新,通過使用tftp下載方式進行鏡像的驗證,以及使用scp方式來更新linux內核與設備樹。
2.STM32CubeProgrammer燒寫方式
STM32CubeProgrammer工具已經在前面的章節(jié)進行了安裝,現在我們可以通過使用這個工具來燒錄系統(tǒng)。
2.1調整撥碼開關
在開發(fā)板上電之前我們需要先將開發(fā)板的撥碼開關撥到【000】位置。
?

?
2.2硬件接線
在使用USB方式燒寫鏡像時,需要借助USB mini線來進行數據傳輸,此外還可以通過串口終端來監(jiān)視燒寫過程。
?

?
2.3調試串口配置
在燒寫過程中可以通過調試串口來監(jiān)控燒寫過程,串口調試可以借助XSHELL來進行相關調試,XSHELL已經在前面章節(jié)安裝完成,這里只需要配置一下相關串口即可。
雙擊桌面上的“XSHELL 6”圖標打開。
?

?
開啟xshell后在自動彈出的對話框中單擊“新建”按鈕。
?

?
在“新建會話屬性”中“協(xié)議(P)”中選擇“SERIAL”,名稱可以自定義。
?

?
下面需要對串口進行配置。首先需要確定串口在系統(tǒng)中的COM口是哪個端口??梢栽谠O備管理器中查找。
?

?
可以看到這里的串口為“COM3”
下面點擊xshell界面中左側的“串口”按鈕。
?

?
選擇端口號為“COM3”(需要根據當前實際環(huán)境選擇),波特率為:115200,數據位:8,停止位:1,奇偶校驗:無,流控制:無。
?

?
配置好之后點擊“確定”按鈕。將看到如下界面。
?

?
先選中剛剛新建的COM選項后點擊“連接”。
?

?
看到如上界面則說明打開成功。
2.4鏡像燒寫
首先打開桌面上的STM32CubeProgrammer軟件
?

?
軟件打開后將出現如下界面
?

?
如果在打開軟件之前開發(fā)板已經處于上電狀則可以看到右上角的USB設備。
?

?
如果沒有看到“USB1”端口,可將開發(fā)板重新上電或者按開發(fā)板的復位按鈕,之后點擊Port后的“刷新”按鈕。
出現USB1端口后點擊左上角的“Connect”按鈕進行連接。
連接成功后上方原來為“Not connected”字樣變?yōu)椤癈onnect”
?

?
下面開始導入燒寫鏡像。首先需要進入到鏡像所在目錄【華清遠見-FS-MP1A開發(fā)資料\06-系統(tǒng)鏡像\fs-mp1a-weston-openstlinux】。
?

?
再進入“flashlayout_fs-mp1a-weston”文件夾。此文件夾中存放的是鏡像燒錄配置。
?

?
可以看到共有4個文件夾,本小節(jié)只關注optee和trusted兩個文件夾。每個文件夾中都有如下兩個配置文件。
?

?
其中標有 “emmc”字樣的為片上flash燒錄配置,“sdcard”字樣的為外部TF卡燒錄配置;此外還可以看到文件名最后有 “trusted”和“optee”后綴。這對應這不同的啟動模式 “trusted”和“optee”為帶有安全機制的啟動方式。
這里以emmc的“trusted”啟動為例來進行燒錄。
將“flashlayout_fs-mp1a-weston\trusted”文件夾中的“FlashLayout_emmc_stm32mp157a-fsmp1a-trusted.tsv”配置文件復制一份到上層目錄下。
?

?
切換到STM32CubeProgrammer軟件中,點擊“Open file”選項卡
?

?
找到燒寫鏡像所在目錄,打開剛剛復制過去的燒錄配置文件。
?

?
點擊“打開”后界面如下
?

?
檢查Binaries Path路徑是否為燒錄配置文件所在的路徑,如果不是同一路徑需要手動修改。
點擊界面右上角的“Download”按鈕進行燒錄。在串口終端中首先將如下打印信息。
?

?
STM32CubeProgrammer軟件中將會看到進度條,燒錄過程會持續(xù)幾分鐘請耐心等待。
?

?
燒寫成功后會出現以下提示
?

?
至此通過STM32CubeProgrammer方式燒錄emmc trusted鏡像就完成了。后面就可以通過改變撥碼開關為【010】來進行系統(tǒng)的啟動。
?

?
2.5燒錄錯誤處理
如果在燒錄rootfs出現如下錯誤
?

?
此問題是由于STM32CubeProgrammer需要使用64bit的java jre。如果系統(tǒng)中安裝的版本為32bit則會出現此問題。
如果在控制面板中將查看方式修改為“大圖標”后看到有Java(32位)則說明當前系統(tǒng)安裝的java環(huán)境為32位。
?

?
此時我們需要卸載系統(tǒng)中的32位的java環(huán)境,然后安裝資料光盤中的【華清遠見-FS-MP1A開發(fā)資料\01-工具軟件】下的jre-8u261-windows-x64.exe程序。安裝完成后將原來安裝的STM32CubeProgrammer程序卸載,重新安裝一遍STM32CubeProgrammer即可。
3.制作TF卡系統(tǒng)卡
前面章節(jié)已經介紹了通過STM32CubeProgrammer工具來燒錄鏡像,這一章節(jié)將介紹如何通過USB Image Tool工具來制作TF系統(tǒng)卡。
將【華清遠見-FS-MP1A開發(fā)資料\01-工具軟件】下的usbit.zip壓縮包復制到PC的任意位置點擊右鍵選擇“解壓到usbit”。
?

?
得到如下文件夾
?

?
雙擊運行“USB Image Tool.exe”會顯示如下界面
?

?
如果該界面沒有正確顯示出盤符,則需要參“將GPT分區(qū)轉換為MBR分區(qū)”和“MBR創(chuàng)建分區(qū)及格式化”章節(jié)對TF進行重新分區(qū)。
資料中【華清遠見-FS-MP1A開發(fā)資料\06-系統(tǒng)鏡像】下默認提供optee、trusted兩種已經編譯好的weston鏡像。
?

?
在USB Image Tool界面中選擇“Favorites”選項卡
?

?
點擊“Add”按鈕添加一個鏡像,找到鏡像所在目錄,文件類型選擇All files(*.*)。
?

?
這里以trusted鏡像為例選擇flashlayout_fs-mp1a-weston_FlashLayout_sdcard_stm32mp157a-fsmp1a-trusted.raw鏡像進行燒錄。
?

?
點擊“打開”按鈕后。在“Favorites”選項卡中選中剛剛添加的鏡像。
?

?
點擊“Restore”按鈕后會彈出對話框詢問是否要繼續(xù)操作,我們選擇“是”
?

?
可以在界面的左下方看到當前的進度。
?

?
燒錄完成后就可以將撥碼開關撥至【101】來啟動系統(tǒng)。
?

?
4.通過ums方式映射分區(qū)
當我們編譯了自己的一些鏡像后,需要將其下載到開發(fā)板中運行的時候,可以使用此方式將開發(fā)板上的分區(qū)通過USB使用ums工具映射到虛擬機中的ubuntu系統(tǒng)中。這里以更新bootloader和boot分區(qū)為例來介紹ums的使用方法。
首先需要使用xshell連接上調試串口,在系統(tǒng)的啟動過程中會出現1秒的倒計時,在倒計時結束之前按下鍵盤任意鍵即可將程序停留在bootloader的控制終端。
?

?
進入bootloader控制臺
?

?
4.1使用ums更新bootloader
在控制臺使用ums 0 mmc 0命令可以將開發(fā)板上的sdcard分區(qū)映射到PC上,然后再由PC將設備連接到虛擬機當中的ubuntu系統(tǒng)。
- 更新sdcard:
Board $> ums 0 mmc 0
- 更新emmc:
Board $> ums 0 mmc 1
?

?
在輸入命令之后虛擬機會提示檢測到新的USB設備,在如上界面中選擇連接到虛擬機后,在ubuntu系統(tǒng)中使用ls /dev/sd*命令可以看到多出了一些設備分區(qū)。
?

?
其中/dev/sdc設備就是開發(fā)板映射到系統(tǒng)中的,可以看到共有7個分區(qū)。使用ls -l /dev/disk/by-partlabel命令可以查看分區(qū)映射關系。需要注意的是燒錄的鏡像不同,分區(qū)數量也有所變化。
?

?
可以使用dd命令將編譯好的uboot鏡像或者是光盤資料的【華清遠見-FS-MP1A開發(fā)資料\06-系統(tǒng)鏡像\fs-mp1a-weston-openstlinux】下的uboot鏡像下載到開發(fā)板。
- 燒錄optee鏡像
sudo dd if= tf-a-stm32mp157a-fsmp1a-optee.stm32 of=/dev/sdc1 conv=fdatasync
sudo dd if= tf-a-stm32mp157a-fsmp1a-optee.stm32 of=/dev/sdc2 conv=fdatasync
sudo dd if= u-boot-stm32mp157a-fsmp1a-optee.stm32 of=/dev/sdc3 conv=fdatasync
sudo dd if=tee-header_v2-stm32mp157a-fsmp1a-optee.stm32 of=/dev/sdc4 bs=1M conv=fdatasync
sudo dd if=tee-pageable_v2-stm32mp157a-fsmp1a-optee.stm32 of=/dev/sdc5 bs=1M conv=fdatasync
sudo dd if=tee-pager_v2-stm32mp157a-fsmp1a-optee.stm32 of=/dev/sdc6 bs=1M conv=fdatasync
- 燒錄trusted鏡像
sudo dd if=tf-a-stm32mp157a-fsmp1a-trusted.stm32 of=/dev/sdc1 conv=fdatasync
sudo dd if=tf-a-stm32mp157a-fsmp1a-trusted.stm32 of=/dev/sdc2 conv=fdatasync
sudo dd if=u-boot-stm32mp157a-fsmp1a-trusted.stm32 of=/dev/sdc3 conv=fdatasync
注意:tf-a-stm32mp157a-fsmp1a-trusted.stm32鏡像是由tf-a源碼生成
4.2使用ums更新bootfs
在更新bootloader分區(qū)的時候我們通過dd命令將鏡像燒錄的開發(fā)板中,而bootfs分區(qū)是一個ext4格式的分區(qū),可以通過mount掛載的方式將文件系統(tǒng)掛載到ubuntu后直接對里面的內容進行修改。
與更新bootloader方式一樣可以使用ls -l /dev/disk/by-partlabel命令可以查看分區(qū)映射關系。找到bootfs所指向的設備節(jié)點。
?

?
可以看到這里對應的設備節(jié)點是sdc4分區(qū)。
使用sudo mount /dev/sdc4 /mnt 將其掛載到/mnt目錄下
?

?
掛載成功之后切換到/mnt目錄下查看
?

?
可以看到該分區(qū)中存放了linux內核及設備樹,extlinux的配置,開機logo等文件。我們可以通過替換相應的文件即可更新啟動鏡像。
例如我們可以將自行編譯生成的uImage替換到當前目錄下。
?

?
使用sudo umont /mnt 解除掛載后重啟開發(fā)板即可。
5.通過tftp方式下載linux內核及設備樹
除了使用ums掛載的方式進行內核及設備樹的更新之外,還可以通過pxelinux功能,從tftp服務器下載鏡像啟動。
在u-boot中使用tftp前需要將網線接入開發(fā)板,并且要與ubuntu所在的網段相同。
將要使用tftp下載的linux內核與設備樹拷貝到ubuntu系統(tǒng)中tftp服務器工作目錄中(/tftpboot),linux內核與設備樹可以從linux內核源碼中編譯得到。
linux@ubuntu:$ cp arch/arm/boot/uImage /tftpboot/
linux@ubuntu:$ cp arch/arm/boot/dts/stm32mp157a-fsmp1a*.dtb /tftpboot/
在tftp服務器工作目錄中(/tftpboot)建立pxelinux.cfg文件夾。在該文件夾下建立01-00-80-e1-42-60-17文件。tftpboot目錄結構如下
?

?
00-80-e1-42-60-17為開發(fā)板的默認mac地址,可以使用env set -f ethaddr xx:xx:xx:xx:xx:xx來修改mac地址。
如果通過sdcard啟動01-00-80-e1-42-60-17文件內容與開發(fā)板上/boot/mmc0_stm32mp157a-fsmp1a_extlinux/extlinux.cfg文件相同,如下所示
extlinux.cfg
1 23456789101112 |
? |
menu title Select the boot mode MENU BACKGROUND /splash.bmpTIMEOUT 20DEFAULT stm32mp157a-fsmp1a-mipi-sdcardLABEL stm32mp157a-fsmp1a-mipi-sdcard KERNEL /uImage FDT /stm32mp157a-fsmp1a-mipi050.dtb APPEND root=/dev/mmcblk1p6 rootwait rw console=ttySTM0,115200LABEL stm32mp157a-fsmp1a-rgb-sdcard KERNEL /uImage FDT /stm32mp157a-fsmp1a-rgb070.dtb APPEND root=/dev/mmcblk1p6 rootwait rw console=ttySTM0,115200 |
如果通過emmc啟動01-00-80-e1-42-60-17文件內容與與開發(fā)板上/boot/mmc1_stm32mp157a-fsmp1a_extlinux/extlinux.cfg文件相同,如下所示
extlinux.cfg
1 23456789101112 |
? |
menu title Select the boot mode MENU BACKGROUND /splash.bmpTIMEOUT 20DEFAULT stm32mp157a-fsmp1a-mipi-emmcLABEL stm32mp157a-fsmp1a-mipi-emmc KERNEL /uImage FDT /stm32mp157a-fsmp1a-mipi050.dtb APPEND root=/dev/mmcblk2p4 rootwait rw console=ttySTM0,115200LABEL stm32mp157a-fsmp1a-rgb-emmc KERNEL /uImage FDT /stm32mp157a-fsmp1a-rgb070.dtb APPEND root=/dev/mmcblk2p4 rootwait rw console=ttySTM0,115200 |
這里以sdcard為例,將01-00-80-e1-42-60-17內容修改為與開發(fā)板上/boot/mmc0_stm32mp157a-fsmp1a_extlinux/extlinux.cfg文件相同
?

?
在ubuntu中使用ifconfig命令查看當前ip地址,從而確定網段。
?

?
可以看到當前ubuntu的ip地址為192.168.11.78。由此得到當前網段為11網段。
開發(fā)板需要使用xshell連接上調試串口,在系統(tǒng)的啟動過程中會出現1秒的倒計時,在倒計時結束之前按下鍵盤任意鍵即可將程序停留在bootloader的控制終端。
?

?
進入bootloader控制臺
?

?
在u-boot控制臺中使用dhcp命令為開發(fā)板獲取一個ip地址。
?

?
可以看到獲取到了一個192.168.11.68的IP地址,也是11網段。與ubuntu網段相同。為了進一步驗證開發(fā)板與ubuntu的通信狀況可以使用ping命令來ping ubbuntu的IP地址驗證。
?

?
可以看到ping命令已經執(zhí)行成功了。
接下來設置tftp的服務器ip,可以看到也就是ubuntu的ip地址。
root@fsmp1a:# env set serverip 192.168.11.78
這里使用到了env set命令來設置環(huán)境變量,該命令默認只修改內存中的變量,存儲在sdcard或者emmc中的變量不會受到影響,也就是說調電回丟失修改,如果想要永久修改可以使用env save命令將當前內存中的環(huán)境變量更新到外部存儲設備中。
?

?
使用run bootcmd_pxe開始下載linux內核與設備樹文件??吹饺缦绿崾竞筮x擇您對應的啟動選項即可。
?

?
例如這里選擇1,進行5寸屏幕啟動。稍等片刻之后便可看到內核啟動。
?

?
6.通過scp方式更新linux內核及設備樹驅動程序
除了通過tftp方式和ums方式更新linux內核與設備樹文件以外,還可以通過scp方式來更新開發(fā)板中的文件。Scp是基于ssh協(xié)議進行數據傳輸,在傳輸過程中要傳輸數據一端我們稱之為服務器端,開發(fā)板通常作為數據接收端我們稱之為客戶端。當然開發(fā)板在往ubuntu發(fā)送數據的時候則會成為服務端。此方法需要開發(fā)板完整啟動,并進入文件系統(tǒng)終端。
在使用scp前需確認與服務器端所在網絡環(huán)境相同。本例中ubuntu的ip地址為192.168.11.78。開發(fā)板的ip地址需要通過串口終端下使用ifconfig命令確定。
?

?
可以看到當前開發(fā)板IP地址為192.168.11.68??梢酝ㄟ^ping命令來測試通信情況。
?

?
在之前章節(jié)提到過bootfs分區(qū)中存放了啟動時需要的linux內核及設備樹文件,extlinux的配置,開機logo等文件。bootfs分區(qū)在開發(fā)板中則對應了/boot目錄,也就是說對/boot目錄中的文件做出修改后,就相當于是對bootfs分區(qū)做出了修改。
在ubuntu端將需要更新的linux內核鏡像和設備樹文件通過scp命令的方式下發(fā)到開發(fā)板。此方式不僅支持對內核與設備樹的修改,同時也支持更新驅動文件上層應用程序等文件。
- Linux內核更新
linux@ubuntu:$ scp uImage root@192.168.11.68:/boot
linux@ubuntu:$ ssh root@192.168.11.68 /sbin/depmod -a
linux@ubuntu:$ ssh root@192.168.11.68 sync
linux@ubuntu:$ ssh root@192.168.11.68 reboot
首次使用時需要記錄鏈接密鑰。
?

?
在如上界面中輸入yes
?

?
- 設備樹更新
linux@ubuntu:$ scp stm32mp157a-fsmp1a*.dtb root@192.168.11.68:/boot
linux@ubuntu:$ ssh root@192.168.11.68 /sbin/depmod -a
linux@ubuntu:$ ssh root@192.168.11.68 sync
linux@ubuntu:$ ssh root@192.168.11.68 reboot
?

?
- 驅動更新
本例中我們假設需要將開發(fā)板中的觸摸屏驅動進行更新,觸摸屏驅動對應的驅動文件名為goodix.ko。通常驅動文件存放在開發(fā)板的/lib/modules/文件夾下,將工作目錄切換到/lib/ modules/使用find -name goodix.ko來搜索文件所在位置。通過搜索結果可知文件存放在./4.19.94/kernel/drivers/input/touchscreen/目錄下。
?

?
在ubuntu中使用scp命令將驅動程序下發(fā)到該目錄下。
linux@ubuntu:$scp goodix.ko root@192.168.11.68:/lib/modules/4.19.94/kernel/drivers/input/touchscreen/
linux@ubuntu:$ ssh root@192.168.11.68 /sbin/depmod -a
linux@ubuntu:$ ssh root@192.168.11.68 sync
linux@ubuntu:$ ssh root@192.168.11.68 reboot
如果使用scp時有以下提示,則說明之前有其他開發(fā)板使用過當前的ip地址。導致兩次密鑰不同,這種情況下使用圈紅命令就可以移除之前的密鑰。
?

?
7.通過linux更新eMMC中的u-boot
此方式是通過在linux終端下更新u-boot鏡像,使用此方法需確保linux可以正常啟動。
本例以basic啟動方式進行演示。首先需要編譯u-boot源碼得到u-boot-spl.stm32和u-boot.img鏡像文件。
將鏡像下發(fā)到開發(fā)板,這里使用scp網絡下載的方式(假設開發(fā)板ip為192.168.11.81)。
linux@ubuntu:$ scp u-boot-spl.stm32 root@192.168.11.81:/home/root
linux@ubuntu:$ scp u-boot.img root@192.168.11.81:/home/root
這樣就將主機的u-boot-spl.stm32和u-boot.img兩個文件,下發(fā)到開發(fā)板的/home/root目錄下。
?

?
更新eMMC的u-boot
root@fsmp1a:# echo 0 > /sys/class/block/mmcblk2boot0/force_ro
root@fsmp1a:# echo 0 > /sys/class/block/mmcblk2boot1/force_ro
root@fsmp1a:# dd if=u-boot-spl.stm32 of=/dev/mmcblk2boot0 conv=fdatasync
root@fsmp1a:# dd if=u-boot-spl.stm32 of=/dev/mmcblk2boot1 conv=fdatasync
root@fsmp1a:# echo 1 > /sys/class/block/mmcblk2boot0/force_ro
root@fsmp1a:# echo 1 > /sys/class/block/mmcblk2boot1/force_ro
root@fsmp1a:# dd if=u-boot.img of=/dev/mmcblk2p1 conv=fdatasync
?

?
在開發(fā)板上運行,執(zhí)行錯誤或文件寫入錯誤,會導致開發(fā)板無法啟動。如出現無法啟動的情況,請重新燒寫開發(fā)板即可。
8.使用STM32CubeProgrammer讀取OTP配置
注意:如果非必要操作務必不要修改OPT配置。如果修改錯誤會導致CPU無法啟動。
將開發(fā)板撥碼開關設置成【000】USB模式,將USB線連接到PC中。
?

?
運行STM32CubeProgrammer軟件。
?

?
連接USB并導入燒寫鏡像。
?

?
這里只需要勾選前兩個分區(qū)進行下載
?

?
下載成功后斷開USB連接
?

?
之后使用win+r鍵打開運行窗口。運行cmd窗口。
?

?
在cmd窗口中將當前工作目錄切換到STM32CubeProgrammer軟件的安裝目錄下的bin目錄。
?

?
使用STM32_Programmer_CLI -c port=usb1命令查看USB連接情況
?

?
使用STM32_Programmer_CLI -c port=usb1 -otp displ命令可以讀取OPT配置
?

?
可以使用STM32_Programmer_CLI -c port=usb1 -otp program wordID=0xXX value=0xXXXXXXXX命令來更新wordID的值。此方法在開發(fā)板斷電后值不會被保存如果想要永久生效需要在命令最后添加pl=1。
注意:如果非必要操作務必不要修改OPT配置。如果修改錯誤會導致CPU無法啟動。
評論