rts-sim-testing-service/third_party/message/can_net.go
2024-04-18 11:14:05 +08:00

133 lines
3.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package message
import (
"fmt"
"log/slog"
"strings"
)
// CanetFrame USR-CANET200_V1.0.7 设备 以太网-CAN 透传协议帧(13字节)
type CanetFrame struct {
FF bool //true-1扩展帧
RTR bool //true-1远程帧
CanLen byte //CAN帧数据长度[0,8]CanData中有效数据字节数
CanId CanFrameId //CAN帧ID
CanData []byte //CAN帧数据8字节
IsTrainPcSim bool //是否列车pc仿真
}
func NewCanetFrame(buf []byte, isTrainPcSim bool) *CanetFrame {
cf := &CanetFrame{IsTrainPcSim: isTrainPcSim}
cf.Decode(buf)
return cf
}
func (p *CanetFrame) Encode() []byte {
buf := make([]byte, 0)
if !p.IsTrainPcSim {
//canet200帧信息
b1 := byte(0x00)
if p.FF {
b1 |= 0x80 //bit7
}
if p.RTR {
b1 |= 0x40 //bit6
}
b1 |= p.CanLen & 0x0f
buf = append(buf, b1)
}
//CAN 帧ID
buf = append(buf, p.CanId.ID1)
buf = append(buf, p.CanId.ID2)
buf = append(buf, p.CanId.ID3)
buf = append(buf, p.CanId.ID4<<3)
//CAN 帧数据
if len(p.CanData) != 8 {
panic("len(p.CanData)!=8")
}
buf = append(buf, p.CanData...)
return buf
}
func (p *CanetFrame) Decode(buf []byte) {
//
if !p.IsTrainPcSim {
if len(buf) != 13 {
panic("len(buf)!=13")
}
p.FF = buf[0]&0x80 == 0x80
p.RTR = buf[0]&0x40 == 0x40
p.CanLen = buf[0] & 0x0f
}
//1 2 3 4
p.CanId.ID1 = buf[1]
p.CanId.ID2 = buf[2]
p.CanId.ID3 = buf[3]
p.CanId.ID4 = buf[4] >> 3
//
p.CanData = buf[5:]
}
func (p *CanetFrame) String() string {
sb := strings.Builder{}
sb.WriteString(fmt.Sprintf("CanetFrame FF = %t, RTR = %t, CanLen = %d, ID1 = 0x%0x, ID2 = 0x%0x, ID3 = 0x%0x, ID4 = 0x%0x, isTrainPcSim=%v", p.FF, p.RTR, p.CanLen,
p.CanId.ID1, p.CanId.ID2, p.CanId.ID3, p.CanId.ID4, p.IsTrainPcSim))
sb.WriteString("CanData = ")
for _, d := range p.CanData {
sb.WriteString(fmt.Sprintf(" 0x%0x ", d))
}
return sb.String()
}
// CanFrameType 获取canet帧类型
func (p *CanetFrame) CanFrameType() CanFrameType {
switch p.CanId.ID3 {
case 0x01:
{ //状态应答帧0x01
return CfStatusRsp
}
case 0x8d:
{ //msgTimeA数据帧0x80+0x0d
return CfMsgTimeA
}
case 0x8e:
{ //msgTimeB数据帧0x80+0x0e
return CfMsgTimeB
}
case 0xff:
{ //msgEnd数据帧0x80+0x7f
return CfMsgEnd
}
case 0x02:
{
if p.CanId.ID1 == 0x62 && p.CanId.ID2 == 0x81 {
return CfReq
} else {
return CfTimeSync
}
}
default:
if p.CanId.ID3 >= 0x80 && p.CanId.ID3 <= 0x8c { //数据帧0x80+(0x00-0x0c)
return CfMsg
} else {
slog.Warn(fmt.Sprintf("无法识别的Canet帧[%s]", p.String()))
return CfNon
}
}
}
// CanFrameType 帧类型定义
type CanFrameType = byte
// Can帧类型枚举
const (
CfNon = CanFrameType(0)
CfReq = CanFrameType(1) //查询帧0x02
CfStatusRsp = CanFrameType(2) //状态应答帧0x01
CfTimeSync = CanFrameType(3) //时间同步校验帧0x02
CfMsg = CanFrameType(4) //数据帧0x80+(0x00-0x0c)
CfMsgTimeA = CanFrameType(5) //msgTimeA数据帧0x80+0x0d
CfMsgTimeB = CanFrameType(6) //msgTimeB数据帧0x80+0x0e
CfMsgEnd = CanFrameType(7) //msgEnd数据帧0x80+0x7f
)