本帖最后由 正点原子运营 于 2024-1-29 16:23 编辑
第八章 使用Vitis开发Linux应用 1)实验平台:正点原子 DFZU2EG_4EV MPSoC开发板
2) 章节摘自【正点原子】DFZU2EG_4EV MPSoC开发板之嵌入式Linux 驱动开发指南 V1.0
3)购买链接:https://detail.tmall.com/item.htm?id=692450874670
4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/fpga/zdyz-MPSOC.html
5)正点原子官方B站:https://space.bilibili.com/394620890
6)Linux技术交流QQ群:887820935
上一章我们学习了在Petalinux搭建的Linux系统上基础外设的使用,本章我们以创建“Hello World”工程为例学习如何使用Vitis开发Linux应用以及如何让应用程序运行在Petalinux搭建的Linux系统上。运行方式本章介绍了三种,可根据个人喜好选择。
1.1 创建基于Vitis的Linux平台工程双击Windows系统桌面的Xilinx Vitis IDE 2019.2图标打开Vitis工具,弹出图 8.1.1所示的Lancher界面: 设置Vitis Workspace文件夹,可以是任一文件夹,最好不要包括中文以及特殊字符,这里笔者选择的是F:\Mpsoc\appDev_Linux文件夹,然后点击“Launch”按钮,进入如下图所示界面: 单击“Create Platform Project”,即创建平台工程,进入下图所示界面: “Project name”栏输入平台工程名“appDev_Linux_plat”,其他保持默认,然后单击底部的“Next >”,进入下一页面,如图 8.2.5所示。 选择“Create from hardware specification (XSA)”,然后单击底部的“Next >”,进入下一页面,如下图所示: “XSA file:”栏选择用于该平台工程的xsa文件,与6.3.4节使用的xsa文件相同。 “Operating system”操作系统选择“linux”, 选择后“Processor”默认配置为“psu_cortexa53”。 取消勾选“Generate boot components”。 配置好后,点击底部的“Finish”按钮。 现在我们将开发板资料盘(A盘)\4_SourceCode\3_Embedded_Linux\zynq_petalinux\4ev\linux_boot文件夹拷贝到Vitis Workspace文件夹F:\Mpsoc\appDev_Linux下,如下图所示: 图 8.1.6 解压缩后的linux_boot文件夹 回到Vitis界面,设置“Bif File”为linux_boot文件夹下的linux_image.bif文件,设置“Boot Components Directory”为linux_boot文件夹,如下图所示: 设置完成后编译平台工程如下图所示: 编译完平台工程后,平台工程的搭建就完成了。现在可以创建Linux应用工程了。
1.2 创建Linux应用工程点击Vitis菜单栏的“File->New->ApplicationProject…”,创建应用工程,如下图所示: 设置工程名为“hello_world”,如下图所示: 单击底部的“Next >”,进入下一页面,选择刚才新建的“appDev_Linux_plat”,如下图所示: 图 8.2.3 选择appDev_Linux_plat 单击底部的“Next >”,进入下一页面,如下图所示: Domain保持默认即可,Language默认为C,也可以选择C++,这里保持默认,使用C语言开发应用,然后单击底部的“Next >”,进入下一页面,如图 8.2.5所示。 可以看到有两个模板,第一个是Linux空白应用工程模板,第二个是“LinuxHello World”工程模板。我们选择“LinuxHello World”工程模板,点击底部的“Finish”,进入图 8.2.6所示界面。 关于Vitis的使用想必就不用多介绍了,毕竟我们在《DFZU2EG_4EV MPSoC嵌入式Vitis开发指南》中已经使用的够多了。我们展开左侧的“hello_world”下的src,可以看到helloworld.c文件,双击可以看到右侧的源码,是不是很简单,跟我们平时写的C应用没区别。 编译hello_world工程。至此,Linux应用工程的创建就完成了。下面我们将介绍如何将该工程的elf文件运行在我们第六章搭建的Linux上。 有两种方式,一种是通过Vitis软件自带的TCF Agent,另一种是通过其他方式如NFS、ssh等将文件共享到或传到开发板上的Linux系统中。 注意无论使用什么方式,都需要开发板连接网线,且与Windows系统处于同一网络。 说一下运行前的准备工作: 先在开发板上运行我们第六章搭建的Linux系统,并接上网线,在串口上位机中输入ifconfig命令或“ip a s”命令查看以太网的IP地址,关于开发板以太网的使用请参考7.7小节以太网的使用。从下图可见笔者使用的开发板的IP地址为192.168.2.218,该地址后面会使用到。 完成准备工作后,我们先来看下TCF Agent方式,然后试下NFS方式和SSH方式。
1.3 使用TCF Agent方式运行在Vitis界面,右键点击“hello_world”应用工程,在弹出的菜单中选择“Run As—>RunConfiguration”,如图 8.3.1所示。 图8.3.1 双击“Linux Agent[defalut]” 在弹出的界面中,双击“Single Applicatuin Debug”,会自动创建“Debugger_hello_world-Default”,如下图所示: 输入Host的IP地址,也就是开发板的IP地址,笔者的为192.168.2.218。输入IP地址完成后,点击“Test Connection”,如果出现下图所示的结果,表示连接测试成功,Linux TCF Agent服务运行正常,可以与主机(开发板)连接。点击“OK”按钮,完成设置。 完成图 8.3.5的1和2之后,我们点击3处的“Apply”,然后点击4处的“Run”,如下图所示: 在Console终端可以看到Hello World输出,表明程序在Linux上运行成功,如下图所示: 1.4 使用NFS共享方式运行在4.4.1节我们使用/home/cx/workspace/nfs文件夹供nfs服务器使用,所以首先我们将工程的elf文件复制到Ubuntu虚拟机的该文件夹下。 复制完成后,我们在开发板上挂载Ubuntu主机的NFS目录,在挂载之前先要知道Ubuntu主机的IP地址,使用ifconfig命令或“ip a s”命令查询到笔者的Ubuntu主机的IP地址为192.168.2.134。在连接到开发板的串口上位机如Putty中输入如下命令进行挂载: - mount -t nfs -o nolock 192.168.2.134:/home/cx/workspace/nfs/mnt
复制代码其中192.168.2.134为笔者的Ubuntu主机IP地址,/mnt为挂载到开发板的目录。 在串口终端中输入”ls /mnt”可以看到hello_world.elf文件,输入如下命令执行该elf文件: - chmod +x /mnt/hello_world.elf #赋予可执行权限
- /mnt/hello_world.elf #执行
复制代码执行结果如下图所示: 可以看到打印出“Hello World”信息,表明执行成功。
1.5 使用SSH方式运行SSH方式是将工程的elf文件传到开发板上的Linux系统中,在Ubuntu主机终端中输入如下命令将elf文件传到开发板的Linux系统中(上一节已经工程的elf文件复制到/home/cx/workspace/nfs文件夹): - scp /home/cx/workspace/nfs/hello_world.elf root@192.168.2.132:/home/root
复制代码上面命令的192.168.2.132为笔者使用的开发板的IP地址,/home/root表示传到开发板的该目录下,也就是root用户所在的目录。 执行结果如下图所示: 需要输入开发板上Linux系统的root用户密码,默认为”root”。传输完成后,在串口终端中输入“ls”会看到有一个hello_world.elf文件。输入“./hello_world.elf”会打印出“Hello World”信息,表明运行成功。在串口上位机中输入的命令及结果如下图所示: 1.6 Vitis开发Linux外设前面我们用Vitis开发了Linux最基础的HelloWorld应用,其实我们还可以用Vitis开发Linux外设,比如按键和LED。我们将helloworld.c的内容替换成如下内容: - <font face="Tahoma" size="3">#include<stdio.h>
- #include<stdlib.h>
- #include<time.h>
- #include<fcntl.h>
- #include<signal.h>
- #include<pthread.h>
- #include<linux/input.h>
-
- #defineLED_BRIGHTNESS "/sys/class/leds/ps_led1/brightness"
- #defineLED_TRIGGER "/sys/class/leds/ps_led1/trigger"
- #defineINPUT_EVENT "/dev/input/event0"
- #defineLED_MAX_SPEED 10
- #definePERIOD_COEFF 16000
-
- unsigned int led_speed;
- pthread_mutex_t lock;
-
- /* Blink LED */
- static void *LEDMod(void *dummy)
- {
- unsigned int led_period;
- int tmp;
- tmp = open(LED_BRIGHTNESS,O_WRONLY);
- if (tmp< 0)
- exit(1);
- while (1){
- pthread_mutex_lock(&lock);
- led_period = (LED_MAX_SPEED- led_speed) * PERIOD_COEFF;
- pthread_mutex_unlock(&lock);
-
- write(tmp,"1",2);
- usleep(led_period);
- write(tmp,"0",2);
- usleep(led_period);
- }
- }
-
- int main()
- {
- pthread_t pth;
- struct input_event ev;
- int tmp;
- int key_code;
- int size = sizeof(ev);
-
- /*Configure LED */
- led_speed = 5;
- tmp = open(LED_TRIGGER,O_WRONLY);
- if (tmp< 0)
- return 1;
- if (write(tmp,"default-on",10) !=10) {
- printf("Errorwriting trigger");
- return 1;
- }
- close(tmp);
- printf("ConfiguredLED for use\n");
-
- /*Create thread */
- pthread_mutex_init(&lock, NULL);
- pthread_create(&pth,NULL, LEDMod,"Blinking LED...");
-
- /*Read event0 */
- tmp = open(INPUT_EVENT,O_RDONLY);
- if (tmp< 0){
- printf("\nOpen" INPUT_EVENT " failed!\n");
- return 1;
- }
- /* Read and parse event, update global variable*/
- while (1){
- if (read(tmp,&ev, size) < size) {
- printf("\nReadingfrom " INPUT_EVENT " failed!\n");
- return 1;
- }
-
- if (ev.value== 1 && ev.type == 1) { /* Down press only */
- key_code =ev.code;
- if (key_code== KEY_DOWN) { /* lower speed */
- /* Protect from concurrent read/write */
- pthread_mutex_lock(&lock);
- if (led_speed> 0)
- led_speed -=1;
- pthread_mutex_unlock(&lock);
- } else if (key_code == KEY_UP){ /* raise speed */
- pthread_mutex_lock(&lock);
- if (led_speed< 9)
- led_speed += 1;
- pthread_mutex_unlock(&lock);
- }
- printf("Speed:%i\n", led_speed);
- usleep(1000);
- }
- }
- }</font>
复制代码然后编译应用工程,会出现如下图所示错误: 出错的原因是缺少相应库——pthread库,现在我们来添加pthread库。鼠标右键点击“hello_world”应用工程,在弹出的菜单中选择“C/C++ Build Settings”,如下图所示: 图 8.6.2 “C/C++ BuildSettings” 添加pthread库,添加方式如下图所示: 添加完成后,点击该设置界面右下角的“Apply and Close”。再次编译应用工程,编译完成后下载,结果如下图所示: 可以看到开发板上的PS_LED1灯闪烁,按开发板上的PS_KEY1和PS_KEY2可以控制PS_LED1灯的闪烁频率。 当然了也可以用Vitis调试应用工程,此处就不介绍了。
1.7 扩展阅读 |