前言
STM32MP1是意法半导体推出的第一款MPU,它家的STM32系列MCU搞的不错,资料什么挺多,所以平时用的也蛮多,所以它家出的MPU也想体验下。
这篇文章将以官方的STM32MP157F-DK2套件为基础,参考官方的wiki,进行体验使用,并对相关过程做个记录。 https://wiki.stmicroelectronics.cn/stm32mpu/wiki/Getting_started/STM32MP1_boards/STM32MP157x-DK2
基础准备
系统环境
下载安装Ubuntu Desktop(这里使用版本为20.04.4): https://ubuntu.com/download/desktop
安装完成后进行基础环境安装与设置:
sudo apt update
sudo apt install -y build-essential
以下为应用与内核开发需要的环境安装与设置:
sudo apt install -y gawk git-core diffstat texinfo gcc-multilib chrpath socat cpio python3-pip python3-pexpect xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev pylint3 pylint xterm
sudo apt install -y xsltproc docbook-utils fop dblatex xmlto
sudo apt install -y libmpc-dev libgmp-dev
sudo apt install -y libncurses5 libncurses5-dev libncursesw5-dev libssl-dev linux-headers-generic u-boot-tools device-tree-compiler bison flex libyaml-dev libmpc-dev libgmp-dev
sudo apt install -y python-is-python3
echo 'options mmc_block perdev_minors=16' > /tmp/mmc_block.conf
sudo mv /tmp/mmc_block.conf /etc/modprobe.d/mmc_block.conf
硬件连接
硬件连接如下图所示: 特别需要注意的是使用的电源(5V3A)、供电的USB线、通讯的USB线品质不能太差,不然可能系统镜像烧录过程中会出错。
系统镜像烧录测试
ST官方提供了测试用的系统镜像,使用ST的烧录工具可以烧录镜像到存储器中。烧录工具有Linux、Windows、Mac版本的,选择合适的平台进行即可。
烧录是通过 USB OTG 那个口进行的(DFU模式)。需要注意的是烧录过程中设备会断开重新连接,如果使用虚拟机的话需要把这个USB设备设置为自动转到虚拟机或是在重新连接的过程中手动转到虚拟机。
下面是Linux下系统镜像烧录测试过程:
STM32CubeProgrammer安装
STM32CubeProgrammer用来将系统二进制文件烧录到TF卡或eMMC中,可以从下面选择合适的版本下载: https://www.st.com/en/development-tools/stm32cubeprog.html 我这里通过Ubuntu自带的浏览器下载,得到的 en.stm32cubeprg-lin_v2-10-0.zip 文件位于 ~/Downloads/ 目录下。
接下来进行安装:
mkdir -p ~/mp157/tools/prog
cd ~/Downloads/
unzip en.stm32cubeprg-lin_v2-10-0.zip
./SetupSTM32CubeProgrammer-2.10.0.linux
允许USB相关功能:
cd ~/mp157/tools/prog/Drivers/rules/
sudo cp *.* /etc/udev/rules.d/
导出到环境变量方便使用:
export PATH=$HOME/mp157/tools/prog/bin:$PATH
系统镜像烧录
从下面地址下载ST官方提供的系统镜像: https://www.st.com/content/st_com/en/products/embedded-software/mcu-mpu-embedded-software/stm32-embedded-software/stm32-mpu-openstlinux-distribution/stm32mp1starter.html 我这里通过Ubuntu自带的浏览器下载,得到的 en.FLASH-stm32mp1-openstlinux-5-10-dunfell-mp1-21-11-17_tar.xz 文件位于 ~/Downloads/ 目录下。
mkdir -p ~/mp157/ecosystem/starter
cd ~/mp157/ecosystem/starter
mv ~/Downloads/en.FLASH-stm32mp1-openstlinux-5-10-dunfell-mp1-21-11-17_tar.xz ./
tar xvf en.FLASH-stm32mp1-openstlinux-5-10-dunfell-mp1-21-11-17_tar.xz
烧录前将开发板背面的两个拨码开关都拨到OFF位置,然后按正面的RESET按钮进行复位。接着启动烧录工具:
STM32CubeProgrammer
连接设备,打开下面目录中对应的烧录配置文件(.tsv): ~/mp157/ecosystem/starter/stm32mp1-openstlinux-5.10-dunfell-mp1-21-11-17/images/stm32mp1/flashlayout_st-image-weston/ 然后二进制文件路径选择下面这个: ~/mp157/ecosystem/starter/stm32mp1-openstlinux-5.10-dunfell-mp1-21-11-17/images/stm32mp1/ 最后点击 Download 进行烧录即可: 烧录过程比较漫长,请耐心等待。
烧录完成后将开发板背面的两个拨码开关都拨回ON位置,然后按正面的RESET按钮进行复位。 系统将正常启动显示开机画面,初次启动时接着将黑屏几分钟进行初始化,完成后会在屏幕上显示文章开头图片中画面。
如果STLink那个USB口使用数据线连接到电脑的话会在电脑上有一个串口,使用终端工具进行连接的话会在这里打印出启动日志。也可以通过这里与系统进行交互:
应用与内核开发
SDK安装
从下面地址下载ST官方提供的SDK(SDK中包含编译工具链和库文件): https://www.st.com/content/st_com/en/products/embedded-software/mcu-mpu-embedded-software/stm32-embedded-software/stm32-mpu-openstlinux-distribution/stm32mp1dev.html 我这里通过Ubuntu自带的浏览器下载,得到的 en.SDK-x86_64-stm32mp1-openstlinux-5.10-dunfell-mp1-21-11-17.tar.xz 文件位于 ~/Downloads/ 目录下。
cd ~/Downloads/
tar xvf en.SDK-x86_64-stm32mp1-openstlinux-5.10-dunfell-mp1-21-11-17.tar.xz
mkdir -p ~/mp157/ecosystem/developer/SDK
chmod +x stm32mp1-openstlinux-5.10-dunfell-mp1-21-11-17/sdk/st-image-weston-openstlinux-weston-stm32mp1-x86_64-toolchain-3.1.11-openstlinux-5.10-dunfell-mp1-21-11-17.sh
./stm32mp1-openstlinux-5.10-dunfell-mp1-21-11-17/sdk/st-image-weston-openstlinux-weston-stm32mp1-x86_64-toolchain-3.1.11-openstlinux-5.10-dunfell-mp1-21-11-17.sh -d $HOME/mp157/ecosystem/developer/SDK
cd ~/mp157/ecosystem/developer/
source SDK/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
应用开发
mkdir -p ~/mp157/ecosystem/developer/application/gtk_hello_world_example
cd ~/mp157/ecosystem/developer/application/gtk_hello_world_example/
建立 gtk_hello_world.c 文件(gedit gtk_hello_world.c),内容如下:
#include <gtk/gtk.h>
static void
print_hello (GtkWidget *widget,
gpointer data)
{
g_print ("Hello World\n");
}
static void
activate (GtkApplication *app,
gpointer user_data)
{
GtkWidget *window;
GtkWidget *button;
GtkWidget *button_box;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_container_add (GTK_CONTAINER (window), button_box);
button = gtk_button_new_with_label ("Hello World");
g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
gtk_container_add (GTK_CONTAINER (button_box), button);
gtk_widget_show_all (window);
}
int
main (int argc,
char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
建立 Makefile 文件(gedit Makefile),内容如下:
PROG = gtk_hello_world
SRCS = gtk_hello_world.c
CLEANFILES = $(PROG)
CFLAGS += -Wall $(shell pkg-config --cflags gtk+-3.0)
LDFLAGS += $(shell pkg-config --libs gtk+-3.0)
all: $(PROG)
$(PROG): $(SRCS)
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
clean:
rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS))
使用 make 进行编译。编译得到的二进制文件可以通过网络传输到开发板中(比如使用 scp gtk_hello_world root@<board ip address>:/usr/local 方式),然后在开发板中运行(比如通过串口终端来运行)。运行运行上面程序会在开发板的屏幕上出现一个带有按钮的窗体:
内核编译
从下面地址下载ST官方提供的Linux内核源码开发包: https://st.com/content/ccc/resource/technical/sw-updater/firmware2/group0/78/11/85/59/c4/22/46/41/STM32cube_Standard_A7_BSP_components_kernel/files/SOURCES-kernel-stm32mp1-openstlinux-5.10-dunfell-mp1-21-11-17.tar.xz/_jcr_content/translations/en.SOURCES-kernel-stm32mp1-openstlinux-5.10-dunfell-mp1-21-11-17.tar.xz 我这里通过Ubuntu自带的浏览器下载,得到的 en.SOURCES-kernel-stm32mp1-openstlinux-5.10-dunfell-mp1-21-11-17.tar.xz 文件位于 ~/Downloads/ 目录下。
cd ~/mp157/ecosystem/developer/
cp ~/Downloads/en.SOURCES-kernel-stm32mp1-openstlinux-5.10-dunfell-mp1-21-11-17.tar.xz ./
tar xvf en.SOURCES-kernel-stm32mp1-openstlinux-5.10-dunfell-mp1-21-11-17.tar.xz
cd stm32mp1-openstlinux-5.10-dunfell-mp1-21-11-17/sources/arm-ostl-linux-gnueabi/linux-stm32mp-5.10.61-stm32mp-r2-r0/
tar xvf linux-5.10.61.tar.xz
cd linux-5.10.61
for p in `ls -1 ../*.patch`; do patch -p1 < $p; done
make ARCH=arm multi_v7_defconfig "fragment*.config"
for f in `ls -1 ../fragment*.config`; do scripts/kconfig/merge_config.sh -m -r .config $f; done
yes '' | make ARCH=arm oldconfig
make ARCH=arm uImage vmlinux dtbs LOADADDR=0xC2000040
make ARCH=arm modules
mkdir -p $PWD/install_artifact/
make ARCH=arm INSTALL_MOD_PATH="$PWD/install_artifact" modules_install
编译完成后后可以使用网络将生成的内容更新到开发板上:
以下操作在开发板终端中进行:
内核修改测试
gedit ./drivers/gpu/drm/stm/drv.c
在打开的文件中添加红框中一条语句:
修改完成后保存推出,然后重新编译内核:
make uImage LOADADDR=0xC2000040
scp arch/arm/boot/uImage root@<board ip address>:/boot
以下操作在开发板终端中进行:
reboot
dmesg | grep -i stm_drm_platform_probe
------END------
|