220 lines
5.7 KiB
Go
220 lines
5.7 KiB
Go
|
package message
|
|||
|
|
|||
|
/////////////////////CAN串行总线 bit 流处理 ////////////////////////
|
|||
|
|
|||
|
// CanBits 可以在CAN总线上传输的bit流
|
|||
|
// 按bit位来存储数据
|
|||
|
// 一个字节中bit位编号,从高位到低位依次为bit7-bit0
|
|||
|
type CanBits struct {
|
|||
|
Data []byte
|
|||
|
LastBitsLen int //Data中最后一个字节中从高位到低位存储数据的有效位数,值范围[1,8],8-LastBitsLen则为最后一个字节中低位剩余的空位数量
|
|||
|
readRowIndex int //行读指针,Data中的一个字节为一行,从0开始;当前值表示当前可读位置
|
|||
|
readColIndex int //列读指针,字节中的bit位为列,从7开始到0,字节中最左侧bit为最高位编号7;当前值表示当前可读位置;当值为-1时表示已经读结束
|
|||
|
}
|
|||
|
|
|||
|
// 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
|
|||
|
)
|
|||
|
|
|||
|
var (
|
|||
|
crc16AtpReqTable []uint32 = nil
|
|||
|
)
|
|||
|
|
|||
|
func CanCreateCrcTable() {
|
|||
|
if crc16AtpReqTable == nil {
|
|||
|
crc16AtpReqTable = CreateCrcTable(CAN_CRC16_ATPREQ, 16, false)
|
|||
|
}
|
|||
|
}
|
|||
|
func calculateAtpReqCrc16(data []byte) uint16 {
|
|||
|
crc := CrcTableBased(data, 16, 0, false, false, 0, crc16AtpReqTable)
|
|||
|
return uint16(crc)
|
|||
|
}
|