物联网的时代怎么能离开一系列的网络应用,做为物联网操作系统本篇文章以移植wget & cURL为例来说明一些GNU应用如何移植到rt-smart/树莓派上。
RT-Thread Smart在用户态是以全POSIX的方式来兼容已有的UNIX应用程序,选择的是musl libc,同时对其中的一些底层做相应的对接和适配,例如UNIX中常见的fork/vfork,pipe系统调用,而对于pthreads,musl libc中则大量的用到了futex,也在smart上做了对接。
对于网络客户端应用,这里选择的是wget和cURL两个开源网络应用:
wget 是一个从网络上自动下载文件的自由工具,支持通过 HTTP、HTTPS、FTP 三个最常见的 TCP/IP协议 下载,并可以使用 HTTP 代理。"wget" 这个名称来源于 “World Wide Web” 与 “get” 的结合。
cURL是一个利用URL语法在命令行下工作的文件传输工具,1997年首次发行。它支持文件上传和下载,所以是综合传输工具,但按传统,习惯称cURL为下载工具。cURL还包含了用于程序开发的libcurl。
移植前的准备
在移植之前,我们需要先获得wget和curl的源代码。我们在rt-smart sdk的userapps目录下创建一个gnu-apps目录,下载对应版本的代码并进行解压:
1~/workspace/rtthread-smart/userapps$ mkdir gnu-apps
2
3# 下载wget及cURL,并解压到wget和cURL目录下
4~/workspace/rtthread-smart/userapps$ cd gnu-apps
5~/workspace/rtthread-smart/userapps$ mkdir curl
6~/workspace/rtthread-smart/userapps$ tar jxf curl-7.76.1.tar.bz2
7
8~/workspace/rtthread-smart/userapps$ mkdir wget
9~/workspace/rtthread-smart/userapps$ tar zxf wget-1.21.1.tar.gz
因为编译rt-smart的环境和编译Linux应用程序的环境并不完全相同,可以针对rt-smart创建一些公共的变量,这样可以在不同的应用程序移植时提供方便,可以在gnu-apps目录下创建config.sh脚本
1#!/bin/bash23# 指向userapps目录的变量4UROOT_DIR=${PWD}/../..56export RTT_EXEC_PATH=${UROOT_DIR}/../tools/gnu_gcc/arm-linux-musleabi_for_x86_64-pc-linux-gnu/bin7export PATH=$RTT_EXEC_PATH:$PATH89export CROSS_COMPILE="arm-linux-musleabi"
10export CFLAGS="-march=armv7-a -marm -msoft-float -D__RTTHREAD__ -O0 -g -gdwarf-2 -Wall -n --static"
11
12export AR=${CROSS_COMPILE}-ar
13export AS=${CROSS_COMPILE}-as
14export LD=${CROSS_COMPILE}-ld
15export RANLIB=${CROSS_COMPILE}-ranlib
16export CC=${CROSS_COMPILE}-gcc
17export CXX=${CROSS_COMPILE}-g++
18export NM=${CROSS_COMPILE}-nm
移植GNU软件包
移植wget
wget是采用configure & make的方式来编译,可以准备一份编译脚本,设置一定的环境变量来进行编译,以下是编译脚本清单:
1#!/bin/bash23source "../config.sh"45APP_NAME="wget"6VERSION="1.21.1"7APP_DIR=${APP_NAME}-${VERSION}89RT_DIR=${UROOT_DIR}/sdk/rt-thread
10RT_INC=" -I${UROOT_DIR}/apps/${APP_DIR} -I${RT_DIR}/include -I${RT_DIR}/components/dfs -I${RT_DIR}/components/drivers -I${RT_DIR}/components/finsh -I${RT_DIR}/components/net -I${UROOT_DIR}/sdk/include"
11
12export CPPFLAGS=${RT_INC}
13export LDFLAGS="-L${UROOT_DIR}/sdk/lib -L${RT_DIR}/lib"
14
15export LIBS="-T ${UROOT_DIR}/linker_scripts/arm/cortex-a/link.lds -march=armv7-a -marm -msoft-float -L${RT_DIR}/lib -Wl,--whole-archive -lrtthread -Wl,--no-whole-archive -n -static -Wl,--start-group -lc -lgcc -lrtthread -Wl,--end-group"
16
17cd ${APP_DIR}
18./configure \
19 --prefix=${UROOT_DIR}/sdk \
20 --target=${CROSS_COMPILE} \
21 --host=${CROSS_COMPILE} \
22 --build=i686-pc-linux-gnu \
23 --without-zlib \
24 --with-ssl=no \
25 --disable-threads \
26 --disable-debug
27
28make clean
29make V=1
移植cURL
cURL和wget类似,也是采用configure & make的结构,类似的build.sh脚本清单如下:
1#!/bin/bash23# Get initial variables4source "../config.sh"56APP_NAME="curl"7VERSION="7.76.1"8APP_DIR=${APP_NAME}-${VERSION}9
10RT_DIR=${UROOT_DIR}/sdk/rt-thread
11RT_INC=" -I${UROOT_DIR}/apps/${APP_DIR} -I${RT_DIR}/include -I${RT_DIR}/components/dfs -I${RT_DIR}/components/drivers -I${RT_DIR}/components/finsh -I${RT_DIR}/components/net -I${UROOT_DIR}/sdk/include"
12
13export CPPFLAGS=${RT_INC}
14export LDFLAGS="-L${UROOT_DIR}/sdk/lib -L${RT_DIR}/lib"
15
16export LIBS="-T ${UROOT_DIR}/linker_scripts/arm/cortex-a/link.lds -march=armv7-a -marm -msoft-float -L${RT_DIR}/lib -Wl,--whole-archive -lrtthread -Wl,--no-whole-archive -n -static -Wl,--start-group -lc -lgcc -lrtthread -Wl,--end-group"
17
18cd ${APP_DIR}
19
20./configure \
21 --prefix=${UROOT_DIR}/sdk \
22 --target=${CROSS_COMPILE} \
23 --host=${CROSS_COMPILE} \
24 --build=i686-pc-linux-gnu \
25 --without-ssl \
26 --without-zlib \
27 --disable-socketpair \
28 --disable-proxy \
29 --enable-debug
30
31make clean
32make V=1
通过上面这些脚本,可以发现把Linux的一些程序移植到rt-smart非常简单,主要是一些配置,然后再使用传统的configure & make方式即可。当然在一些点上,rt-smart和Linux还是存在差别的,这个会反映在一些configure执行参数的配置上,例如上面默认关闭了ssl,zlib等这些。
主要的几点需要特别注意的:
config.sh - 可以放置一些公共变量的定义 ,例如
-
UROOT_DIR - 指向userapps目录,因为在rt-smart sdk中,整体默认把工具链放在tools/gnu_gcc目录下;然后rtthread sdk以及编译后的头文件、库文件也会默认放在userapps/sdk目录下。
PATH - 需要把工具链路径加入到可执行路径中;
CROSS_COMPILE - 交叉工具链的前缀;
定义CFLAGS、CPPFLAGS、LDFLAGS、LIBS这些环境变量;
-
这里面会包括:需要的宏定义,例如针对RT-Thread会在命令行上主动定义__RTTHREAD__
使用wget和cURL程序
使用wget来下载网页的结果:
使用curl下载网页的结果:
我们看到,在上面的移植过程中,最主要的是加入简单的build.sh脚本,然后再使用Linux应用传统的configure & make模式来移植到了rt-smart,对wget & cURL的代码并未做更改。使用这样的方式,是因为希望遵循一个核心原则:兼容则兼容得最彻底,能够充分得使用Linux下丰富的软件生态,我们甚至期待可以在rt-smart上把webkit浏览器运行起来,从而做到更佳的人机交互体验。
下集预告:
在很轻松的移植完wget & cURL,下一节我们将移植Linux下常用的工具集busybox。busybox会相对更复杂,不过带来的功能也会更多,例如包括了压缩/解压工具,http服务器、ftp服务器等。我们也将正式进入到rt-smart上复杂应用之旅。
学习活动
跟随本系列文章一起打卡学习RT-Thread Smart吧,学习期间在RT-Thread论坛分享学习心得或者提问答疑均可获得积分奖励,截止最后一篇连载文章完结的一周内,可兑换相应奖品!立即进群参与活动~
进群交流学习
RT-Thread线下技术培训:MQTT网关
本次培训RT-Thread将以ART-Pi为硬件平台+RT-Thread物联网操作系统提供MQTT网关原型,希望帮助工程师快速熟悉基于RT-Thread的项目开发流程,熟悉MQTT网关开发中所涉及到的技术要点如Modbus、MQTT、连网、文件系统、FTP、Bootloader、OTA、裁剪优化,提升产品开发速度。
我们将到访的城市有:上海(就在下周)、深圳(就在下周)、南京(就在下周)、广州(就在下周)、郑州、北京、武汉、天津、成都、西安
长按识别上方二维码报名
你可以添加微信17775982065为好友,注明:公司+姓名,拉进 RT-Thread 官方微信交流群!
???????????? 点击阅读原文报名培训