Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Linux
qemu-vexpress-a9
原创征文
linux下搭建rtthread_qemu
发布于 2023-07-07 08:44:17 浏览:832
订阅该版
[tocm] # 1.获取RT-Thread以及env工具 ## 1.1 源码包获取 RT-Thread源码的获取方式有多种,可以是官网浏览器下载、云盘下载、git获取,强烈推荐git,因为使用git可以很方便的切换各种版本的rtthread,但是前提是要先安装git,linux下的安装方法不多叙述。这里不推荐拷贝windows系统里面的源码包,因为windows与linux的文件换行符等差异,会导致各种坑,所以还是老老实实的重新下载源码包吧。 git方式国内建议使用gitee。 在终端输入 ```shell git clone http://gitee.com/rtthread/rt-thread.git ``` 即可获取rtthread最新版的源码包,但是由于兼容问题不太推荐最新的包,终端输入cd rt-thread 进入源码包后,使用git reset --hard + 某旧版本id可以快速切换到改旧版本的源码包,以4.1.1为例,在终端输入 ```shell git reset --hard aab2428d4177a02cd3b0fd020e47a88de379a6ab ``` 版本的id号可以通过 git log查看,commit后的就是该版本 ![git版本回溯.png](https://oss-club.rt-thread.org/uploads/20230707/9c81360ec3e5ae564c0e364fa96be5ed.png.webp) ## 1.2 env工具 https://github.com/RT-Thread/env 可查看env工具相关信息,里面有几句信息: 对于中国大陆用户,请使用以下三行命令进行下载,第一行是下载,第二行修改权限,第三行安装 ```shell wget https://gitee.com/RT-Thread-Mirror/env/raw/master/install_ubuntu.sh chmod 777 install_ubuntu.sh ./install_ubuntu.sh --gitee ``` ### Prepare Env PLAN A: Whenever start the ubuntu system, you need to type command `source ~/.env/env.sh` to activate the environment variables. or PLAN B: open `~/.bashrc` file, and attach the command `source ~/.env/env.sh` at the end of the file. It will be automatically executed when you log in the ubuntu, and you don't need to execute that command any more. 意思就是有两种方法来配置env,推荐第二种,输入 ```shell gedit ~/.bashrc ``` 再在文件最后一行输入source ~/.env/env.sh ## 1.3 编译调试所需工具 除此之外,需安装编译工具gcc-arm-none-eabi、scons、gdb调试工具等,输入以下指令下载安装 ```shell sudo apt-get install gcc-arm-none-eabi sudo apt-get install qemu-system-arm sudo apt-get install scons sudo apt-get install binutils-arm-none-eabi ``` 通常编译器都自动安装到/usr/bin下了,安装好之后需进入rt-thread/bsp/qemu-vexpress-a9,打开rtconfig.py文件,37行左右会指定编译工具,设置为gcc,路径为/usr/bin ```shell PLATFORM = 'gcc' EXEC_PATH = r'/usr/bin' ``` # 2.运行QEMU看看效果 在windows下是运行qemu.bat,linux下则是qemu.sh。进入到rt-thread/bsp/qemu-vexpress-a9下,输入 ```shell ./qemu.sh ``` 即可启动虚拟的开发板。如果运行不了qemu.sh,则需要使用 ```shell chmod +x qemu.sh ``` 为该文件增加“可执行”的属性。 如果还是运行不了,可能是没有生成rtthread.elf的文件,qemu.sh脚本里面就一句话,作用是使用qemu创建机器,运行rtthread.elf。 输入scons可编译工程生成rtthread.elf 运行效果如下图,已经进入了虚拟开发板的命令行界面。 ![运行qemu.png](https://oss-club.rt-thread.org/uploads/20230707/e67c8a00834231c6a5d98209943609da.png.webp) 输入 Ctrl + c 可退出 # 3.修改main.c并编译运行 打开rt-thread/bsp/qemu-vexpress-a9/application下的main.c,可以看到如下内容,经典的hello world ```C #include
#include
#include
int main(void) { printf("Hello RT-Thread!\n"); return 0; } ``` 尝试修改一下,printf("Hello RT-Thread this is a test \n"); 保存后,再linux终端rt-thread/bsp/qemu-vexpress-a9/目录下,输入scons,工程便开始编译 ![scons生成elf.png](https://oss-club.rt-thread.org/uploads/20230707/2afb8d5f3ffe77522fc2f60ac57d799c.png.webp) 最终提示生成了rtthread.elf文件。运行./qemu.sh,可以看到启动后打印修改的内容 ![运行./qemu.sh.png](https://oss-club.rt-thread.org/uploads/20230707/76baca0a1ab6127b8cef1ad37434c128.png) # 4.搭建VSCode,开发更方便 很多人不习惯使用vi编辑器、gedit编辑器修改文件,不习惯使用gdb进行调试(我就是),搭建VSCode是很有必要的,看代码很方便,调试界面也很友好。 VSCode的下载安装不多作介绍,简介就是宇宙最强万能写代码工具。 这里还要借助VSCode里面的插件: RT-Thread Studio ![vscode插件.png](https://oss-club.rt-thread.org/uploads/20230707/23cd5136931805a7e065f203d6e38f24.png.webp) 安装好之后,按照扩展设置,添加几个必要的路径: 1.rtthread源码包路径 2.gdb路径:/usr/bin/arm-none-eabi-gdb 3.Toolchain_Loacation工具链 gcc编译器的路径:/usr/bin 使用左侧的RT按钮,即可打开一个工程。鼠标悬停再工程上,可看到编译、调试等选项: ![rt插件.png](https://oss-club.rt-thread.org/uploads/20230707/921ae723cbf04d8c3a273a54eafe327d.png) 如此,就很方便了。调试起来毫无压力。 ![debug.png](https://oss-club.rt-thread.org/uploads/20230707/5372ec354a37b4f3d20e889271aeffaf.png.webp) # 5.为QEMU增加网卡 到这里,基本的环境就已经搭建好了。但是需要使用更多的接口,还需要了解以下QEMU。 QEMU的本质是使用电脑的硬件,虚拟出一个开发板,也就是说这个开发板使用的接口实际上都是你的电脑的接口。 这一步,为QEMU增加网卡。根据RT-Thread文档中心的指引,在windows下使用qemu,添加网卡是首先安装一个虚拟网卡,然后将真实的可上网的网卡共享到虚拟网卡,然后再启动虚拟开发板的时候设置启动参数,将虚拟网卡作为启动项,当作虚拟开发板的网卡。 Linux中也是如此。大概的示意图如下图所示。 ![网卡连接.png](https://oss-club.rt-thread.org/uploads/20230707/c4cc9391936ea2def34bd71b6eee6518.png) 需要先安装网桥软件包 ```shell sudo apt-get install bridge-utils sudo apt-get install uml-utilities ``` 参照网上的例子改写了qemu.sh,如下。其中ens33和ens36为我电脑上的两个网卡,一个是以太网(VMware实体window和linux虚拟机NET模式),一个是WIFI(VMware桥接模式,linux和windows共用wifi)。 ```shell if [ ! -f "sd.bin" ]; then dd if=/dev/zero of=sd.bin bs=1024 count=65536 fi #检测是否可上网 function network() { local ret_code=`curl -I -s --connect-timeout 1 www.baidu.com -w %{http_code} | tail -n1` if [ "x$ret_code" = "x200" ]; then return 1 #网络畅通 else return 0 #不通 fi return 0 } network if [ $? -eq 0 ];then echo "网络不通畅" #不使用dhcp sudo ifconfig ens33 down if [ ! -d /sys/class/net/br0 ];then sudo brctl addbr br0 #添加名为br0的网桥 sudo brctl addif br0 ens33 #网桥上添加接口ens33 sudo brctl stp br0 off #关闭生成树协议 sudo brctl setfd br0 1 #设置转发延迟 sudo brctl sethello br0 1 #设置hello时间 fi sudo ifconfig br0 192.168.75.12 promisc up #启用br0接口 sudo ifconfig ens33 192.168.75.128 promisc up #启用网卡接口 sudo dhclient br0 #从dhcp服务器获得br0IP地址 sudo brctl show br0 #查看虚拟网桥列表 sudo brctl showstp br0 #查看br0各接口信息 tunctl -t tap0 -u root brctl addif br0 tap0 ifconfig tap0 0.0.0.0 promisc up brctl showstp br0 else sudo ifconfig ens36 down #关闭能连接的主机网卡 if [ ! -d /sys/class/net/br0 ];then sudo brctl addbr br0 #添加名为br0的网桥 sudo brctl addif br0 ens36 #网桥上添加接口ens36 sudo brctl stp br0 off #关闭生成树协议 sudo brctl setfd br0 1 #设置转发延迟 sudo brctl sethello br0 1 #设置hello时间 fi sudo ifconfig br0 0.0.0.0 promisc up #启用br0接口 sudo ifconfig ens36 0.0.0.0 promisc up #启用网卡接口 sudo dhclient br0 #从dhcp服务器获得br0IP地址 sudo brctl show br0 #查看虚拟网桥列表 sudo brctl showstp br0 #查看br0各接口信息 tunctl -t tap0 -u root brctl addif br0 tap0 ifconfig tap0 0.0.0.0 promisc up brctl showstp br0 fi sudo qemu-system-arm \ -M vexpress-a9 \ -smp cpus=2 \ -kernel rtthread.bin \ -serial stdio \ -sd sd.bin \ -net nic -net tap,ifname=tap0 ``` 修改完之后,保存,运行qemu.sh,在rtthread终端ping一个网站即可ping通,到此就可以进行下一步学习了。B站上RTThread官方账号有网络课程专栏【7天入门网络编程】,搭配使用真香。若ping不通则有可能是你的linux系统本身就上不了网,所以网桥一定要连接到可以上网的网卡才能往下走。ping不通移步第6节 VMWare虚拟机网卡配置简介,参考一下我的配置。 ![ping通外网.png](https://oss-club.rt-thread.org/uploads/20230707/30b3970d1afbef29f7cb27973a9e352c.png.webp) 此时启动另一个终端,输入ifconfig,可以看到网卡的信息,里面有qemu.sh文件里新建的br0网桥、本机网卡ens33、ens36、lo回环、tap0虚拟网卡 ![查看网卡.png](https://oss-club.rt-thread.org/uploads/20230707/db2bdffe6e9dd96e4a63f2a40692d198.png.webp) # 6.VMWare虚拟机网卡配置简介 以下给出我的参考配置 在windows平台下使用VMware,windos下网络适配器为如下配置,其中WLAN就是可以上网的Wifi,虚拟网卡VMnet8用于NET模式进行windows和Ubuntu的文件共享、SSH等 ![网络适配器.png](https://oss-club.rt-thread.org/uploads/20230707/779c55ab9bf21d5281bd2a564d7ae725.png) 在虚拟机设置里面使用VMnet8和VMnet0,其中VMnet8设置为NAT模式,VMnet0设置为自定义桥接模式。在虚拟网络编辑器里设置VMnet0桥接目标为我的WIFI,即RZ608 Wi-Fi 6E 80MHz。 ![虚拟机设置.png](https://oss-club.rt-thread.org/uploads/20230707/1bc95c069e17578319cb3d75a67ffa7c.png) ![虚拟网络设置.png](https://oss-club.rt-thread.org/uploads/20230707/29af06e78b351f1caed74e7a00ef7507.png) 设置完成后,在Ubuntu中使用ifconfig就可以看到这两个网卡了,或者在图形界面中也可以设置,但是Ubuntu都认为这两个网卡都是有线网卡 ![linux中的网卡.png](https://oss-club.rt-thread.org/uploads/20230707/16a7cb4fca72d6cc27036967d27529f3.png) 这时在去ping一个网站就可以ping通了,如果ping不通可以尝试关闭再重新打开。 # 7.TCP客户端示例 演示TCP客户端示例。 在windows下打开一个TCP服务器(咱也不知道为什么用windows,正好电脑上有,用着方便) ![TCP实验.png](https://oss-club.rt-thread.org/uploads/20230707/0e4081a4ae5515eafe507ac22749ebda.png.webp) 在RT-Thread命令行中输入tcp_client命令 + 服务器IP +服务器端口号 ```shell msh /> tcp_client 192.168.75.1 7001 ``` ![qemu运行结果.png](https://oss-club.rt-thread.org/uploads/20230707/509df2a01651aae7e991d1950c7dbbd2.png.webp) ![TCP.png](https://oss-club.rt-thread.org/uploads/20230707/0a656205502f395169e2f6e7c8c23eb6.png) 源码见文末尾,该源码包通过sons --menuconfig弹出裁剪配置界面,添加 ``` RT-Thread online packages ----> miscellaneous packages ----> samples:kernel and components samples ---> a network_samples package for rt-thread ----> [network] tcp client ``` 即可获得,添加完成之后,在终端输入 ``` pkgs --update ``` 自动下载TCP示例源代码,然后直接scons编译即可使用 ```C /* * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * */ /* * 程序清单:tcp 客户端 * * 这是一个 tcp 客户端的例程 * 导出 tcpclient 命令到控制终端 * 命令调用格式:tcpclient URL PORT * URL:服务器地址 PORT::端口号 * 程序功能:接收并显示从服务端发送过来的信息,接收到开头是 'q' 或 'Q' 的信息退出程序 */ #include
#include
/* 使用BSD socket,需要包含socket.h头文件 */ #include
#include
#include
#include
#define BUFSZ 1024 static const char send_data[] = "This is TCP Client from RT-Thread."; /* 发送用到的数据 */ static void tcpclient(int argc, char **argv) { int ret; char *recv_data; struct hostent *host; int sock, bytes_received; struct sockaddr_in server_addr; const char *url; int port; if (argc < 3) { rt_kprintf("Usage: tcpclient URL PORT\n"); rt_kprintf("Like: tcpclient 192.168.12.44 5000\n"); return ; } url = argv[1]; port = strtoul(argv[2], 0, 10);//第2个参数字符串转为整形 端口号 /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */ host = gethostbyname(url); /* 分配用于存放接收数据的缓冲 */ recv_data = rt_malloc(BUFSZ); if (recv_data == RT_NULL) { rt_kprintf("No memory\n"); return; } /* 创建一个socket,类型是SOCKET_STREAM,TCP类型 */ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { /* 创建socket失败 */ rt_kprintf("Socket error\n"); /* 释放接收缓冲 */ rt_free(recv_data); return; } /* 初始化预连接的服务端地址 */ server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); server_addr.sin_addr = *((struct in_addr *)host->h_addr); rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero)); /* 连接到服务端 */ if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) { /* 连接失败 */ rt_kprintf("Connect fail!\n"); closesocket(sock); /*释放接收缓冲 */ rt_free(recv_data); return; } else { /* 连接成功 */ rt_kprintf("Connect successful\n"); } while (1) { /* 从sock连接中接收最大BUFSZ - 1字节数据 */ bytes_received = recv(sock, recv_data, BUFSZ - 1, 0); if (bytes_received < 0) { /* 接收失败,关闭这个连接 */ closesocket(sock); rt_kprintf("\nreceived error,close the socket.\r\n"); /* 释放接收缓冲 */ rt_free(recv_data); break; } else if (bytes_received == 0) { /* 默认 recv 为阻塞模式,此时收到0认为连接出错,关闭这个连接 */ closesocket(sock); rt_kprintf("\nreceived error,close the socket.\r\n"); /* 释放接收缓冲 */ rt_free(recv_data); break; } /* 有接收到数据,把末端清零 */ recv_data[bytes_received] = '\0'; if (strncmp(recv_data, "q", 1) == 0 || strncmp(recv_data, "Q", 1) == 0) { /* 如果是首字母是q或Q,关闭这个连接 */ closesocket(sock); rt_kprintf("\n got a 'q' or 'Q',close the socket.\r\n"); /* 释放接收缓冲 */ rt_free(recv_data); break; } else { /* 在控制终端显示收到的数据 */ rt_kprintf("\nReceived data = %s ", recv_data); } /* 发送数据到sock连接 */ ret = send(sock, send_data, strlen(send_data), 0); if (ret < 0) { /* 接收失败,关闭这个连接 */ closesocket(sock); rt_kprintf("\nsend error,close the socket.\r\n"); rt_free(recv_data); break; } else if (ret == 0) { /* 打印send函数返回值为0的警告信息 */ rt_kprintf("\n Send warning,send function return 0.\r\n"); } } return; } MSH_CMD_EXPORT(tcpclient, a tcp client sample); ``` 更多信息可查看官方文档中心 https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/tutorial/qemu-network/tcpclient/tcpclient 我的原创文章https://blog.csdn.net/weixin_43166744/article/details/131236821?spm=1001.2014.3001.5502
2
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
LICDCD
这家伙很懒,什么也没写!
文章
2
回答
3
被采纳
0
关注TA
发私信
相关文章
1
RT-Thread Studio 跨平台
2
Linux下Scons编译工程遇到宏定义的问题,如何解决?
3
Linux下开发rtthread,求资料
4
qemu-vexpress-a9运行 qemu-dbg.sh 提示错误
5
ART-Pi SDK在Linux环境下编译不通过问题
6
虚拟串口在Linux下的使用问题
7
linux命令行通过串口发送finsh指令无法执行
8
怎么移植linux上的软件
9
linux下使用RT-Thread Studio插件如何进行stlink下载
10
代码在ubuntu上编译不能运行
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
SFUD
msh
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1443
个答案
289
次被采纳
张世争
805
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部