保姆级教程八:告别手动敲代码!ZYNQ程序打包进PetaLinux与开机自启动
文章目录
- 保姆级教程八:告别手动敲代码!ZYNQ程序打包进PetaLinux与开机自启动
-
- 🛠️ 第一步:让 PetaLinux 帮你管理 C 语言代码
-
- 1. 创建 PetaLinux APP 工程
- 2. 把你的 C 代码放进去
- 🚀 第二步:编写“开机自启动”脚本
-
- 1. 创建启动脚本文件
- 2. 写入极其关键的脚本代码
- 🔧 第三步:修改配方文件 (Yocto Recipe) – 施展魔法
- 🔨 第四步:一键编译,见证奇迹!
- 🎉 第五步:烧录开机,享受产品化的快感
- ❓ 新手常见问题排雷 (FAQ)
很多学到这里的同学都会面临一个极其现实的痛点:我的 DMA 程序跑通了,但每次修改代码都要在 Ubuntu 里交叉编译,然后用网线拖到板子上,再赋予权限,再手动运行……极其繁琐!
不仅如此,如果这块 ZYNQ-7030 开发板要作为最终产品交付,它必须做到**“上电即用”**(开机自动运行我们的程序)。
今天,我们就来揭秘 PetaLinux 最强大的功能之一:自定义应用程序打包 (Custom Apps) 与 SysVinit 开机自启动配置。
🛠️ 第一步:让 PetaLinux 帮你管理 C 语言代码
以前我们是在 Ubuntu 里新建一个文件夹自己用 arm-linux-gnueabihf-gcc 编译。现在,我们要把代码正式“入编”,交给 PetaLinux 的构建系统统一管理。
1. 创建 PetaLinux APP 工程
打开终端,进入你的 PetaLinux 工程根目录,输入以下命令:
petalinux-create -t apps –name my-autostart-app –enable
- -t apps:创建一个应用程序模板。
- –name my-autostart-app:你的程序名字。
- –enable:默认在文件系统中启用它(相当于打上了勾)。

2. 把你的 C 代码放进去
命令执行完后,PetaLinux 会自动在工程目录下生成一个文件夹: project-spec/meta-user/recipes-apps/my-autostart-app/files/
进到这个文件夹,你会发现里面有一个 my-autostart-app.c。 用你自己的 C 语言代码(比如上一篇写好的 DMA 测试代码,或者一个简单的 LED 闪烁代码),直接覆盖掉这个文件里的内容!
💡 小白避坑指南:以后你的代码修改,全部都在这个 files/ 文件夹里进行,再也不用自己去敲交叉编译命令了!
🚀 第二步:编写“开机自启动”脚本
Linux 系统开机后,会去 /etc/init.d/ 目录下依次执行里面的脚本。我们需要为我们的程序写一个启动脚本。
1. 创建启动脚本文件
还在刚才那个 files/ 文件夹下,新建一个文本文件,命名为 my-autostart-init.sh。
2. 写入极其关键的脚本代码
用文本编辑器打开它,输入以下内容(这是标准的 Linux sysVinit 脚本格式):
#!/bin/sh
# 这是一个开机自启动脚本
DAEMON=/usr/bin/my-autostart-app # 我们刚才创建的 C 程序编译后会被放在这里
NAME=my-autostart-app
DESC="My ZYNQ Auto-start Application"
case "$1" in
start)
echo "Starting $DESC…"
# ⚠️ 极其关键的 '&' 符号!
# 它代表把程序放在后台运行。如果不加 '&',而且你的 C 代码里有个 while(1) 死循环,
# Linux 开机就会永远卡在这里,进不了登录界面!!!
$DAEMON &
;;
stop)
echo "Stopping $DESC…"
killall $NAME
;;
restart)
$0 stop
sleep 1
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
exit 0
保存并退出。 
🔧 第三步:修改配方文件 (Yocto Recipe) – 施展魔法
现在代码和脚本都有了,我们要告诉 PetaLinux:“编译的时候,把我的 C 程序放到 /usr/bin/ 下,把我的脚本放到 /etc/init.d/ 下,并设置为开机自启!”
返回上一级目录: project-spec/meta-user/recipes-apps/my-autostart-app/ 找到一个叫 my-autostart-app.bb 的文件(这是 Yocto 系统的配方文件)。
用编辑器打开它,将里面的内容全部替换为以下代码(请小心复制,不要漏掉空格):
SUMMARY = "petalinux-user-app my-autostart-app"
SECTION = "PETALINUX/apps"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
# 1. 声明我们需要编译的源文件和脚本
SRC_URI = "file://my-autostart-app.c \\
file://my-autostart-init.sh \\
file://Makefile \\
"
S = "${WORKDIR}"
# 2. 引入 Linux 开机自启服务插件
inherit update-rc.d
# 3. 配置自启动参数 (名字必须和刚才的脚本名字一致,99代表开机最后阶段启动)
INITSCRIPT_NAME = "my-autostart-init.sh"
INITSCRIPT_PARAMS = "start 99 5 ."
do_compile() {
oe_runmake
}
# 4. 告诉构建系统,把文件安装到开发板的哪个目录下
do_install() {
# 将编译好的可执行文件放到 /usr/bin
install -d ${D}${bindir}
install -m 0755 my-autostart-app ${D}${bindir}
# 将自启动脚本放到 /etc/init.d/
install -d ${D}${sysconfdir}/init.d
install -m 0755 ${S}/my-autostart-init.sh ${D}${sysconfdir}/init.d/my-autostart-init.sh
}
保存并退出!这一步非常硬核,恭喜你成功掌握了底层 OS 工程师的核心技能!
🔨 第四步:一键编译,见证奇迹!
配置全部完成!现在回到 PetaLinux 工程的根目录,我们只需要告诉 PetaLinux 重新编译一下我们的 APP:
# 单独编译我们刚才写的 APP,检查有没有语法错误 (速度很快)
petalinux-build -c my-autostart-app
# 确认无误后,重新打包整个 Linux 系统文件
petalinux-build
petalinux-package –boot –fsbl images/linux/zynq_fsbl.elf –fpga images/linux/system.bit –u-boot –force
🎉 第五步:烧录开机,享受产品化的快感
把重新生成的 BOOT.BIN 和 image.ub 拷贝到 SD 卡,插到 ZYNQ-7030 开发板上,拔掉网线,只留一根串口线看日志。
打开电源开关!
盯着串口终端,当 Linux 内核启动完毕,即将进入 login: 登录界面之前,你会惊喜地看到屏幕上打印出这样一行字:
Starting My ZYNQ Auto-start Application…
接着,你在 C 语言里写的打印信息(比如 Hello ZYNQ! 或者 DMA 传输成功!)就会自动冒出来!
这意味着什么? 意味着你的 ZYNQ 开发板不再是一个“需要连接电脑才能跑的实验玩具”,而是一台 “通电就能独立工作的工业级计算平台”!
哪怕你把板子埋在深山老林里,只要一通电,Linux 就会自动拉起你的 FPGA 控制程序,默默地在后台跑起来。 
❓ 新手常见问题排雷 (FAQ)
Q1:为什么开机后,串口停在打印我的 C 语言输出,再也不出 login: 登录提示符了?我连键盘都敲不进去了!
- 致命原因:你绝对在第二步写 .sh 脚本时,漏掉了那个 & 符号!
- 原理解释:Linux 开机是单线程排队执行的。你的 C 程序如果是个死循环,它就会永远霸占启动线程,后面的“显示登录界面”任务就排不上号了。加了 &,就是让它滚去后台运行。
- 解决:拔掉 SD 卡,回 Ubuntu 把那个 & 加上,重新编译打包。
Q2:如果我的程序跑在后台了,我想手动关掉它怎么办?
- 登录 root 账号后,直接输入命令:/etc/init.d/my-autostart-init.sh stop,脚本里的 killall 命令就会精准地把它杀掉。想再次开启就输入 start。
结语: 兄弟们,走到这一篇,ZYNQ 嵌入式 Linux 的“新手村”主线剧情就算是正式通关了! 从一块空白的硅片,到画图生成 FPGA 电路(XSA),再到裁剪 Linux 内核,写中断与 DMA,最后把它打包成开机自启的商业级固件。你已经掌握了嵌入式行业的全栈核心科技!



