搜索
bottom↓
回复: 24

go语言开发新塘NUC980之点灯

[复制链接]

出0入36汤圆

发表于 2022-2-16 13:13:18 | 显示全部楼层 |阅读模式
本帖最后由 redworlf007 于 2022-2-16 13:16 编辑

go语言在Windows上写好,直接编译成arm v5的程序,放到开发板上跑,不用自己搭建交叉编译环境。
Linux系统做成glibc的库。

以下是GPIO相关的函数,做成了一个包。

package gpio

import (
        "fmt"
        "os"
        "strconv"
)

//GpioMapSlice 定义一个切片map表
var GpioMapSlice = make([]map[byte]byte, 9)

//GpioMapInit 初始化GPIO编号和驱动编号的对应表。
//PA15:A对应0,PA15的驱动编号计算方式、:0*32+15
func GpioMapInit() {
        for index, _ := range GpioMapSlice {
                GpioMapSlice[index] = make(map[byte]byte, 1)
                GpioMapSlice[index][byte(index)+65] = byte(index)
        }

        // for index, value := range GpioMapSlice {
        //         fmt.Printf("index:%d value:%v\n", index, value)
        // for K2, value := range GpioMapSlice[index] {
        //         // if K2 == 'G' {
        //         fmt.Printf("K2:%c value:%v\n", K2, value)
        //         // }
        //}
        // }
}

//FindPinNum 查表计算驱动编号
func FindPinNum(p byte, a int) (Driver_number int) {
        for index, _ := range GpioMapSlice {
                //fmt.Printf("index:%d value:%v\n", index, value)
                for K2, value := range GpioMapSlice[index] {
                        if K2 == p {
                                //fmt.Printf("K2:%c value:%v\n", K2, value)
                                Driver_number = int(value)*32 + a
                                return Driver_number
                        }
                }
        }
        return -1
}

//GpioGetGpioNumber 检查输入的GPIO号是否正确
func GpioGetDriverNumber(Port_Name string) (Driver_number int) {
        //fmt.Println(Port_Name)
        Driver_number = -1
        var Slice = make([]byte, 4, 8)
        Slice = []byte(Port_Name)
        if Slice[0] == 'P' {
                if Slice[1] >= 'A' && Slice[1] <= 'I' {
                        var a, _ = strconv.Atoi(string(Slice[2:]))
                        if a >= 0 && a <= 31 {
                                Driver_number = FindPinNum(Slice[1], a)
                                return Driver_number
                        } else {
                                Driver_number = -1
                                fmt.Println("Port_Name错误-1")
                        }
                } else {
                        fmt.Println("Port_Name错误-2")
                        Driver_number = -2
                }
        } else {
                fmt.Println("Port_Name错误-3")
                Driver_number = -3
        }
        return Driver_number
}

//InitGpio 生成Linux系统里面的gpio文件
func InitGpio(Port_Name string) {

        num := GpioGetDriverNumber(Port_Name)
        file, err := os.OpenFile("/sys/class/gpio/export", os.O_WRONLY, 0666)
        if err != nil {
                fmt.Println("open file failed, err:", err)
                return
        }
        defer file.Close()
        var str = fmt.Sprintf("%d", num)
        //fmt.Println(str)
        file.WriteString(str)
}

//SetGpioDirection 设置GPIO方向,in:输入,out:输出
func SetGpioDirection(Port_Name string, Direction string) {
        num := GpioGetDriverNumber(Port_Name)
        var strs = fmt.Sprintf("/sys/class/gpio/gpio%d/direction", num)
        file, err := os.OpenFile(strs, os.O_RDWR, 0666)
        if err != nil {
                fmt.Println("open file failed, err:", err)
                return
        }
        defer file.Close()
        file.WriteString(Direction)
}

//WriteGpioValue 设置GPIO输出高低电平,1:高电平,0:低电平
func WriteGpioValue(Port_Name string, value byte) {
        num := GpioGetDriverNumber(Port_Name)
        var strs = fmt.Sprintf("/sys/class/gpio/gpio%d/value", num)
        file, err := os.OpenFile(strs, os.O_RDWR, 0666)
        if err != nil {
                fmt.Println("open file failed, err:", err)
                return
        }
        defer file.Close()
        var str = fmt.Sprintf("%d", value)
        //fmt.Println(str)
        file.WriteString(str)
}

*************************************************************************************************************************

*************************************************************************************************************************
//以下是main文件


package main

import (
        "fmt"
        "gpio_test/gpio"
        "sync"
        "time"
)

var wg sync.WaitGroup

//Bee_PA8 蜂鸣器
func Bee_PA8() {

        for i := 0; i < 6; i++ {
                gpio.WriteGpioValue("PA8", 1)
                time.Sleep(time.Millisecond * 500)
                gpio.WriteGpioValue("PA8", 0)
                time.Sleep(time.Millisecond * 500)
        }

        wg.Done()
}

//LED_PC13 绿色指示灯
func LED_PC13() {
        for {
                gpio.WriteGpioValue("PC13", 1)
                time.Sleep(time.Millisecond * 500)
                gpio.WriteGpioValue("PC13", 0)
                time.Sleep(time.Millisecond * 500)
        }
        //wg.Done()
}

//LED_PC13 红色指示灯
func LED_PC14() {
        for {
                gpio.WriteGpioValue("PC14", 1)
                time.Sleep(time.Millisecond * 1000)
                gpio.WriteGpioValue("PC14", 0)
                time.Sleep(time.Millisecond * 1000)
        }
        //wg.Done()
}

func main() {

        gpio.GpioMapInit() //初始化IO映射表

        gpio.InitGpio("PA8")
        gpio.SetGpioDirection("PA8", "out")

        gpio.InitGpio("PC13")
        gpio.SetGpioDirection("PC13", "out")

        gpio.InitGpio("PC14")
        gpio.SetGpioDirection("PC14", "out")

        wg.Add(1)
        Bee_PA8()

        wg.Add(1)
        go LED_PC13()

        wg.Add(1)
        go LED_PC14()

        wg.Wait()
        fmt.Println("进程退出")

}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出25入0汤圆

发表于 2022-2-16 13:21:02 | 显示全部楼层
num980支持payhon吗,有python点灯的例子没?   go比python好在哪里?

出0入33汤圆

发表于 2022-2-16 13:25:17 来自手机 | 显示全部楼层
我一个golang的工程里,有几十上百个 if err != nil {。??

出0入36汤圆

 楼主| 发表于 2022-2-16 13:26:29 | 显示全部楼层
hspydf 发表于 2022-2-16 13:21
num980支持payhon吗,有python点灯的例子没?   go比python好在哪里?
(引用自2楼)

Python可以的,把Python解释器做到系统里面就好了。

Python我们在NUC972上的用过,Python解释器自己就要大概占40M的空间,系统启动的时候挂在文件系统非常慢,Python解释器启动非常慢,Python有的库需要交叉编译,不一定能编译的过。

如果所有的代码都是用go写的,那么可以不需要自己搭建交叉编译环境,在Windows上写好程序,直接在Windows上编译成arm linux上的程序,go的库直接打包进去,go是编译型的语言,运行速度要比Python快的多。

出0入36汤圆

 楼主| 发表于 2022-2-16 13:27:27 | 显示全部楼层
vtte 发表于 2022-2-16 13:25
我一个golang的工程里,有几十上百个 if err != nil {。??
(引用自3楼)

错误处理,我还没咋搞,下午再倒腾以下看看,一遍看教程一遍搞。

出0入148汤圆

发表于 2022-2-16 14:13:30 | 显示全部楼层
网络或者多线程的编程 golang 还是挺有优势的,并且就打包成单个可执行文件,部署简单,挺适合用来做嵌入式linux开发

相对C而言有个缺点就是打包出来的执行文件太大,500KB起步

出100入312汤圆

发表于 2022-2-16 14:21:53 来自手机 | 显示全部楼层
电工新技能

出0入33汤圆

发表于 2022-2-16 14:37:24 | 显示全部楼层
yplin27 发表于 2022-2-16 14:13
网络或者多线程的编程 golang 还是挺有优势的,并且就打包成单个可执行文件,部署简单,挺适合用来做嵌入式 ...
(引用自6楼)

我怎么都2M多起步的? 随便用几个包就5、6M了。

出0入90汤圆

发表于 2022-2-16 15:48:41 | 显示全部楼层
以前没太了解过,没想到go还可以直接windows编译成arm啊,不需要虚拟机了,挺方便的。

出0入36汤圆

 楼主| 发表于 2022-2-16 16:09:40 | 显示全部楼层
yplin27 发表于 2022-2-16 14:13
网络或者多线程的编程 golang 还是挺有优势的,并且就打包成单个可执行文件,部署简单,挺适合用来做嵌入式 ...
(引用自6楼)

带来好多库,打包出来的就大。

其实都上Linux了系统,不差那一点存储空间。

出0入36汤圆

 楼主| 发表于 2022-2-16 16:11:22 | 显示全部楼层
vtte 发表于 2022-2-16 14:37
我怎么都2M多起步的? 随便用几个包就5、6M了。
(引用自8楼)

我这个程序打包以后1.68MB。

出0入148汤圆

发表于 2022-2-16 16:13:53 | 显示全部楼层
vtte 发表于 2022-2-16 14:37
我怎么都2M多起步的? 随便用几个包就5、6M了。
(引用自8楼)

编译加 -ldflags="-s -w",然后用 upx 压缩

出0入148汤圆

发表于 2022-2-16 16:22:46 | 显示全部楼层
redworlf007 发表于 2022-2-16 16:09
带来好多库,打包出来的就大。

其实都上Linux了系统,不差那一点存储空间。 ...
(引用自10楼)

就一个helloworld,估计是运行时占的空间,感觉是官方把golang定位为服务端使用,编译速度更重要

很多物联网网关可能也就几十MB Flash空间,这点存储还是需要考虑的

出0入36汤圆

 楼主| 发表于 2022-2-16 17:32:24 | 显示全部楼层
yplin27 发表于 2022-2-16 16:22
就一个helloworld,估计是运行时占的空间,感觉是官方把golang定位为服务端使用,编译速度更重要

很多物 ...
(引用自13楼)

我在MT7628的openwrt路由器上跑了个tcp server,编译完5.7M

出0入36汤圆

 楼主| 发表于 2022-2-16 17:35:56 | 显示全部楼层
yplin27 发表于 2022-2-16 16:13
编译加 -ldflags="-s -w",然后用 upx 压缩
(引用自12楼)

我最上面那个程序,编译好是1.68M。
加了-ldflags="-s -w" 这个编译后是1.18M。
小了一点点。

出0入228汤圆

发表于 2022-2-16 18:50:41 来自手机 | 显示全部楼层
用了golang就回不去了。

出0入71汤圆

发表于 2022-2-16 19:18:52 | 显示全部楼层
go语言怎么看着像pascal

出5入0汤圆

发表于 2022-2-17 09:34:51 | 显示全部楼层
刚好我也有块980的板子,楼主能否分享下怎么搭建工程

出0入36汤圆

 楼主| 发表于 2022-2-17 10:17:14 | 显示全部楼层
NM2012 发表于 2022-2-17 09:34
刚好我也有块980的板子,楼主能否分享下怎么搭建工程
(引用自18楼)


我上传了压缩包,你解压后,用vscode打卡那个文件夹,然后再vscode的下面的终端里面输入:GOOS=linux GOARCH=arm GOARM=5  go build -ldflags="-s -w"  main.go

就能编译从成980上跑的程序了,对了980的系统要做成依赖glibc的。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出5入0汤圆

发表于 2022-2-17 10:18:57 | 显示全部楼层
redworlf007 发表于 2022-2-17 10:17
我上传了压缩包,你解压后,用vscode打卡那个文件夹,然后再vscode的下面的终端里面输入:GOOS=linux GOA ...
(引用自19楼)

非常感谢,玩这个的资料很少啊。

出0入36汤圆

 楼主| 发表于 2022-2-17 10:31:04 | 显示全部楼层
NM2012 发表于 2022-2-17 10:18
非常感谢,玩这个的资料很少啊。
(引用自20楼)

只要会go语言就不需要啥资料了。

出5入0汤圆

发表于 2022-2-17 10:36:56 | 显示全部楼层
redworlf007 发表于 2022-2-17 10:17
我上传了压缩包,你解压后,用vscode打卡那个文件夹,然后再vscode的下面的终端里面输入:GOOS=linux GOA ...
(引用自19楼)

Desktop\gpio_test> GOOS=linux GOARCH=arm GOARM=5  go build -ldflags="-s -w"  main.go
GOOS=linux : 无法将“GOOS=linux”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再
试一次。
所在位置 行:1 字符: 1
+ GOOS=linux GOARCH=arm GOARM=5  go build -ldflags="-s -w"  main.go
+ ~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (GOOS=linux:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

是不是开发环境什么没有配置好?

出0入36汤圆

 楼主| 发表于 2022-2-17 10:53:10 | 显示全部楼层
NM2012 发表于 2022-2-17 10:36
Desktop\gpio_test> GOOS=linux GOARCH=arm GOARM=5  go build -ldflags="-s -w"  main.go
GOOS=linux :  ...
(引用自22楼)

你的终端那里应该能选git bash

出5入0汤圆

发表于 2022-2-17 12:59:13 | 显示全部楼层
redworlf007 发表于 2022-2-17 10:53
你的终端那里应该能选git bash
(引用自23楼)

把Git安装好就可以编译通过了。NUC980板子上是不是也要安装相应的库什么的?

出0入36汤圆

 楼主| 发表于 2022-2-17 13:10:46 | 显示全部楼层
NM2012 发表于 2022-2-17 12:59
把Git安装好就可以编译通过了。NUC980板子上是不是也要安装相应的库什么的?
...
(引用自24楼)

你直接放到板子上看能不能跑,记得在开发板上修改下你放进去的程序的权限777.
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 22:05

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表