2023-11-17 14:37:32 +08:00
|
|
|
|
package message
|
|
|
|
|
|
|
|
|
|
/////////////////////CAN串行总线 bit 流处理 ////////////////////////
|
|
|
|
|
|
|
|
|
|
// CanBits 可以在CAN总线上传输的bit流
|
|
|
|
|
// 按bit位来存储数据
|
|
|
|
|
// 一个字节中bit位编号,从高位到低位依次为bit7-bit0
|
2023-11-20 10:24:55 +08:00
|
|
|
|
// 对于一个CAN帧:29bits帧ID+64bits帧数据,以bit为单位,最后一字节即第12个字节的低位3bits为无用数据
|
2023-11-17 14:37:32 +08:00
|
|
|
|
type CanBits struct {
|
2023-11-20 10:24:55 +08:00
|
|
|
|
Data []byte //bits
|
|
|
|
|
LastBitsLen int //Data中最后一个字节中从高位到低位存储数据的有效位数,值范围[1,8],8-LastBitsLen则为最后一个字节中低位剩余的空位数量
|
|
|
|
|
readRowIndex int //行读指针,Data中的一个字节为一行,从0开始;当前值表示当前可读位置
|
|
|
|
|
readColIndex int //列读指针,字节中的bit位为列,从7开始到0,字节中最左侧bit为最高位编号7;当前值表示当前可读位置;当值为-1时表示已经读结束
|
2023-11-17 14:37:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CanBusData CAN总线上传输的数据
|
|
|
|
|
type CanBusData interface {
|
|
|
|
|
GetData() []byte
|
|
|
|
|
GetLastRowBitsLen() int
|
|
|
|
|
}
|
|
|
|
|
type CanBitsReader interface {
|
|
|
|
|
// ReadByte 读取一个字节
|
|
|
|
|
ReadByte() (byte, bool)
|
|
|
|
|
// ReadBits 读取bits,一次最多8bits
|
|
|
|
|
ReadBits(bitsLen int) (byte, bool)
|
|
|
|
|
}
|
|
|
|
|
type CanBitsWriter interface {
|
|
|
|
|
// AddByte 添加一整个字节bit数据
|
|
|
|
|
AddByte(bits byte) bool
|
|
|
|
|
// AddBits 添加bit数据,bitsLen-bits字节中有效位数,有效位向低位对齐
|
|
|
|
|
AddBits(bits byte, bitsLen int) bool
|
|
|
|
|
//GetReader 获取CanBits reader
|
|
|
|
|
GetReader() CanBitsReader
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewCanBitsWriter(cap int) CanBitsWriter {
|
|
|
|
|
return &CanBits{LastBitsLen: 8, Data: make([]byte, 0, cap)}
|
|
|
|
|
}
|
|
|
|
|
func NewCanBitsReader(data []byte, lastRowBitsLen int) CanBitsReader {
|
|
|
|
|
return &CanBits{
|
|
|
|
|
LastBitsLen: lastRowBitsLen,
|
|
|
|
|
Data: data,
|
|
|
|
|
readRowIndex: 0,
|
|
|
|
|
readColIndex: 7,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
func (b *CanBits) GetData() []byte {
|
|
|
|
|
return b.Data
|
|
|
|
|
}
|
|
|
|
|
func (b *CanBits) GetLastRowBitsLen() int {
|
|
|
|
|
return b.LastBitsLen
|
|
|
|
|
}
|
|
|
|
|
func (b *CanBits) GetReader() CanBitsReader {
|
|
|
|
|
if len(b.Data) > 0 {
|
|
|
|
|
b.readRowIndex = 0
|
|
|
|
|
b.readColIndex = 7
|
|
|
|
|
} else {
|
|
|
|
|
b.readRowIndex = -1
|
|
|
|
|
}
|
|
|
|
|
return b
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ReadByte 读取一个字节
|
|
|
|
|
func (b *CanBits) ReadByte() (byte, bool) {
|
|
|
|
|
return b.ReadBits(8)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ReadBits 读取bits,一次最多8bits
|
|
|
|
|
func (b *CanBits) ReadBits(bitsLen int) (byte, bool) {
|
|
|
|
|
if bitsLen < 1 || bitsLen > 8 {
|
|
|
|
|
return 0, false
|
|
|
|
|
}
|
|
|
|
|
//当前可读行可读bits数
|
|
|
|
|
if !b.isReadEnd() {
|
|
|
|
|
rowBitsLen := b.curRowCanReadLen()
|
|
|
|
|
if bitsLen <= rowBitsLen { //当前行有足够的bits
|
|
|
|
|
sb := b.Data[b.readRowIndex]
|
|
|
|
|
sb >>= b.readColIndex - bitsLen + 1
|
|
|
|
|
b.toNextReadPos(bitsLen)
|
|
|
|
|
return sb & b.getCanBitsMask(bitsLen), true
|
|
|
|
|
} else { //当前行没有有足够的bits
|
|
|
|
|
sb1 := b.Data[b.readRowIndex]
|
|
|
|
|
rt1 := sb1 >> (b.readColIndex - rowBitsLen + 1)
|
|
|
|
|
rt1 <<= bitsLen - rowBitsLen
|
|
|
|
|
b.toNextReadPos(rowBitsLen)
|
|
|
|
|
if !b.isReadEnd() {
|
|
|
|
|
readBitsLen := bitsLen - rowBitsLen
|
|
|
|
|
if b.curRowCanReadLen() >= readBitsLen {
|
|
|
|
|
sb2 := b.Data[b.readRowIndex]
|
|
|
|
|
sb2 >>= b.readColIndex - readBitsLen + 1
|
|
|
|
|
b.toNextReadPos(readBitsLen)
|
|
|
|
|
return (rt1 | sb2) & b.getCanBitsMask(bitsLen), true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//
|
|
|
|
|
return 0, false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 是否读到最后一行
|
|
|
|
|
func (b *CanBits) isReadInLastRow() bool {
|
|
|
|
|
return b.readRowIndex == len(b.Data)-1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 当前可读行可读bits数
|
|
|
|
|
func (b *CanBits) curRowCanReadLen() int {
|
|
|
|
|
if b.isReadInLastRow() {
|
|
|
|
|
return b.LastBitsLen - (7 - b.readColIndex)
|
|
|
|
|
} else {
|
|
|
|
|
return b.readColIndex + 1
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
func (b *CanBits) toNextReadPos(hadReadRowLen int) {
|
|
|
|
|
lastRow := b.isReadInLastRow()
|
|
|
|
|
b.readColIndex -= hadReadRowLen
|
|
|
|
|
if !lastRow {
|
|
|
|
|
if b.readColIndex < 0 {
|
|
|
|
|
b.readRowIndex++
|
|
|
|
|
b.readColIndex = 7
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 是否读结束
|
|
|
|
|
func (b *CanBits) isReadEnd() bool {
|
|
|
|
|
return b.isReadInLastRow() && (7-b.readColIndex >= b.LastBitsLen) || b.readRowIndex < 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AddByte 添加一整个字节bit数据
|
|
|
|
|
func (b *CanBits) AddByte(bits byte) bool {
|
|
|
|
|
return b.AddBits(bits, 8)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AddBits 添加bit数据,bitsLen-bits字节中有效位数,有效位向低位对齐
|
|
|
|
|
func (b *CanBits) AddBits(bits byte, bitsLen int) bool {
|
|
|
|
|
if bitsLen < 1 || bitsLen > 8 {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
if len(b.Data) <= 0 {
|
|
|
|
|
b.LastBitsLen = 8
|
|
|
|
|
}
|
|
|
|
|
//
|
|
|
|
|
bits &= b.getCanBitsMask(bitsLen)
|
|
|
|
|
//
|
|
|
|
|
lastByteHavePos := b.LastBitsLen < 8
|
|
|
|
|
if lastByteHavePos {
|
|
|
|
|
lastBytePosWidth := 8 - b.LastBitsLen //最后一个字节低位剩余可用bit位
|
|
|
|
|
if bitsLen <= lastBytePosWidth { //最后一个字节有足够的空位
|
|
|
|
|
bits <<= lastBytePosWidth - bitsLen
|
|
|
|
|
b.Data[len(b.Data)-1] |= bits
|
|
|
|
|
b.LastBitsLen += bitsLen
|
|
|
|
|
} else { //最后一个字节没有足够的空位
|
|
|
|
|
lb := bits >> (bitsLen - lastBytePosWidth)
|
|
|
|
|
b.Data[len(b.Data)-1] |= lb //至此最后一个字节中的位存满
|
|
|
|
|
//
|
|
|
|
|
nb := bits << (8 - (bitsLen - lastBytePosWidth))
|
|
|
|
|
b.Data = append(b.Data, nb)
|
|
|
|
|
b.LastBitsLen = bitsLen - lastBytePosWidth
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
bits <<= 8 - bitsLen
|
|
|
|
|
b.Data = append(b.Data, bits)
|
|
|
|
|
b.LastBitsLen = bitsLen
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
func (b *CanBits) getCanBitsMask(bitsLen int) byte {
|
|
|
|
|
switch bitsLen {
|
|
|
|
|
case 1:
|
|
|
|
|
return CAN_BITS_LEN1
|
|
|
|
|
case 2:
|
|
|
|
|
return CAN_BITS_LEN2
|
|
|
|
|
case 3:
|
|
|
|
|
return CAN_BITS_LEN3
|
|
|
|
|
case 4:
|
|
|
|
|
return CAN_BITS_LEN4
|
|
|
|
|
case 5:
|
|
|
|
|
return CAN_BITS_LEN5
|
|
|
|
|
case 6:
|
|
|
|
|
return CAN_BITS_LEN6
|
|
|
|
|
case 7:
|
|
|
|
|
return CAN_BITS_LEN7
|
|
|
|
|
case 8:
|
|
|
|
|
return CAN_BITS_LEN8
|
|
|
|
|
default:
|
|
|
|
|
panic("bitsLen<1||bitsLen>8")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
CAN_BITS_LEN1 = byte(0b0000_0001)
|
|
|
|
|
CAN_BITS_LEN2 = byte(0b0000_0011)
|
|
|
|
|
CAN_BITS_LEN3 = byte(0b0000_0111)
|
|
|
|
|
CAN_BITS_LEN4 = byte(0b0000_1111)
|
|
|
|
|
CAN_BITS_LEN5 = byte(0b0001_1111)
|
|
|
|
|
CAN_BITS_LEN6 = byte(0b0011_1111)
|
|
|
|
|
CAN_BITS_LEN7 = byte(0b0111_1111)
|
|
|
|
|
CAN_BITS_LEN8 = byte(0b1111_1111)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
///////////////////// CRC ////////////////////////
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
CAN_CRC16_ATPREQ = 0x11021
|
2023-11-21 14:30:42 +08:00
|
|
|
|
CAN_CRC32 = 0x04C11DB7
|
2023-11-17 14:37:32 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
crc16AtpReqTable []uint32 = nil
|
2023-11-21 14:30:42 +08:00
|
|
|
|
crc32CanTable []uint32 = nil
|
2023-11-17 14:37:32 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func CanCreateCrcTable() {
|
|
|
|
|
if crc16AtpReqTable == nil {
|
|
|
|
|
crc16AtpReqTable = CreateCrcTable(CAN_CRC16_ATPREQ, 16, false)
|
|
|
|
|
}
|
2023-11-21 14:30:42 +08:00
|
|
|
|
if crc32CanTable == nil {
|
|
|
|
|
crc32CanTable = CreateCrcTable(CAN_CRC32, 32, false)
|
|
|
|
|
}
|
2023-11-17 14:37:32 +08:00
|
|
|
|
}
|
|
|
|
|
func calculateAtpReqCrc16(data []byte) uint16 {
|
|
|
|
|
crc := CrcTableBased(data, 16, 0, false, false, 0, crc16AtpReqTable)
|
|
|
|
|
return uint16(crc)
|
|
|
|
|
}
|
2023-11-21 14:30:42 +08:00
|
|
|
|
func calculateCanCrc32(data []byte) uint32 {
|
|
|
|
|
crc := CrcTableBased(data, 32, 0xFF_FF_FF_FF, false, false, 0, crc32CanTable)
|
|
|
|
|
return crc
|
|
|
|
|
}
|
2023-11-20 16:55:07 +08:00
|
|
|
|
|
|
|
|
|
// CRC32A的校验范围是:报文+时间戳A
|
|
|
|
|
func calculateDataRspCrc32A(data []byte) uint32 {
|
2023-11-21 14:30:42 +08:00
|
|
|
|
return calculateCanCrc32(data)
|
2023-11-20 16:55:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CRC32B的校验范围是:报文+时间戳B
|
|
|
|
|
func calculateDataRspCrc32B(data []byte) uint32 {
|
2023-11-21 14:30:42 +08:00
|
|
|
|
return calculateCanCrc32(data)
|
2023-11-20 16:55:07 +08:00
|
|
|
|
}
|
|
|
|
|
func calculateDataRspCrc32C(data []byte) uint32 {
|
2023-11-21 14:30:42 +08:00
|
|
|
|
return calculateCanCrc32(data)
|
2023-11-20 16:55:07 +08:00
|
|
|
|
}
|