搭建知睿 STM32MP135 的交叉编译环境
前言
过程思路很简单,核心就是,先配好环境,然后做交叉编译,最后用 U 盘把编译完的文件放进文件导入到板子里面运行,但是作为新手还是稍微记录一下~
环境
- 主机系统:Win11
- 虚拟机:VMware® Workstation Pro 25H2u1 25.0.1.25219725
- Linux:Ubuntu 24.04.4 LTS
- 开发板:知睿-MP135-嵌入式学习系统 (STM32MP135)
- 板载系统:Buildroot 2022.02.3
配置交叉编译器
准备工作
根据《知睿-MP135-嵌入式学习系统—实验指南》,先装上各种依赖库和常用工具
sudoaptupdatesudoaptinstallgawkwgetgitdiffstatunziptexinfo gcc-multilib chrpath socat cpio python3 python3-pip python3-pexpect libssl-dev libgmp-dev libmpc-dev lz4 zstdsudoaptinstallbuild-essential libncurses-dev libyaml-dev libssl-devsudoaptinstallcoreutils bsdmainutilssedcurlbclrzsz corkscrew cvs subversion mercurial nfs-common nfs-kernel-server libarchive-zip-perl dos2unix texi2html libxml2-utils然后,根据文档:必须安装其他配置才能支持每个 MMC 最多 16 个分区。 默认情况下,在 Linux 系统上,MMC 上最多允许 8 个分区。 所有软件包(入门软件包等)都需要 10 个以上的分区供存储设备使用。为了将每个设备的分区数扩展到 16,必须将以下选项添加到 modprobe:
echo'options mmc_block perdev_minors=16'>/tmp/mmc_block.confsudomv/tmp/mmc_block.conf /etc/modprobe.d/mmc_block.conf然后下载 SDK:en.SDK-x86_64-stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24.tar.xz,在 Linux 系统中解压(注意不要直接在共享文件夹解压)。
- 下载SDK
安装 SDK
解压 SDK,然后一路点进去找到脚本:st-image-weston-openstlinux-weston-stm32mp1-x86_64-toolchain-3.1-openstlinux-5.4-dunfell-mp1-20-06-24.sh,开权限,运行脚本,设定好你想要放 SDK 的路径——当然就按照他的默认路径也行(记得提前记录一下他的路径),然后等他解压。
安装成功后,进入 SDK 的安装路径,应该会看到这些文件:
environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi site-config-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi sysroots version-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi之后安装包就没用了,可以删了省空间。
配置 SDK 环境
SDK 的路径下,其中一个文件,看开头叫做 environment-setup,这就是初始化环境所需要的文件。在这个文件夹下启动命令行,开始敲命令:
source./environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi然后检查一下各个变量,看看有没有成功:
$echo$ARCHarm $echo$CROSS_COMPILEarm-ostl-linux-gnueabi- $echo$CCarm-ostl-linux-gnueabi-gcc-mthumb-mfpu=neon-vfpv4 -mfloat-abi=hard-mcpu=cortex-a7--sysroot=/opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/sysroots/cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi $$CC--versionarm-ostl-linux-gnueabi-gcc(GCC)9.3.0 Copyright(C)2019Free Software Foundation, Inc. This isfreesoftware;see thesourceforcopying conditions. There is NO warranty;not evenforMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.CC 是什么?是 Cross-Compiler,交叉编译器,记住,后面要考哦()
这样,我们在同一个控制台中就可以编译文件了。注意,我们每次要启动交叉编译的时候,都要重复这个步骤——这么看,这个流程还是太麻烦了,也许我们可以稍微简化一下。可以用符号链接在自己平时的工作区做一个快捷方式:
语法:
ln-s[link-target][link-name]比如在我的工作区:
ln-s/opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24 /home/felix/embedded/sdk-base这样我们在上一级目录可以直接用符号链接等效地进入前面那一堆乱七八糟的路径。
还可以给那个 setup 脚本做个副本,取一个简单的名字——直接 cp 一下就好了。注意如果不是在 home,要有管理员权限:
sudocpenvironment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi setup然后下次启动 SDK 就简单了,直接用快捷方式+简化,比如从符号链接的上一层开始:
cdsdk-basesource./setup就能够成功启动环境了。
交叉编译
然后我们准备一个 C 语言的 demo,比如 hello world,然后启动 SDK,按照 gcc 的语法开始编译:
$CC-g/your/src/dir/hello.c-o/your/target/dir/hello控制台没有输出,目标路径生成文件,那就是成功了,至此,SDK 中的交叉编译就已经完成了,我们有了一个可以在板子上运行的二进制可执行文件。
minicom 配置
在开启串口前,首先把 brltty 卸载掉,否则看不到我们需要的设备,然后安装 minicom:
sudoaptremove brlttysudoaptinstallminicom卸载 brltty 之后要重启一下 Linux。然后,我们把有串口的 USB 线从板子引出来,连接电脑,接入虚拟机,紧接着查一下/dev路径,看看有没有名称中包含 USB 的设备,检查电脑是否识别到串口:
ls/dev|grepUSB如果查到了ttyUSB0(或者其他数字)那就是连上了,这时候就可以管理员启动 minicom,连接板子:
sudominicom-D/dev/ttyUSB0默认的比特率是 115200,我在跑的时候也是115200,不用给参数就能连上,如果要换其他比特率就加上-b 9600。
如果到这里一切正常,应该就能在串口中与板子的命令行交互了。
导入文件
U盘法
这个是我最开始尝试成功的。准备一个U盘,确定这个U盘的文件系统是 FAT32(可以在主机上查看属性,如果不是的话去问问 AI 看看对应的兼容性和命令),然后把刚才编译好的可执行文件拷贝进去,然后把U盘插进板子。
如果仔细观察板子的/dev,能够注意到,插入U盘的时候会出现 sda,sda1 ——这就是U盘对应的设备。接下来把他挂载到系统中。
注意,接下来的操作都是通过串口在从机上操作的。
首先,创建一个拿来挂载用的路径:
mkdir-p/mnt/udisk
-p的含义自己去查,感觉是挺有用的
然后把 sda1 挂载到刚才做好的路径下:
mount-tvfat /dev/sda1 /mnt/udisk如果没有报错,就是成功了,接下来可以 cd 进挂载好的路径,ls 一下看看能不能读到U盘中的文件。如果一切正常,就可以试着跑一下。在嵌入式平台中,建议不用exec启动可执行文件,直接用文件名运行就好,比如
./hello_arm如果一切顺利的话——
文本发送法
对于我们用来demo的这种小文件,这个方法会快很多。思路就是,把整个可执行文件变成一大串字符串,通过串口方便地发送到从机,然后再转回文件。
在主机上把编译好的可执行文件转化为 base64 编码,输出到文件中:
base64 hello>hello_base64注意,接下来的操作都是通过串口在从机上操作的。
然后打开文件,把这堆代码复制一下,接着进入串口,把这堆文字发送到从机上。这段文字包含了换行,因此最好的方法是用 cat:
cat<<EOF>>hello_base64这个 EOF 是指定的文件末尾标记,把刚才的那一堆文字复制进来,最后一行写上 EOF,这样刚才的字符串就成功保存到从机上的文件里面了。紧接着,解码,重新生成可执行文件,给权限:
base64-dhello_base64>hellochmod+x hello然后,同上一个方法,运行即可,是激动人心的hello world!
(补)网络 NFS 法
这个方法也非常快,但是绕了很久,而且网络协议我不了解,就做个简单的记录。
用网线连接板子和电脑,然后先去 VMWare 的 Edit - Virtual Network Editor,进入编辑,然后把桥接的那一个选项删掉(比如 VMnet0),重新建立,在直连的对象中找到疑似网口的选项,选中保存,然后去虚拟机设置里面也把桥接设置好,当然可以多开一个 NAT 保证联网。
然后去串口中查一下板子的 IP:
ipaddr然后,进入虚拟机,进入到网络的设置界面。我的 Ubuntu 可以建立多个预设,因此新建一个预设,把 IP 设置成和板子前三位相同的固定值,比如192.168.1.66,子网掩码照常255.255.255.0,网关和IP前三个数字相同,最后一位是1,比如192.168.1.1。
这些设置完成后,插上网线,如果系统显示正常,就可以用从机 ping 一下虚拟机了。
接着,在主机上确定 NFS 共享的文件夹。首先安装nfs-kernel-server,然后创建好文件夹,开777权限,然后去/etc/exports里面加一句/dir/to/folder *(rw,sync,no_root_squash,no_subtree_check),具体怎么设置权限自行查命令。
然后加载配置,重启服务,exportfs 应该能查到你刚才的设置项:
sudoexportfs-arvsudosystemctl restart nfs-kernel-server然后,关掉防火墙,如果一股脑全关掉就是sudo ufw disable,想要细化可以以后再说。
接着,去/etc/nfs.conf中解除掉这句注释:
[nfsd] ... vers4=y到这步之后,上位机的权限就放开了,进行一轮重启:
sudosystemctl restart rpcbindsudosystemctl restart rpc-statdsudosystemctl restart nfs-server然后去下位机创建好文件夹,跑命令:
mount-tnfs-overs=4192.168.1.66:/home/felix/embedded/board /mnt/nfs正常的话,这里应该就可以完成文件夹的共享了。由于我进行了大量的回档,因此这些记录可能不全面,仅做记录。
总结
思路很清晰,配置交叉编译环境,与下位机建立通讯,把文件发送过去,能这么轻松,从机上自己的标准化 Linux 环境还是立了大功的。
流程挺长的,但是上板子毕竟还是和在模拟空间里面跑不一样,更有乐趣了,毕竟这样就可以在板子里面大闹天宫了嘛(bushi
