1、手上的这个hilink的mt7628开发板的系统里面用reg的软件包来控制io口的。
2、用golang操作reg命令不方便。
3、所以用mmap来操作io口。

直接干代码
①、以下是mmap.go
package mmap

import (
        "fmt"
        "os"
        "syscall"
        "unsafe"
        // "github.com/edsrzf/mmap-go"
)

func check(e error) {
        if e != nil {
                fmt.Println(e)
        }
}

const (
        gpioBase          = 0x00000000 + 0x10000000 // MT6826寄存器基地址
        gpioRegs          = 426                     // number of GPIO registers
        gpioRegBufferSize = gpioRegs * 4            // 32 bits hardcoded here

        RALINK_GPIO_DIR_IN  = 0
        RALINK_GPIO_DIR_OUT = 1

        RALINK_REG_PIOINT   = 0x690
        RALINK_REG_PIOEDGE  = 0x6A0
        RALINK_REG_PIORENA  = 0x650
        RALINK_REG_PIOFENA  = 0x660
        RALINK_REG_PIODATA  = 0x620
        RALINK_REG_PIODIR   = 0x600
        RALINK_REG_PIOSET   = 0x630
        RALINK_REG_PIORESET = 0x640

        RALINK_REG_PIO6332INT   = 0x694
        RALINK_REG_PIO6332EDGE  = 0x6A4
        RALINK_REG_PIO6332RENA  = 0x654
        RALINK_REG_PIO6332FENA  = 0x664
        RALINK_REG_PIO6332DATA  = 0x624
        RALINK_REG_PIO6332DIR   = 0x604
        RALINK_REG_PIO6332SET   = 0x634
        RALINK_REG_PIO6332RESET = 0x644

        RALINK_REG_PIO9564INT   = 0x698
        RALINK_REG_PIO9564EDGE  = 0x6A8
        RALINK_REG_PIO9564RENA  = 0x658
        RALINK_REG_PIO9564FENA  = 0x668
        RALINK_REG_PIO9564DATA  = 0x628
        RALINK_REG_PIO9564DIR   = 0x608
        RALINK_REG_PIO9564SET   = 0x638
        RALINK_REG_PIO9564RESET = 0x648
)

var Gpio_mmap_reg *[gpioRegs]uint32

func Gpio_mmap() int {
        f, err := os.OpenFile("/dev/mem", os.O_RDWR|os.O_SYNC, 0644)
        check(err)
        defer f.Close()

        /*第一种方式使用mmap-go库 ("github.com/edsrzf/mmap-go")*/
        // mapped, err := mmap.MapRegion(f, gpioRegBufferSize, mmap.RDWR, 0, gpioBase)
        // check(err)

        /*第一种方式使用syscall库 ("syscall")*/
        mapped, err := syscall.Mmap(int(f.Fd()), gpioBase, gpioRegBufferSize, syscall.PROT_WRITE, syscall.MAP_SHARED)

        if nil != err {

                fmt.Println(err)
                return -1

        }
        Gpio_mmap_reg = (*[gpioRegs]uint32)(unsafe.Pointer(&mapped[0]))

        //fmt.Printf("regs1=0x%2x\r\n", &Gpio_mmap_reg[0])
        //fmt.Println(reflect.TypeOf(Gpio_mmap_reg))
        return 0
}

func mt76x8_gpio_reg_choose(reg *[gpioRegs]uint32, reg_addr uint32) (reg_mmap_addr *uint32) {
        var p0 *uint32 = &reg[0]

        var p1 unsafe.Pointer = unsafe.Pointer(p0)

        //fmt.Printf("*p1=0x%2x\r\n", p1)

        var p2 uintptr = uintptr(p1)

        p2 += uintptr(reg_addr)

        // fmt.Println(reflect.TypeOf(p2))

        var p3 = unsafe.Pointer(p2)

        var p4 *uint32 = (*uint32)(p3)
        // fmt.Printf("*p4=0x%2x\r\n", *p4)
        return p4
}

func Mt76x8_gpio_get_pin(pin int) int {
        var tmp uint32 = 0
        /* MT7621, MT7628 */
        if pin <= 31 {
                // tmp = *mt76x8_gpio_reg_choose(Gpio_mmap_reg, RALINK_REG_PIODIR)
                tmp = (tmp >> pin) & uint32(1)
        } else if pin <= 63 {
                tmp = *mt76x8_gpio_reg_choose(Gpio_mmap_reg, RALINK_REG_PIO6332DATA)
                tmp = (tmp >> (pin - 32)) & uint32(1)
                //fmt.Printf("tmp=0x%2x\r\n", tmp)
        } else if pin <= 95 {
                // tmp = *mt76x8_gpio_reg_choose(Gpio_mmap_reg, RALINK_REG_PIO9564DATA)
                tmp = (tmp >> (pin - 64)) & uint32(1)
                tmp = (tmp >> (pin - 24)) & uint32(1)
        }
        return int(tmp)
}

func Mt76x8_gpio_set_pin_direction(pin int, is_output int) {
        var tmp uint32 = 0

        /* MT7621, MT7628 */
        if pin <= 31 {
                tmp = *mt76x8_gpio_reg_choose(Gpio_mmap_reg, RALINK_REG_PIODIR)
                if is_output == 1 {
                        tmp |= (uint32(1) << pin)
                } else {
                        tmp &= ^(uint32(1) << pin)
                }
                *mt76x8_gpio_reg_choose(Gpio_mmap_reg, RALINK_REG_PIODIR) = tmp
        } else if pin <= 63 {
                tmp = *mt76x8_gpio_reg_choose(Gpio_mmap_reg, RALINK_REG_PIO6332DIR)
                if is_output == 1 {
                        tmp |= (uint32(1) << (pin - 32))
                } else {
                        tmp &= ^(uint32(1) << (pin - 32))
                }
                *mt76x8_gpio_reg_choose(Gpio_mmap_reg, RALINK_REG_PIO6332DIR) = tmp
        } else if pin <= 95 {
                tmp = *mt76x8_gpio_reg_choose(Gpio_mmap_reg, RALINK_REG_PIO9564DIR)
                if is_output == 1 {
                        tmp |= (uint32(1) << (pin - 64))
                } else {
                        tmp &= ^(uint32(1) << (pin - 64))
                }
                *mt76x8_gpio_reg_choose(Gpio_mmap_reg, RALINK_REG_PIO9564DIR) = tmp
        }
}

func Mt76x8_gpio_set_pin_value(pin int, value int) {
        var tmp uint32 = 0

        /* MT7621, MT7628 */
        if pin <= 31 {
                tmp = (uint32(1) << pin)
                if value == 1 {
                        *mt76x8_gpio_reg_choose(Gpio_mmap_reg, RALINK_REG_PIOSET) = tmp
                } else {
                        *mt76x8_gpio_reg_choose(Gpio_mmap_reg, RALINK_REG_PIORESET) = tmp

                }
        } else if pin <= 63 {
                tmp = (uint32(1) << (pin - 32))
                if value == 1 {
                        *mt76x8_gpio_reg_choose(Gpio_mmap_reg, RALINK_REG_PIO6332SET) = tmp
                } else {
                        *mt76x8_gpio_reg_choose(Gpio_mmap_reg, RALINK_REG_PIO6332RESET) = tmp
                }
        } else if pin <= 95 {
                tmp = (uint32(1) << (pin - 64))
                if value == 1 {
                        *mt76x8_gpio_reg_choose(Gpio_mmap_reg, RALINK_REG_PIO9564SET) = tmp
                } else {
                        *mt76x8_gpio_reg_choose(Gpio_mmap_reg, RALINK_REG_PIO9564RESET) = tmp
                }
        }
}

②、以下是copy.go
package copy

import (
        "fmt"
        "io"
        "os"
)

//自己编写一个函数,接收两个文件路径 srcFileName dstFileName
func CopyFile(srcFileName string, dstFileName string) (err error) {
        sFile, err1 := os.Open(srcFileName)
        defer sFile.Close() //必须关闭
        dFile, err2 := os.OpenFile(dstFileName, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
        defer dFile.Close() //必须关闭
        if err1 != nil {
                return err1
        }
        if err2 != nil {
                return err2
        }
        var tempSlice = make([]byte, 1280)
        for {
                //读取数据
                n1, err := sFile.Read(tempSlice)
                if err == io.EOF {
                        break
                }
                if err != nil {
                        return err
                }
                // 写入数据
                if _, err := dFile.Write(tempSlice[:n1]); err != nil {
                        return err
                }
        }
        return nil
}

func Recover() {

        //调用CopyFile 完成文件拷贝
        srcFile := "/data/root/NUC980_Sleep/go/NUC980/gpio_test/1.txt"
        dstFile := "/data/root/NUC980_Sleep/go/NUC980/gpio_test/2.txt"
        err := CopyFile(srcFile, dstFile)
        if err == nil {
                fmt.Printf("拷贝完成\n")
        } else {
                fmt.Printf("拷贝错误 err=%v\n", err)
        }

}

③、以下是main.go
/*
Playing around with Go on the Raspberry Pi, doing some trivial GPIO stuff
using the unsafe/dangerous/ugly but fast mmap approach.
*/
package main

import (
        "fmt"
        "io/ioutil"
        "mmap/copy"
        "mmap/mmap"
        "os"
        "os/exec"
        "sync"
        "time"
        // "github.com/edsrzf/mmap-go"
)

var wg sync.WaitGroup
var KeyPressNo int = 0

//LED_PC13 绿色指示灯
func LED_GPIO_44() {

        mmap.Mt76x8_gpio_set_pin_direction(44, 1)
        for {
                mmap.Mt76x8_gpio_set_pin_value(44, 1)
                time.Sleep(100 * time.Millisecond)
                mmap.Mt76x8_gpio_set_pin_value(44, 0)
                time.Sleep(100 * time.Millisecond)
        }
        //wg.Done()
}
func Watchdog() {
        file, err := os.OpenFile("/dev/watchdog", os.O_WRONLY, 0666)
        if err != nil {
                fmt.Println("open file failed, err:", err)
                return
        }
        defer file.Close()

        for {
                file.WriteString("1")
                time.Sleep(500 * time.Millisecond)
        }
        //wg.Done()
}

func KeyScan() {

        for {
                KeyValue := mmap.Mt76x8_gpio_get_pin(38)
                if KeyValue == 1 {
                        KeyPressNo = 0
                } else if KeyValue == 0 {
                        KeyPressNo++
                        if KeyPressNo > 12 {
                                fmt.Println("Recover system")
                                copy.Recover()
                                time.Sleep(2000 * time.Millisecond)
                                ExecCommand("reboot -f")

                        }
                }
                time.Sleep(1000 * time.Millisecond)
        }
        //wg.Done()
}

func ExecCommand(strCommand string) string {
        cmd := exec.Command("sh", "-c", strCommand)

        stdout, _ := cmd.StdoutPipe()
        if err := cmd.Start(); err != nil {
                fmt.Println("Execute failed when Start:" + err.Error())
                return ""
        }

        out_bytes, _ := ioutil.ReadAll(stdout)
        stdout.Close()

        if err := cmd.Wait(); err != nil {
                fmt.Println("Execute failed when Wait:" + err.Error())
                return ""
        }
        return string(out_bytes)
}

func main() {
        mmap.Gpio_mmap()

        wg.Add(1)
        go LED_GPIO_44()

        wg.Add(1)
        go Watchdog()

        wg.Add(1)
        go KeyScan()

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

④、vscode上编译为mips架构上的指令:
GOOS=linux GOARCH=mipsle go build -ldflags="-s -w"  main.go