1)实验平台:正点原子MPSoC开发板
2)平台购买地址:https://detail.tmall.com/item.htm?id=692450874670
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html
第八章使用Vitis开发Linux应用
上一章我们学习了在Petalinux搭建的Linux系统上基础外设的使用,本章我们以创建“Hello World”工程为例学习如何使用Vitis开发Linux应用以及如何让应用程序运行在Petalinux搭建的Linux系统上。运行方式本章介绍了三种,可根据个人喜好选择。
8.1创建基于Vitis的Linux平台工程
双击Windows系统桌面的Xilinx Vitis IDE 2019.2图标打开Vitis工具,弹出图 8.1.1所示的Lancher界面:
图 8.1.1 打开Vitis工具
设置Vitis Workspace文件夹,可以是任一文件夹,最好不要包括中文以及特殊字符,这里笔者选择的是F:\Mpsoc\appDev_Linux文件夹,然后点击“Launch”按钮,进入如下图所示界面:
图 8.1.2 创建Platform工程
单击“Create Platform Project”,即创建平台工程,进入下图所示界面:
图 8.1.3 平台工程配置选项
“Project name”栏输入平台工程名“appDev_Linux_plat”,其他保持默认,然后单击底部的“Next >”,进入下一页面,如图 8.2.5所示。
图 8.1.4 创建新的平台工程
选择“Create from hardware specification (XSA)”,然后单击底部的“Next >”,进入下一页面,如下图所示:
图 8.1.5 配置平台工程
“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文件夹,如下图所示:
图 8.1.7 设置Vitis平台工程
设置完成后编译平台工程如下图所示:
编译完平台工程后,平台工程的搭建就完成了。现在可以创建Linux应用工程了。
8.2创建Linux应用工程
点击Vitis菜单栏的“File->New->Application Project…”,创建应用工程,如下图所示:
图 8.2.1 创建应用工程
设置工程名为“hello_world”,如下图所示:
图 8.2.2 设置工程名
单击底部的“Next >”,进入下一页面,选择刚才新建的“appDev_Linux_plat”,如下图所示:
图 8.2.3 选择appDev_Linux_plat
单击底部的“Next >”,进入下一页面,如下图所示:
图 8.2.4 选择Domain
Domain保持默认即可,Language默认为C,也可以选择C++,这里保持默认,使用C语言开发应用,然后单击底部的“Next >”,进入下一页面,如图 8.2.5所示。
可以看到有两个模板,第一个是Linux空白应用工程模板,第二个是“Linux Hello World”工程模板。我们选择“Linux Hello World”工程模板,点击底部的“Finish”,进入图 8.2.6所示界面。
图 8.2.5 工程模板
图 8.2.6 Vitis界面
关于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,该地址后面会使用到。
图 8.2.7 开发板的IP地址
完成准备工作后,我们先来看下TCF Agent方式,然后试下NFS方式和SSH方式。
8.3使用TCF Agent方式运行
在Vitis界面,右键点击“hello_world”应用工程,在弹出的菜单中选择“Run As—>Run Configuration”,如图 8.3.1所示。
图 8.3.1 双击“Linux Agent[defalut]”
在弹出的界面中,双击“Single Applicatuin Debug”,会自动创建“Debugger_hello_world-Default”,如下图所示:
图 8.3.2 创建Linux Agent
图 8.3.3 输入Host的IP 地址
输入Host的IP地址,也就是开发板的IP地址,笔者的为192.168.2.218。输入IP地址完成后,点击“Test Connection”,如果出现下图所示的结果,表示连接测试成功,Linux TCF Agent服务运行正常,可以与主机(开发板)连接。点击“OK”按钮,完成设置。
图 8.3.4 连接测试成功
完成图 8.3.5的1和2之后,我们点击3处的“Apply”,然后点击4处的“Run”,如下图所示:
图 8.3.5 运行
在Console终端可以看到Hello World输出,表明程序在Linux上运行成功,如下图所示:
图 8.3.6 Console终端输出运行结果
8.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 #执行
执行结果如下图所示:
图 8.4.1 执行elf文件
可以看到打印出“Hello World”信息,表明执行成功。
8.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用户所在的目录。
执行结果如下图所示:
图 8.5.1 scp命令传输文件
需要输入开发板上Linux系统的root用户密码,默认为”root”。传输完成后,在串口终端中输入“ls”会看到有一个hello_world.elf文件。输入“./hello_world.elf”会打印出“Hello World”信息,表明运行成功。在串口上位机中输入的命令及结果如下图所示:
图 8.5.2 命令及结果
8.6Vitis开发Linux外设
前面我们用Vitis开发了Linux最基础的HelloWorld应用,其实我们还可以用Vitis开发Linux外设,比如按键和LED。我们将helloworld.c的内容替换成如下内容:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <signal.h>
#include <pthread.h>
#include <linux/input.h>
#define LED_BRIGHTNESS "/sys/class/leds/ps_led1/brightness"
#define LED_TRIGGER "/sys/class/leds/ps_led1/trigger"
#define INPUT_EVENT "/dev/input/event0"
#define LED_MAX_SPEED 10
#define PERIOD_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("Error writing trigger");
return 1;
}
close(tmp);
printf("Configured LED 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("\nReading from " 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);
}
}
}
然后编译应用工程,会出现如下图所示错误:
图 8.6.1 编译出错
出错的原因是缺少相应库——pthread库,现在我们来添加pthread库。鼠标右键点击“hello_world”应用工程,在弹出的菜单中选择“C/C++ Build Settings”,如下图所示:
图 8.6.2 “C/C++ Build Settings”
添加pthread库,添加方式如下图所示:
图 8.6.3 添加pthread库
添加完成后,点击该设置界面右下角的“Apply and Close”。再次编译应用工程,编译完成后下载,结果如下图所示:
在这里插入图片描述
图 8.6.4 输出信息
可以看到开发板上的PS_LED1灯闪烁,按开发板上的PS_KEY1和PS_KEY2可以控制PS_LED1灯的闪烁频率。
当然了也可以用Vitis调试应用工程,此处就不介绍了。
8.7扩展阅读
在Vitis IDE 中构建 Linux 应用程序:https://china.xilinx.com/video/software/building-linux-application-vitis.html