From 2be3990983b258cf638ae4817c29c3c14e8c8782 Mon Sep 17 00:00:00 2001 From: xzb <223@qq.com> Date: Tue, 21 Nov 2023 17:20:03 +0800 Subject: [PATCH] =?UTF-8?q?btm=20=20can-net=20=E9=80=8F=E4=BC=A0=E5=8D=8F?= =?UTF-8?q?=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- third_party/message/can_atp_req.go | 53 ++++-------- third_party/message/can_btm_data.go | 88 +++++++++++++------- third_party/message/can_btm_rsp.go | 82 +++++++----------- third_party/message/can_btm_status_rsp.go | 21 +++-- third_party/message/can_btm_time_sync_rsp.go | 21 +++-- third_party/message/can_bus.go | 4 +- third_party/message/can_net.go | 71 ++++++++++++++++ 7 files changed, 199 insertions(+), 141 deletions(-) create mode 100644 third_party/message/can_net.go diff --git a/third_party/message/can_atp_req.go b/third_party/message/can_atp_req.go index a46c4df..ce3c217 100644 --- a/third_party/message/can_atp_req.go +++ b/third_party/message/can_atp_req.go @@ -30,36 +30,6 @@ type CanFrameId struct { ID4 byte } -func (f *CanFrameId) Encode(bits CanBitsWriter) { - bits.AddByte(f.ID1) - bits.AddByte(f.ID2) - bits.AddByte(f.ID3) - bits.AddBits(f.ID4, 5) -} -func (f *CanFrameId) Decode(bits CanBitsReader) bool { - if id, ok := bits.ReadByte(); ok { - f.ID1 = id - } else { - return false - } - if id, ok := bits.ReadByte(); ok { - f.ID2 = id - } else { - return false - } - if id, ok := bits.ReadByte(); ok { - f.ID3 = id - } else { - return false - } - if id, ok := bits.ReadBits(5); ok { - f.ID4 = id - } else { - return false - } - return true -} - // NewCanFrameId 创建CAN串行总线帧ID // dstAddr 目的设备地址 // srcAddr 源设备地址 @@ -102,10 +72,11 @@ func NewAtpRequestFrame(sn byte) *AtpRequestFrame { FId: *NewCanFrameId(CAN_ADDR_REQ_BTM, CAN_ADDR_REQ_ATP, CAN_FRAME_ATP_REQ, sn), } } -func (f *AtpRequestFrame) Decode(bits CanBitsReader) bool { - if !f.FId.Decode(bits) { - return false - } +func (f *AtpRequestFrame) Decode(cf *CanetFrame) bool { + f.FId = cf.CanId + // + bits := NewCanBitsReader(cf.CanData, 8) + // if d, ok := bits.ReadBits(1); ok { f.PowerAmplifierTurnOn = d == 1 } else { @@ -188,10 +159,14 @@ func (f *AtpRequestFrame) Decode(bits CanBitsReader) bool { // return true } -func (f *AtpRequestFrame) Encode() CanBusData { - bits := NewCanBitsWriter(12) +func (f *AtpRequestFrame) Encode() *CanetFrame { + cf := &CanetFrame{} + cf.CanId = f.FId + cf.CanLen = 8 + cf.FF = true + cf.RTR = false // - f.FId.Encode(bits) + bits := NewCanBitsWriter(8) // if f.PowerAmplifierTurnOn { bits.AddBits(1, 1) @@ -223,5 +198,7 @@ func (f *AtpRequestFrame) Encode() CanBusData { bits.AddByte(byte(crc16 >> 8)) bits.AddByte(byte(crc16)) // - return bits.(CanBusData) + cf.CanData = bits.(CanBusData).GetData() + // + return cf } diff --git a/third_party/message/can_btm_data.go b/third_party/message/can_btm_data.go index 5718566..f9dcd85 100644 --- a/third_party/message/can_btm_data.go +++ b/third_party/message/can_btm_data.go @@ -16,20 +16,26 @@ func NewBtmDataMessageFrame(sn byte, offset byte) *BtmDataMessageFrame { FId: *NewCanFrameId(CAN_ADDR_RSP_ATP, CAN_ADDR_RSP_BTM, 0x80+offset, sn), } } -func (f *BtmDataMessageFrame) Encode() CanBusData { - writer := NewCanBitsWriter(12) +func (f *BtmDataMessageFrame) Encode() *CanetFrame { + cf := &CanetFrame{} + cf.CanId = f.FId + cf.CanLen = 8 + cf.FF = true + cf.RTR = false // - f.FId.Encode(writer) + writer := NewCanBitsWriter(8) // for _, data := range f.Message { writer.AddByte(data) } - return writer.(CanBusData) + cf.CanData = writer.(CanBusData).GetData() + // + return cf } -func (f *BtmDataMessageFrame) Decode(reader CanBitsReader) bool { - if !f.FId.Decode(reader) { - return false - } +func (f *BtmDataMessageFrame) Decode(cf *CanetFrame) bool { + f.FId = cf.CanId + // + reader := NewCanBitsReader(cf.CanData, 8) // f.Message = make([]byte, 0, 8) for c := 0; c < 8; c++ { @@ -61,10 +67,14 @@ func NewBtmDataMessageTimeAFrame(sn byte) *BtmDataMessageTimeAFrame { FId: *NewCanFrameId(CAN_ADDR_RSP_ATP, CAN_ADDR_RSP_BTM, 0x80+0x0d, sn), } } -func (f *BtmDataMessageTimeAFrame) Encode() CanBusData { - writer := NewCanBitsWriter(12) +func (f *BtmDataMessageTimeAFrame) Encode() *CanetFrame { + cf := &CanetFrame{} + cf.CanId = f.FId + cf.CanLen = 8 + cf.FF = true + cf.RTR = false // - f.FId.Encode(writer) + writer := NewCanBitsWriter(8) // byteMsk := uint32(0x00_00_00_ff) // @@ -78,13 +88,15 @@ func (f *BtmDataMessageTimeAFrame) Encode() CanBusData { writer.AddByte(byte((f.Crc32A >> 8) & byteMsk)) writer.AddByte(byte(f.Crc32A & byteMsk)) // - return writer.(CanBusData) + cf.CanData = writer.(CanBusData).GetData() + // + return cf } -func (f *BtmDataMessageTimeAFrame) Decode(reader CanBitsReader) bool { - if !f.FId.Decode(reader) { - return false - } +func (f *BtmDataMessageTimeAFrame) Decode(cf *CanetFrame) bool { + f.FId = cf.CanId + // + reader := NewCanBitsReader(cf.CanData, 8) // f.TimeA = 0 a1, a1Ok := reader.ReadByte() @@ -157,10 +169,14 @@ func NewBtmDataMessageTimeBFrame(sn byte) *BtmDataMessageTimeBFrame { FId: *NewCanFrameId(CAN_ADDR_RSP_ATP, CAN_ADDR_RSP_BTM, 0x80+0x0e, sn), } } -func (f *BtmDataMessageTimeBFrame) Encode() CanBusData { - writer := NewCanBitsWriter(12) +func (f *BtmDataMessageTimeBFrame) Encode() *CanetFrame { + cf := &CanetFrame{} + cf.CanId = f.FId + cf.CanLen = 8 + cf.FF = true + cf.RTR = false // - f.FId.Encode(writer) + writer := NewCanBitsWriter(8) // byteMsk := uint32(0x00_00_00_ff) // @@ -174,12 +190,14 @@ func (f *BtmDataMessageTimeBFrame) Encode() CanBusData { writer.AddByte(byte((f.Crc32B >> 8) & byteMsk)) writer.AddByte(byte(f.Crc32B & byteMsk)) // - return writer.(CanBusData) + cf.CanData = writer.(CanBusData).GetData() + // + return cf } -func (f *BtmDataMessageTimeBFrame) Decode(reader CanBitsReader) bool { - if !f.FId.Decode(reader) { - return false - } +func (f *BtmDataMessageTimeBFrame) Decode(cf *CanetFrame) bool { + f.FId = cf.CanId + // + reader := NewCanBitsReader(cf.CanData, 8) // f.TimeB = 0 a1, a1Ok := reader.ReadByte() @@ -253,10 +271,14 @@ func NewBtmDataMessageEndFrame(sn byte) *BtmDataMessageEndFrame { FId: *NewCanFrameId(CAN_ADDR_RSP_ATP, CAN_ADDR_RSP_BTM, 0x80+0x7f, sn), } } -func (f *BtmDataMessageEndFrame) Encode() CanBusData { - writer := NewCanBitsWriter(12) +func (f *BtmDataMessageEndFrame) Encode() *CanetFrame { + cf := &CanetFrame{} + cf.CanId = f.FId + cf.CanLen = 8 + cf.FF = true + cf.RTR = false // - f.FId.Encode(writer) + writer := NewCanBitsWriter(8) // byteMsk := uint32(0x00_00_00_ff) // @@ -270,12 +292,14 @@ func (f *BtmDataMessageEndFrame) Encode() CanBusData { writer.AddByte(byte((f.Crc32C >> 8) & byteMsk)) writer.AddByte(byte(f.Crc32C & byteMsk)) // - return writer.(CanBusData) + cf.CanData = writer.(CanBusData).GetData() + // + return cf } -func (f *BtmDataMessageEndFrame) Decode(reader CanBitsReader) bool { - if !f.FId.Decode(reader) { - return false - } +func (f *BtmDataMessageEndFrame) Decode(cf *CanetFrame) bool { + f.FId = cf.CanId + // + reader := NewCanBitsReader(cf.CanData, 8) // f.TkB = 0 a1, a1Ok := reader.ReadByte() diff --git a/third_party/message/can_btm_rsp.go b/third_party/message/can_btm_rsp.go index dadc599..2ab9c44 100644 --- a/third_party/message/can_btm_rsp.go +++ b/third_party/message/can_btm_rsp.go @@ -61,60 +61,38 @@ func CreateBtmRspFramesData(statusRsp *BtmStatusRspFrame, msg []byte, msgPackErr end := NewBtmDataMessageEndFrame(sn) end.TkB = tkTimeB // - crc32CData := make([]byte, 0, 132) //17*8-4 - rt := make([]byte, 0, 204) //17*12 - // 状态应答帧 - statusData := statusRsp.Encode() - crc32CData = append(crc32CData, canFrameContent(statusData)...) - rt = append(rt, statusData.GetData()...) - // 数据帧 + statusCf := statusRsp.Encode() + dmsCfs := make([]*CanetFrame, 0, 13) for _, dm := range dms { - dmData := dm.Encode() - crc32CData = append(crc32CData, canFrameContent(dmData)...) - rt = append(rt, dmData.GetData()...) - } - // 消息时刻A - dtAData := dtA.Encode() - crc32CData = append(crc32CData, canFrameContent(dtAData)...) - rt = append(rt, dtAData.GetData()...) - // 消息时刻B - dtBData := dtB.Encode() - crc32CData = append(crc32CData, canFrameContent(dtBData)...) - rt = append(rt, dtBData.GetData()...) - // 消息结束帧 - crc32CData = append(crc32CData, canTimeToBytes(end.TkB)...) - if len(crc32CData) != 132 { - slog.Warn("BtmDataMessageEndFrame crc32 校验数据须132字节") - return nil, false - } - end.Crc32C = calculateDataRspCrc32C(crc32CData) - rt = append(rt, end.Encode().GetData()...) - if len(rt) != 204 { - slog.Warn("BTM响应ATP 17帧须136字节") - return nil, false + dmsCfs = append(dmsCfs, dm.Encode()) } + dtACf := dtA.Encode() + dtBCf := dtB.Encode() // + crc32cData := make([]byte, 0, 132) + crc32cData = append(crc32cData, statusCf.CanData...) + for _, dmCf := range dmsCfs { + crc32cData = append(crc32cData, dmCf.CanData...) + } + crc32cData = append(crc32cData, dtACf.CanData...) + crc32cData = append(crc32cData, dtBCf.CanData...) + crc32cData = append(crc32cData, canTimeToBytes(end.TkB)...) + // + end.Crc32C = calculateDataRspCrc32C(crc32cData) + // + endCf := end.Encode() + // + rt := make([]byte, 0, 221) //17*13 + rt = append(rt, statusCf.Encode()...) + for _, dmCf := range dmsCfs { + rt = append(rt, dmCf.Encode()...) + } + rt = append(rt, dtACf.Encode()...) + rt = append(rt, dtBCf.Encode()...) + rt = append(rt, endCf.Encode()...) + if len(rt) != 221 { + slog.Warn("len(rt)!=221") + return nil, false + } return rt, true } - -// CAN帧中除去开始29bits的剩余8字节数据 -func canFrameContent(canFrame CanBusData) []byte { - rd := NewCanBitsReader(canFrame.GetData(), canFrame.GetLastRowBitsLen()) - rd.ReadByte() //ID1 - rd.ReadByte() //ID2 - rd.ReadByte() //ID3 - rd.ReadBits(5) //ID4 - // - rt := make([]byte, 0, 8) - for { - d, ok := rd.ReadByte() - if !ok { - break - } - rt = append(rt, d) - } - if len(rt) != 8 { - panic("CAN帧中数据体须为8字节") - } - return rt -} diff --git a/third_party/message/can_btm_status_rsp.go b/third_party/message/can_btm_status_rsp.go index ffef805..39f2564 100644 --- a/third_party/message/can_btm_status_rsp.go +++ b/third_party/message/can_btm_status_rsp.go @@ -29,10 +29,10 @@ func NewBtmStatusRspFrame(sn byte) *BtmStatusRspFrame { FId: *NewCanFrameId(CAN_ADDR_RSP_ATP, CAN_ADDR_RSP_BTM, CAN_FRAME_STATUS_RSP, sn), } } -func (f *BtmStatusRspFrame) Decode(reader CanBitsReader) bool { - if !f.FId.Decode(reader) { - return false - } +func (f *BtmStatusRspFrame) Decode(cf *CanetFrame) bool { + f.FId = cf.CanId + // + reader := NewCanBitsReader(cf.CanData, 8) //数据流水号 if d, ok := reader.ReadByte(); ok { f.Dsn = d @@ -106,10 +106,14 @@ func (f *BtmStatusRspFrame) Decode(reader CanBitsReader) bool { // return true } -func (f *BtmStatusRspFrame) Encode() CanBusData { - writer := NewCanBitsWriter(12) +func (f *BtmStatusRspFrame) Encode() *CanetFrame { + cf := &CanetFrame{} + cf.CanId = f.FId + cf.CanLen = 8 + cf.FF = true + cf.RTR = false // - f.FId.Encode(writer) + writer := NewCanBitsWriter(8) writer.AddByte(f.Dsn) writer.AddByte(f.BaliseCounter) writer.AddByte(f.MessageCounter) @@ -150,5 +154,6 @@ func (f *BtmStatusRspFrame) Encode() CanBusData { writer.AddByte(tk3) writer.AddByte(tk4) // - return writer.(CanBusData) + cf.CanData = writer.(CanBusData).GetData() + return cf } diff --git a/third_party/message/can_btm_time_sync_rsp.go b/third_party/message/can_btm_time_sync_rsp.go index 77afddd..0e9b940 100644 --- a/third_party/message/can_btm_time_sync_rsp.go +++ b/third_party/message/can_btm_time_sync_rsp.go @@ -17,11 +17,10 @@ func NewBtmTimeSyncCheckFrame(sn byte) *BtmTimeSyncCheckFrame { FId: *NewCanFrameId(CAN_ADDR_RSP_ATP, CAN_ADDR_RSP_BTM, CAN_FRAME_TIME_SYNC_RSP, sn), } } -func (f *BtmTimeSyncCheckFrame) Decode(reader CanBitsReader) bool { +func (f *BtmTimeSyncCheckFrame) Decode(cf *CanetFrame) bool { + f.FId = cf.CanId // - if !f.FId.Decode(reader) { - return false - } + reader := NewCanBitsReader(cf.CanData, 8) //T2 t21, t21Ok := reader.ReadByte() if !t21Ok { @@ -69,9 +68,14 @@ func (f *BtmTimeSyncCheckFrame) Decode(reader CanBitsReader) bool { // return true } -func (f *BtmTimeSyncCheckFrame) Encode() CanBusData { - writer := NewCanBitsWriter(12) - f.FId.Encode(writer) +func (f *BtmTimeSyncCheckFrame) Encode() *CanetFrame { + cf := &CanetFrame{} + cf.CanId = f.FId + cf.CanLen = 8 + cf.FF = true + cf.RTR = false + // + writer := NewCanBitsWriter(8) // timeByteMsk := uint32(0x00_00_00_ff) //t2 @@ -93,5 +97,6 @@ func (f *BtmTimeSyncCheckFrame) Encode() CanBusData { writer.AddByte(t33) writer.AddByte(t34) // - return writer.(CanBusData) + cf.CanData = writer.(CanBusData).GetData() + return cf } diff --git a/third_party/message/can_bus.go b/third_party/message/can_bus.go index 25f4d7b..8c5ea4c 100644 --- a/third_party/message/can_bus.go +++ b/third_party/message/can_bus.go @@ -4,8 +4,6 @@ package message // CanBits 可以在CAN总线上传输的bit流 // 按bit位来存储数据 -// 一个字节中bit位编号,从高位到低位依次为bit7-bit0 -// 对于一个CAN帧:29bits帧ID+64bits帧数据,以bit为单位,最后一字节即第12个字节的低位3bits为无用数据 type CanBits struct { Data []byte //bits LastBitsLen int //Data中最后一个字节中从高位到低位存储数据的有效位数,值范围[1,8],8-LastBitsLen则为最后一个字节中低位剩余的空位数量 @@ -211,7 +209,7 @@ var ( crc32CanTable []uint32 = nil ) -func CanCreateCrcTable() { +func CreateCanCrcTable() { if crc16AtpReqTable == nil { crc16AtpReqTable = CreateCrcTable(CAN_CRC16_ATPREQ, 16, false) } diff --git a/third_party/message/can_net.go b/third_party/message/can_net.go new file mode 100644 index 0000000..c76be01 --- /dev/null +++ b/third_party/message/can_net.go @@ -0,0 +1,71 @@ +package message + +import ( + "fmt" + "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字节 +} + +func NewCanetFrame(buf []byte) *CanetFrame { + cf := &CanetFrame{} + cf.Decode(buf) + return cf +} +func (p *CanetFrame) Encode() []byte { + buf := make([]byte, 0, 13) + //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 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("FF = %t, RTR = %t, CanLen = %d, ID1 = 0x%0x, ID2 = 0x%0x, ID3 = 0x%0x, ID4 = 0x%0x,", p.FF, p.RTR, p.CanLen, + p.CanId.ID1, p.CanId.ID2, p.CanId.ID3, p.CanId.ID4)) + sb.WriteString("CanData = ") + for _, d := range p.CanData { + sb.WriteString(fmt.Sprintf(" 0x%0x ", d)) + } + return sb.String() +}