go开发上位机--OTA上篇/文件操作

C:\Program Files\JetBrains\GoLand 2020.3.1\bin  

goland64.exe 

只能使用30天 !

package main
func main() {
	println("hello koson")
}

开发环境OK

准备编码

1--文件操作

【补充

整理一下GW我全新设计:
情景写文件:XXXX

情景快速获得文件长度:
https://www.flysnow.org/2020/07/25/golang-file-size.html

hex上报是
触发上报+强制上报 Wsm.Chan_reportHexData 键盘4

func main() {
	fi,err:=os.Stat("water")
	if err ==nil {
		fmt.Println("file size is ",fi.Size(),err)
	}
}

也只需要三行代码即可实现,这里使用的是os.Stat,通过他可以获得文件的元数据信息,现在我们看看它能获取到哪些信息。

获取文件信息

通过os.Stat方法,我们可以获取文件的信息,比如文件大小、名字等。

os.Stat函数,它可以在不打开文件的情况下,高效获取文件信息。

2--JS操作 

3--串口操作

1---golang 读取文件的四种方式 - 简书  使用方法2

读bin文件 每次读出来4K  不要一下子全部读出 那样太简单

GOROOT=C:\Go #gosetup
GOPATH=C:\Users\Koson.Gong\go #gosetup
C:\Go\bin\go.exe build -o C:\Users\Koson.Gong\AppData\Local\Temp\___go_build_HELLO_go.exe C:\Users\Koson.Gong\Documents\GO_OTA\HELLO.go #gosetup
C:\Users\Koson.Gong\AppData\Local\Temp\___go_build_HELLO_go.exe #gosetup
【10】[248 89 0 16 21 226 2 8 37 226]
Process finished with exit code 0 

代码

package main

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

func main() {
	f, err := os.Open("application.bin")

	defer f.Close()

	buf := make([]byte, 10)

	n, err := f.Read(buf)
	if err != nil && err != io.EOF{
	fmt.Printf("read buf fail", err)
	return
	}
	fmt.Printf("【%d】%+v", n,buf)
	return
}

2---比较鸡肋 JS操作用到file的读写 Golang: 解析JSON数据之三 - liuhe688 - 博客园

package main

import (
	"encoding/json"
	"fmt"
	"os"
)

type Person struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
	// 如果Child字段为nil 编码JSON时可忽略
	Child *Person `json:"child,omitempty"`
}
func set_js(){
	person := Person{
		Name: "John",
		Age: 40,
		Child: &Person{
			Name: "Jack",
			Age: 20,
		},
	}

	// File类型实现了io.Writer接口
	file, _ := os.Create("person.json")

	// 根据io.Writer创建Encoder 然后调用Encode()方法将对象编码成JSON
	json.NewEncoder(file).Encode(&person)
}

func get_js(){
	var person Person

	// File类型也实现了io.Reader接口
	file, _ := os.Open("person.json")

	// 根据io.Reader创建Decoder 然后调用Decode()方法将JSON解析成对象
	json.NewDecoder(file).Decode(&person)

	fmt.Println(person)
	fmt.Println(*person.Child)
}
func main() {
	set_js()
	get_js()
}

3---【GO】串口简单通讯_吴秀华Cherry的有趣博客-CSDN博客_go 操作串口

WIN10怎么跑起来?

package main

import (
	"fmt"
	"log"
	"time"
	"github.com/tarm/goserial"
)

func main() {

	//设置串口编号
	c := &serial.Config{Name: "COM5", Baud: 115200}

	//打开串口
	s, err := serial.OpenPort(c)
	if err != nil {
		log.Fatal(err)
	}

	// 写入字符串“012345”
	n, err := s.Write([]byte("012345"))
	if err != nil {
		log.Fatal(err)
	}

	//延时100
	time.Sleep(100)

	buf := make([]byte, 128)
	n, err = s.Read(buf)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Read %d Bytes\r\n", n)
	for i := 0; i < n; i++ {
		fmt.Printf("buf[%d]=%c\r\n", i, buf[i])
	}
}

//开机 发消息 随后等到收到A就发送A

变成GO环境的问题

用PI验证

下载代码---放在PI的桌面--增加一个main.go 内容就是上面的代码

  511  cd goserial/
  512  go build serial.go 

显示失败

执行mod  利用go mod tidy把代码down下来

  516  go mod init test
  517  go mod tidy
  518  go env -w GO111MODULE=on
  519  go env -w GOPROXY=https://goproxy.cn,direct
  520  go mod tidy
  521  go build main.go

 编译通过 出来main

在WIN10也是一样  不需要去自己git拉代码的

准备一个串口测试吧

 WIN10虚拟的

这个软件这么使用的?

下面测试一个简单Tx

package main

import (
	"fmt"
	"github.com/tarm/goserial"
	"log"
	"time"
)

func main() {
	c := &serial.Config{Name: "COM5", Baud: 115200}
	s, err := serial.OpenPort(c)
	if err != nil {
		log.Fatal(err)
	}
	for {
		n, err := s.Write([]byte(string("HEELO\r\n")))
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("Write %d Bytes\r\n", n)
		time.Sleep(1000)
	}

}

继续测试收发

package main

import (
	"fmt"
	"log"
	"time"
	"github.com/tarm/goserial"
)

func main() {


	c := &serial.Config{Name: "COM5", Baud: 115200}


	s, err := serial.OpenPort(c)
	if err != nil {
		log.Fatal(err)
	}
	n, err := s.Write([]byte(string("hello\r\n")))
	if err != nil {
		log.Fatal(err)
	}

	time.Sleep(100)

	buf := make([]byte, 128)
	for {
		n, err = s.Read(buf)
		if err != nil {
			log.Fatal(err)
		}

		fmt.Printf("Read %d Bytes\r\n", n)
		for i := 0; i < n; i++ {
			fmt.Printf("buf[%d]=%c\r\n", i, buf[i])
		}
	}
}

注意一个情况 go的这个代码 read好像有问题 你发送123 它收到1 后面再收到23

那就是bug啊 第一个需要人工del吗

不准备去解决这个bug

准备简单点 发数据的时候故意让第一个是没有意义的随机数 

准备技能 没有memcpy有高级的go 结构体转化为string_Go 结构体、数组、字典和 json 字符串的相互转换方法_weixin_39866774的博客-CSDN博客

s := `{"addr":134217758,"len":1034}`
json.Unmarshal([]byte(s), &info)
fmt.Println(info)

//{134217758 1034}

if(n>1) {
	fmt.Printf("Read %d Bytes  ", n)

	fmt.Printf("%s", buf)
	json.Unmarshal(buf, &info)
	fmt.Println(info)
}

最后代码 代码逻辑是:等待UART发消息过来 UART是来索要文件的 我就这个程序模拟HTTP服务器 给出去对应的文件 需要文件的起始地址和文件长度 就是函数读的参数啦!

package main

import (
	"encoding/json"
	"fmt"
	"github.com/tarm/goserial"
	"io"
	"log"
	"os"
	"time"
)

type Start struct {
	Filesize int     `json:"filesize"`
	Md5  string      `json:"md5"`
	Ver  int         `json:"ver"`
}

type Info struct {
	Addr int64    `json:"addr"`
	Len  int      `json:"len"`
}

type Ack struct {
	Duty     int      `json:"duty"`
	Errflag  int      `json:"errflag"`
}

func start_js(){
	start := Start{
		Filesize: 100,
		Md5: "1234",
		Ver:666,
	}
	file, _ := os.Create("start.json")
	json.NewEncoder(file).Encode(&start)
}

func set_js(){
	info := Info{
		Addr: 0x08000000,
		Len: 1024,
	}
	file, _ := os.Create("info.json")
	json.NewEncoder(file).Encode(&info)
}

func get_js(){
	var info Info
	file, _ := os.Open("info.json")
	json.NewDecoder(file).Decode(&info)
	//fmt.Println(info)
}

func getbinfile(info Info)(bin []byte,num int){
	f, err := os.Open("application.bin")
	defer f.Close()
	buf := make([]byte, info.Len)
	n, err := f.ReadAt(buf,info.Addr)//两个参数 约定了从文件的哪个地方读多少hex出来
	if err != nil && err != io.EOF{
		fmt.Printf("read buf fail", err)
		return
	}
	//fmt.Printf("【%d】%+v", n,buf)
	return buf,n
}

func main() {
	//初始化
	c := &serial.Config{Name: "COM1", Baud: 115200}
	s, err := serial.OpenPort(c)
	if err != nil {
		log.Fatal(err)
	}

	//主动发消息
	//start_js()
	var start Start
	file, _ := os.Open("start.json")
	json.NewDecoder(file).Decode(&start)
	fmt.Println(start)

	a,_:= json.Marshal(start)//https://blog.csdn.net/weixin_39866774/article/details/111847526
	_, err = s.Write([]byte(string(a)))

	if err != nil {
		log.Fatal(err)
	}
	time.Sleep(100)

	//被动收消息
	var n int
	buf := make([]byte, 128)

	set_js();
	get_js();
	var info Info
	var ack Ack

	for {

		n, err = s.Read(buf)
		if err != nil {
			log.Fatal(err)
		}
		if(n>1) {
			fmt.Printf("Read %d Bytes  ", n)
			fmt.Printf("%d  ", buf[0])
			head := buf[0]
			fmt.Printf("head【%c】\r\n",head)
			fmt.Printf("【%s】\r\n ", buf)
			switch head {
			case '1':
				json.Unmarshal(buf[1:n], &info)
				fmt.Println(info)

				buf,_ = getbinfile(info)
				fmt.Println(buf)

				s.Write(buf)
			case '2':
				json.Unmarshal(buf[1:n], &ack)
				fmt.Println(ack)
			}
		}
	}
}

//#1{"addr":134217728,"len":1024}
//#2{"duty":23,"errflag":0}

现象是从串口输入6{"addr":134217728,"len":1984} 总是无法获得串口的解析

因为解包JS需要下图

错误笔记:

The system cannot find the file specified

这是因为main里面操作串口 我没有

需要启动虚拟串口软件再做!!!

串口过来的数据JS解析失败 因为JS的接口比较傻 需要限制数目

package main

import (
	"encoding/json"
	"fmt"
	"github.com/tarm/goserial"
	"log"
)

type Info struct {
	Addr int    `json:"addr"`
	Len  int    `json:"len"`
}

func main() {
	//初始化
	c := &serial.Config{Name: "COM1", Baud: 115200}
	s, err := serial.OpenPort(c)
	if err != nil {
		log.Fatal(err)
	}

	//被动收消息
	var n int
	buf := make([]byte, 128)
	var info Info
	for {
		n, err = s.Read(buf)
		if err != nil {
			log.Fatal(err)
		}
		if(n>1) {
			fmt.Printf("Read %d Bytes \r\n ", n)
			fmt.Printf("%s\r\n ", buf)

			//json.Unmarshal(buf, &info)
			err2 :=json.Unmarshal(buf[:n], &info)
			fmt.Println(info)
			fmt.Println(err2)


/*为什么下面的可以上面的不可以 手段是看json.Unmarshal的返回值 打印 看到invalid character '\x00' after top-level value
一百度就知道了 需要限制一下buf的结束 因为string它/0结束了 而这个函数Unmarshal比较傻 需要告诉它到哪里结束*/
			s := `{"addr":134217758,"len":1034}`
			fmt.Printf("%s\r\n ", s)
			json.Unmarshal([]byte(s), &info)
			fmt.Println(info)
		}
	}
}

//01{"addr":134217728,"len":1024}
//02{"duty":23,"errflag":0}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值