现代嵌入式系统中免不了需要网络功能,因此,开发诸如web server,websocket ,json 等网络程序是必不可少的。虽然C/C++是开发嵌入式程序主要的程序设计语言,不过C/C++ 开发现代网络应用程序显得有点老态龙钟,力不从心。被Go ,java,python 甩几条大街。2019年,我们花费了整整一年的时间,将嵌入式网络软件的开发工具从C++ 迁移到了Go,软件开发的效率大幅度提升,我们的做法是在目标计算机(比如全志H6,瑞芯微RK3399 上安装Go 编译器。直接在目标机上开发程序。对于STM32MP157 而言,其硬件资源相对有限,我们采取了交叉编译的方式开发应用程序。C/C++ 当然没有任何问题。厂商提供了完整的交叉编译工具链。Go 怎么办? 我们确实回不去了,爱上Go 了。周末看了网络上一些文章介绍,Go 的交叉编译非常简单,只要设置一些环境变量,原来的X86 ubuntu 上的Go 可以直接编译出Arm 的目标代码。于是,迫不急待地测试了一下。
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello,Arm!")
return
}
(base) yao@yao-dc:~/yao2020/go2020$ GOOS=linux GOARCH=arm GOARM=7 go build -o helloarm test.go
(base) yao@yao-dc:~/yao2020/go2020$ scp helloarm root@192.168.31.194://home/root/workspace
helloarm 100% 1835KB 1.8MB/s 00:00
(base) yao@yao-dc:~/yao2020/go2020$ ssh root@192.168.31.194
myir
root@myir:~# cd workspace
root@myir:~/workspace# ./helloarm
Hello,Arm!
居然成功了,好神奇。整整一个周末都在努力地交叉编译C++的网络库restbed,ASIO。。。巴拉巴拉。。 没有一个成功了。没想到非常顺利地编译了Go,顺便说一句,在Win wsl ubuntu 上,我并没有试成功。而在X86 ubuntu 电脑上非常顺利。
兴奋之余,先发出本博文。下面要做两件事情:
package main
import (
"fmt"
"net/http"
)
func main(){
fmt.Println("Simply webserver\n")
fs := http.FileServer(http.Dir("./www"))
http.Handle("/", fs)
http.ListenAndServe(":3210", nil)
}
这个问题貌似容易,却花费了我许多时间。如果不了解,请参考我的博文:
GO 程序:
package main
import "C"
import (
"fmt"
"net/http"
)
//export webserver
func webserver(){
fmt.Println("Simply webserver\n")
fs := http.FileServer(http.Dir("./www"))
http.Handle("/", fs)
http.ListenAndServe(":3210", nil)
}
func main(){
}
1 .首先,要切换到STM32MP157 SDK 的环境,
source /home/yao/develop/stm32mp157c/Develop-Package/SDK/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
2 . 交叉编译Go 为C的库。
设置编译模式(buildmode=c-archive 为静态库,c-shared 为共享库
3 设置Go环境变量
CGO_ENABLED=1
GOOS=linux
GOARCH=arm
GOARM=7
CGO_ENABLED=1 GOOS=linux GOARCH=arm GOARM=7 go build -o libwebserver.a -buildmode=c-archive webserver.go
这是发现netdb.h 找不到的现象:于是,设置CGO_LDFLAGS 和CGO_CPPFLAGS
export CGO_CPPFLAGS="-I /home/yao/develop/stm32mp157c/Develop-Package/SDK/sysroots/cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi/usr/include -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -fPIC"
export CGO_LDFLAGS="-L/home/yao/develop/stm32mp157c/Develop-Package/SDK/sysroots/cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi/usr/lib -L/home/yao/develop/stm32mp157c/Develop-Package/SDK/sysroots/cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi/lib -L /home/yao/develop/stm32mp157c/Develop-Package/SDK/sysroots/cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi/usr/lib/arm-ostl-linux-gnueabi/9.3.0"
你可以使用go env 查看相关的设备
yao@minipc:~/develop/go/webServer$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/yao/.cache/go-build"
GOENV="/home/yao/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/yao/go_dev"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="arm-ostl-linux-gnueabi-ar"
CC="arm-ostl-linux-gnueabi-gcc"
CXX="arm-ostl-linux-gnueabi-g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-O2 -pipe -g -feliminate-unused-debug-types"
CGO_CPPFLAGS="-I /home/yao/develop/stm32mp157c/Develop-Package/SDK/sysroots/cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi/usr/include -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -fPIC"
CGO_CXXFLAGS="-O2 -pipe -g -feliminate-unused-debug-types"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-L/home/yao/develop/stm32mp157c/Develop-Package/SDK/sysroots/cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi/usr/lib -L/home/yao/develop/stm32mp157c/Develop-Package/SDK/sysroots/cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi/lib -L/home/yao/develop/stm32mp157c/Develop-Package/SDK/sysroots/cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi/usr/lib/arm-ostl-linux-gnueabi/9.3.0"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-mthumb -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 --sysroot=/home/yao/develop/stm32mp157c/Develop-Package/SDK/sysroots/cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build134359271=/tmp/go-build -gno-record-gcc-switches"
在这里搞了很长的时间,老时发现“Scrt1.o“ 无法找到的问题。后来无意中发现 在命令行去掉CC=arm-ostl-linux-gnueabi-gcc 反而好了,其实通过个go env 看到CC 已经设了。到底毛病在那里我也不清楚。
C 程序
#include <libwebserver.h>
void main(){
webserver();
}
$CC -I. -lpthread callweb.c libwebserver.a -o callweb
最后,小结命令行
source /home/yao/develop/stm32mp157c/Develop-Package/SDK/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
export CGO_CPPFLAGS="-I /home/yao/develop/stm32mp157c/Develop-Package/SDK/sysroots/cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi/usr/include -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 -fPIC"
export CGO_LDFLAGS="-L/home/yao/develop/stm32mp157c/Develop-Package/SDK/sysroots/cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi/usr/lib -L/home/yao/develop/stm32mp157c/Develop-Package/SDK/sysroots/cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi/lib -L /home/yao/develop/stm32mp157c/Develop-Package/SDK/sysroots/cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi/usr/lib/arm-ostl-linux-gnueabi/9.3.0"
CGO_ENABLED=1 GOOS=linux GOARCH=arm GOARM=7 go build -o libwebserver.a -buildmode=c-archive webserver.go
$CC -I. -lpthread callweb.c libwebserver.a -o callweb