当前位置: 首页 > 工具软件 > Go Cortex > 使用案例 >

Go 在STM32MP157C 上跑起来!

胡俊美
2023-12-01

现代嵌入式系统中免不了需要网络功能,因此,开发诸如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 电脑上非常顺利。

 兴奋之余,先发出本博文。下面要做两件事情:

编译一个STM32MP157C 上运行的完整的web 应用程序

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)
}

在STM32MP157C上,开发一个Go 程序库,让C++调用

这个问题貌似容易,却花费了我许多时间。如果不了解,请参考我的博文:

ubuntu 下搭建STM32MP157的交叉编译环境

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

 

 类似资料: