草庐IT

petalinux制作自动启动应用过程中遇到的问题解决

songbins 2024-05-22 原文

最近做一个项目,硬件平台为Xilinx ZYNQ7000系列,需要用到网口、串口等较多的外设。特别是网络通信,由于操作系统自带TCP/IP、UDP协议栈,网口通信开发起来简单得多,因此移植Linux系统是很好的选择。在本项目之前,本人从未接触过Linux系统,更别说底层驱动、设备树、系统移植等等了,实在是新手菜鸟一个,所以下面内容中存在对linux理解不是那么清晰的地方,不管怎样,在项目进度的压力下,只好硬着头皮上,边摸索边做,只要能够实现系统移植和开发自己的应用软件,并且能够实现功能就好。等之后有空余时间,再去深入学习理解Linux系统吧。

好在Xinlinx推出了petalinux这套工具,使Linux系统移植、设备树、底层驱动什么的都变得傻瓜化,这就节省了大量的时间和精力去学习Linux。就算如此,在用petalinux定制Linux系统时仍遇到了一些问题,经过在网上查找资料,咨询大神,目前遇到的问题都顺利得到解决。解决这些问题之后,整理了一下收获和心得,进行分享。

1、需要实现的关键功能

先整理需求如下,以便引出为满足需求遇到的问题。因为应用场景的关系,项目的搭载平台没有显示器、键盘等输入输出设备。因此需要目标板上Linux系统启动后,满足以下两个关键条件:

        1)去除掉用户登陆;

        2)自动运行app。

在实现这两条时,主要参考了Xilinx ug1144-petalinux-tools-reference-guide.pdf这个 patelinux工具文档,网上中英文版都有。

2、去掉用户登陆

这条非常好办,在petalinux集成配置界面中就可以搞定。在虚拟机下运行ubuntn,打开终端,配置好工作环境,导入Vivado硬件,用petalinux-create建立工程,这些步骤网上教程很多,这里就不细说了。

在前面的步骤都完成后,cd 进入到建立的petalinux工程目录,

输入命令:petalinux-config

会弹出petalinux集成配置界面,如下:

在界面中用上下键移动,选择 Yocto Settings --->选项,enter键进入该子菜单,如下:

在右图界面中用上下键移动,选中[ ]Enable Debug Tweaks选项,然后按 “Y” 键,在选项前的 方括号 “[]” 中会标记 “*” 号,表示该项已被选中。

然后用左右键移动下方的选项选择,选择<Save>,会弹出提示框,一直回车。最后选择下方的<Exit>,退出到左边的主界面,再次选择<Exit>退出配置界面。就能取消掉用户登陆操作。关键问题出在第2条,目标板上Linux开机自动运行app。

3、目标板上Linux开机自动运行app

首先,UG1144文档中有相当详细的定制应用、构建应用、自启动程序的讲解,按照其步骤的确可以实现开机自启动运行,仔细一看就发现有些问题,当然不是UG1144文档的bug,而是针对不同的需求,要求的开机自启动的时机是不一样的。UG1144只是给出了一个模板,这个模板对于自动启动后台服务应该是没问题的,而当app不是后台服务,且要独占系统资源运行时,就不行了(本人是新手菜鸟,对Linux理解还浅,通过实践摸索后大致猜测应该是这样的)。

按UG1144第8章--自定义Rootfs中如下的顺序构建自启动:

创建和添加定制应用;

构建用户应用;

开机时应用程序自动运行。

3.1 创建和添加定制应用

首先 cd 到创建的petalinux工程目录(启动虚拟机-启动ubuntn-打开终端的基础操作这里略过)

在petalinux工程目录下输入命令:

petalinux-create -t apps –template c –name demoapp --enable

创建一个基于c语言模板的,工程名为demoapp的应用app工程(工程名可以自己随便取),这个工程位于:

<petalinux工程目录>/project-spec/mate-user/recipes-apps/demoapp(这个demoapp以新建的应用工程名命名的目录)

 

目录中有个demoapp.bb文件和一个file文件夹,file文件夹下有demoapp.c、makefile两个文件。makefile是demoapp.c的编译参数配置文件,demoapp.bb是编译源文件及编译后输出文件的存放位置配置文件。还有一个README文件,虽然这个文件有一些使用和放置说明,但是petalinux下的移植与普通Linux移植不太一样,因为petalinux是一个傻瓜似的集成配置环境,很多东西是被镜像打包的,不能直接操作,所以意义不大。

注意1:这里有个坑,自动生成的makefile文件只支持非多线程的app编译,如果把app修改为多线程,那么就需要在makefile文件最后一行的末尾加上 -lpthread参数,否则petalinux-build时就会报错。修改前后见下图,第1张图是自动生成的,第2张图是修改后的:

 

注意2:在同一个petalinux工程下,同名app反复编译时,会报错,这时用UG1144中所说,先清除该应用,再重新构建该应用,可以解决报错问题。

      清除应用的指令:petalinux-build -c <应用名> -x do_clean

      重构建应用的指令:petalinux-build -c <应用名>

3.2 构建用户应用

终端继续保持在petalinux工程目录下,然后用下面的指令构建用户应用。

petalinux-build -c rootfs

petalinux-build -x package

这两条指令是把前面创建的app构建到现有系统镜像中。

其实也可以用 petalinux-build 指令直接完成构建。

3.3 开机时应用程序自动运行

终端继续保持在petalinux工程目录下,然后用下面的指令创建应用安装工程

petalinux-create -t apps –template install -n demo-init –enable

其中demo-init是要创建的应用安装工程名,这个名字可以自己随便取。同样会在petalinux工程目录中自动生成这个应用安装工程的目录。

<petalinux工程目录>/project-spec/mate-user/recipes-apps/demo-init

demo-init目录下,同样有一个名为demo-init.bb的文件,和一个files目录,files目录下则只有一个demo-init文件。demo-init.bb文件也是关于源文件目录和放置目录的脚本,files目录下的demo-init还是一个脚本,只是目前这个脚本只有一条输出指令,还没有指向之前创建的demoapp。仔细看demo-init实际上是shell脚本,只是文件名没有(.sh)后缀。

         

然后按照UG1144修改demo-init.bb文件和demo-init文件。修改完成后如下:

这里在start()部分的第二条语句与UG1144中有些不同,没有加入-background参数,也就是表明不在后台运行,主要是为了方便观察打印信息。

然后petalinux-config -c rootfs配置根文件系统,在apps选项的子菜单中选中demo和demo-init,最后生成镜像,拷贝至目标板SD卡,上电启动。

3.3.1 关键问题的出现

仔细看上面目标板开机的截图,这是完全按照UG1144构建的自启动,图中最上面有行彩色文本,这就是自动运行的app打印输出的信息。注意观察打印输出位置,在这条文字后面还紧跟着一部分Linux系统的启动信息,其中就包括网络端口的配置

这说明什么呢,虽然demoapp开机自动运行了,但是在linux系统完整启动完成前就开始执行了。这里的demoapp仅打印一条语句就退出了,并没有一直占用资源。如果实际需要运行的应用是比较复杂的非后台服务应用,且要在开机后一直占用资源运行呢,那么岂不是就中断了系统开机过程,导致linux系统启动不完整,缺失部分底层功能。从运行情况看,起码网口是不能正常工作的。

发现这个情况后,把demoapp.c修改为含有while(1)循环的代码,再次打包镜像到目标板,系统启动到之前彩色文字处,一直打印输出信息,不再往后启动其它部分。然后去掉while,在没去除登陆的条件下,修改demoapp.c,main函数中只有一条自动输入登陆账号和密码的代码,如下:

#include <unistd.h>

#include <stdio.h>

int main()

{

   execlp( "login", "login", "-f", "root", 0);

}

运行后,发现系统启动过程在上次打印输出位置终止了,直接进入到root@demo:~#控制台。然后输入 ifconfig指令,没有列出网络配置信息,再用ping命令ping主机IP,提示网络无效,无法达成。验证了linux系统启动不完整,网口没有正常初始化的猜想。有兴趣的可以自己验证一下,这里就不详细贴图了。

我实际需要的自动运行应该在下图红色箭头这个位置开始,保证系统启动的完整性。

这就是我目前遇到的最关键的问题,这个问题不解决,即使往后开发软件功能,也无法正确运行。

3.3.2 问题的分析及解决

怎么解决呢,再回头看demo-init.bb文件,这个文件中的do_install中是把demo-init脚本文件放到/etc/init.d目录中,这个目录应该是linux系统启动相关的目录,好像放这里确实有些不适合我这个项目的需求。按照Linux—添加开机启动(服务/脚本) - 刘_love_田 - 博客园 (cnblogs.com)中的讲解,选第二种方法,把启动应用的脚本(.sh)放到/etc/profile.d目录下,/etc/profile.d这个目录是系统完整启动完成后,再自动执行该目录下的脚本,放到该目录下即能确保系统完全启动又能自动运行应用启动脚本。因为petalinux中无法按全人工移植方法处理,文件系统都被镜像打包了的。

看来修改demo-init.bb文件是目前最好的方法,把do_install中放置脚本的目录改为/etc/profiles.d目录。在修改之后我重打包镜像,目标板上电启动,但demoapp根本没有运行,在目标板的控制台输入ls /etc/profiles.d命令,发现有demo-init这个文件,./demo-init运行,提示无效,用chmod +x demo-init指令授权,再次./demo-init运行,打印出了文本信息。说明demo-init文件的授权存在问题,那还得修改demo-init文件的权限。这就有两种情况:

  1. 授权不对或不完整,导致demo-init这个脚本不能执行
  2. 系统不认为demo-init是可以执行的脚本
  3. 或者两种情况都有。

怎么修改呢,仔细看demo-init.bb文件do_install部分,发现第2条install语句为:install -m -0755 ${S}/demo-init ${D}/${sysconfdir}/profiles.d/demo-init。猜想其中的0755就是授权,把0755修改为0777,表示用户、群组、任何其它用户都有这个文件的读写执行权。同时把这条语句中含有demo-init的都改为demo-init.sh,明确的让系统知道这是一个shell脚本,两处都改,确保不会出问题。

这里的demo-init加了后缀,那么demo-init应用工程目录中files目录下的demo-init文件的文件名也要加上(.sh)后缀:demo-init.sh。

最后修改demo-init.sh脚本,因为我的应用不需要太复杂的过程指令,只有一个目的,运行/usr/bin目录下的demoapp,所以把其中的内容全部删除,只有下面几条指令。

#!sh

DAEMON= /usr/bin/demoapp

$DAEMON

就是告诉系统,运行/usr/bin目录下的demoapp应用。以上我自行摸索测试的过程非常繁琐,不再一一截图展示。

修改后的文件内容如下,这里用我之前完成修改的另一个可以正确运行的myapp应用截图展示:

  myapp-init.bb修改后的样子,红色箭头处是修改的地方。

mapp-init.sh修改后的样子

最后给出目标板开机启动的截图,可以看到myapp的打印输出完成之后,没有Linux系统启动的其它过程,直接转到控制台提示符,等待输入指令。表明myapp是在系统完整启动后执行的。这个myapp.c我修改为了多线程测试代码,以验证是否能正确运行多线程。

再看IP信息和ping主机,见下图,有IP地址等信息,也能ping通主机

至此,解决了我用petalinux定制zynq平台Linux系统、制作开机自动启动应用过程中遇到的问题。

4、写在最后

可能对Linux系统熟悉的人会说,直接把需要自动运行的app做成后台服务就好了,按照UG1144中的方法完全没有问题,还要这么瞎折腾一通。可是,由于本项目的周期压力,本人在本项目之前又从未接触过Linux,没有多余的时间和精力去研究Linux下后台服务的开发。如果能有人帮助做好Linux移植,就像在windos平台下开发C或C++程序一样,本人只管做好程序功能就行,那就好了。可惜项目团队是初创团队,人手少,各个专业方向都只有1个人,因此从zynq 7z100硬件平台设计到PL端VHDL代码功能,再到PS端Linux系统移植,Linux系统下app应用开发都只能靠我一个人搞定。所以呢,在各方面条件都受限的情况下,就发生了前面的一番折腾,不管黑猫白猫抓住老鼠就是好猫,不管怎样,达成了我想要的结果。

写这篇文章,主要目的就是分享一下经验,给即将或已经准备从零基础开始接触Xinlinx zynq系列平台下Linux系统移植的,有类似项目需求,且同样有项目周期压力和与本人有类似条件限制的开发人员提供一个参考。

有关petalinux制作自动启动应用过程中遇到的问题解决的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  3. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  4. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  5. ruby-on-rails - Rails 应用程序中的 Rails : How are you using application_controller. rb 是新手吗? - 2

    刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr

  6. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  7. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  8. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  9. ruby-on-rails - 如何在 Gem 中获取 Rails 应用程序的根目录 - 2

    是否可以在应用程序中包含的gem代码中知道应用程序的Rails文件系统根目录?这是gem来源的示例:moduleMyGemdefself.included(base)putsRails.root#returnnilendendActionController::Base.send:include,MyGem谢谢,抱歉我的英语不好 最佳答案 我发现解决类似问题的解决方案是使用railtie初始化程序包含我的模块。所以,在你的/lib/mygem/railtie.rbmoduleMyGemclassRailtie使用此代码,您的模块将在

  10. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

随机推荐