Skip to content

Commit

Permalink
Updated README with example of decoding and dbc file with >8 byte mes…
Browse files Browse the repository at this point in the history
…sage (#6)

* Updated README with example of decoding and dbc file with >8 byte message

* Fixed indenting in README

* Fixed indenting in README part 2

* Updated filename to example_payload.dbc

* Updated dbc messages and removed unnecessary code from payload.go

Co-authored-by: Naveen Venkatesan <nvenkatesan@rivian.com>
  • Loading branch information
naveenv92 and Naveen Venkatesan authored Apr 1, 2021
1 parent 6e5dbc8 commit cddec59
Show file tree
Hide file tree
Showing 4 changed files with 272 additions and 210 deletions.
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,45 @@ can-go makes use of the Linux SocketCAN abstraction for CAN communication.

## Examples

### Decoding CAN messages

Decoding CAN messages from byte arrays can be done using `can.Payload`

```go
func main() {
// Create payload from hex string
byteStringHex := "8000000420061880000005200600"
p, _ := can.PayloadFromHex(byteStringHex)

// Load example dbc file
dbcFile := "./testdata/dbc/example/example_payload.dbc"
input, _ := ioutil.ReadFile(dbcFile)
c, _ := generate.Compile(dbcFile, input)
db := *c.Database

// Decode message frame ID 1530
message, _ := db.Message(uint32(1530))
decodedSignals := message.Decode(&p)
for _, signal := range decodedSignals {
fmt.Printf("Signal: %s, Value: %f, Description: %s\n", signal.Signal.Name, signal.Value, signal.Description)
}
}
```

```
Signal: TargetSpeedRearLeft, Value: 0.000000, Description:
Signal: DisconnectStateRearLeftTarget, Value: 0.000000, Description:
Signal: CurrentRearLeft, Value: 4.000000, Description:
Signal: LockCountRearLeft, Value: 1560.000000, Description:
Signal: DisconnectStateRearLeft, Value: 2.000000, Description: Unlocked
Signal: TargetSpeedRearRight, Value: 0.000000, Description:
Signal: DisconnectStateRearRightTarget, Value: 0.000000, Description:
Signal: CurrentRearRight, Value: 5.000000, Description:
Signal: LockCountRearRight, Value: 1536.000000, Description:
Signal: DisconnectStateRearRight, Value: 2.000000, Description: Unlocked
```


### Receiving CAN frames

Receiving CAN frames from a socketcan interface.
Expand Down
266 changes: 99 additions & 167 deletions payload.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,98 +5,93 @@ import (
"math/big"
)

// const MaxDataLength = 8

// // Data holds the data in a CAN frame.
// //
// // Layout
// //
// // Individual bits in the data are numbered according to the following scheme:
// //
// // BIT
// // NUMBER
// // +------+------+------+------+------+------+------+------+
// // | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
// // BYTE +------+------+------+------+------+------+------+------+
// // NUMBER
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 0 | | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 1 | | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 2 | | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 3 | | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 4 | | 39 | 38 | 37 | 36 | 35 | 34 | 33 | 32 |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 5 | | 47 | 46 | 45 | 44 | 43 | 42 | 41 | 40 |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 6 | | 55 | 54 | 53 | 52 | 51 | 50 | 49 | 48 |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 7 | | 63 | 62 | 61 | 60 | 59 | 58 | 57 | 56 |
// // +-----+ +------+------+------+------+------+------+------+------+
// //
// // Bit ranges can be manipulated using little-endian and big-endian bit ordering.
// //
// // Little-endian bit ranges
// //
// // Example range of length 32 starting at bit 29:
// //
// // BIT
// // NUMBER
// // +------+------+------+------+------+------+------+------+
// // | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
// // BYTE +------+------+------+------+------+------+------+------+
// // NUMBER
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 0 | | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 1 | | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 2 | | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 3 | | <-------------LSb | 28 | 27 | 26 | 25 | 24 |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 4 | | <-------------------------------------------------- |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 5 | | <-------------------------------------------------- |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 6 | | <-------------------------------------------------- |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 7 | | 63 | 62 | 61 | <-MSb--------------------------- |
// // +-----+ +------+------+------+------+------+------+------+------+
// //
// // Big-endian bit ranges
// //
// // Example range of length 32 starting at bit 29:
// //
// // BIT
// // NUMBER
// // +------+------+------+------+------+------+------+------+
// // | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
// // BYTE +------+------+------+------+------+------+------+------+
// // NUMBER
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 0 | | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 1 | | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 2 | | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 3 | | 31 | 30 | <-MSb--------------------------------- |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 4 | | <-------------------------------------------------- |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 5 | | <-------------------------------------------------- |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 6 | | <-------------------------------------------------- |
// // +-----+ +------+------+------+------+------+------+------+------+
// // | 7 | | <------LSb | 61 | 60 | 59 | 58 | 57 | 56 |
// // +-----+ +------+------+------+------+------+------+------+------+
// type Data [MaxDataLength]byte

//type Packed *big.Int
// Data holds the data in a CAN frame.
//
// Layout
//
// Individual bits in the data are numbered according to the following scheme:
//
// BIT
// NUMBER
// +------+------+------+------+------+------+------+------+
// | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
// BYTE +------+------+------+------+------+------+------+------+
// NUMBER
// +-----+ +------+------+------+------+------+------+------+------+
// | 0 | | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
// +-----+ +------+------+------+------+------+------+------+------+
// | 1 | | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 |
// +-----+ +------+------+------+------+------+------+------+------+
// | 2 | | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
// +-----+ +------+------+------+------+------+------+------+------+
// | 3 | | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 |
// +-----+ +------+------+------+------+------+------+------+------+
// | 4 | | 39 | 38 | 37 | 36 | 35 | 34 | 33 | 32 |
// +-----+ +------+------+------+------+------+------+------+------+
// | 5 | | 47 | 46 | 45 | 44 | 43 | 42 | 41 | 40 |
// +-----+ +------+------+------+------+------+------+------+------+
// | 6 | | 55 | 54 | 53 | 52 | 51 | 50 | 49 | 48 |
// +-----+ +------+------+------+------+------+------+------+------+
// | 7 | | 63 | 62 | 61 | 60 | 59 | 58 | 57 | 56 |
// +-----+ +------+------+------+------+------+------+------+------+
//
// Bit ranges can be manipulated using little-endian and big-endian bit ordering.
//
// Little-endian bit ranges
//
// Example range of length 32 starting at bit 29:
//
// BIT
// NUMBER
// +------+------+------+------+------+------+------+------+
// | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
// BYTE +------+------+------+------+------+------+------+------+
// NUMBER
// +-----+ +------+------+------+------+------+------+------+------+
// | 0 | | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
// +-----+ +------+------+------+------+------+------+------+------+
// | 1 | | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 |
// +-----+ +------+------+------+------+------+------+------+------+
// | 2 | | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
// +-----+ +------+------+------+------+------+------+------+------+
// | 3 | | <-------------LSb | 28 | 27 | 26 | 25 | 24 |
// +-----+ +------+------+------+------+------+------+------+------+
// | 4 | | <-------------------------------------------------- |
// +-----+ +------+------+------+------+------+------+------+------+
// | 5 | | <-------------------------------------------------- |
// +-----+ +------+------+------+------+------+------+------+------+
// | 6 | | <-------------------------------------------------- |
// +-----+ +------+------+------+------+------+------+------+------+
// | 7 | | 63 | 62 | 61 | <-MSb--------------------------- |
// +-----+ +------+------+------+------+------+------+------+------+
//
// Big-endian bit ranges
//
// Example range of length 32 starting at bit 29:
//
// BIT
// NUMBER
// +------+------+------+------+------+------+------+------+
// | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
// BYTE +------+------+------+------+------+------+------+------+
// NUMBER
// +-----+ +------+------+------+------+------+------+------+------+
// | 0 | | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
// +-----+ +------+------+------+------+------+------+------+------+
// | 1 | | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 |
// +-----+ +------+------+------+------+------+------+------+------+
// | 2 | | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
// +-----+ +------+------+------+------+------+------+------+------+
// | 3 | | 31 | 30 | <-MSb--------------------------------- |
// +-----+ +------+------+------+------+------+------+------+------+
// | 4 | | <-------------------------------------------------- |
// +-----+ +------+------+------+------+------+------+------+------+
// | 5 | | <-------------------------------------------------- |
// +-----+ +------+------+------+------+------+------+------+------+
// | 6 | | <-------------------------------------------------- |
// +-----+ +------+------+------+------+------+------+------+------+
// | 7 | | <------LSb | 61 | 60 | 59 | 58 | 57 | 56 |
// +-----+ +------+------+------+------+------+------+------+------+

type Payload struct {
// Binary data
Expand Down Expand Up @@ -168,13 +163,8 @@ func (p *Payload) SignedBitsBigEndian(start, length uint16) int64 {
return AsSigned(unsigned, length)
}

// SignedBitsBigEndian returns little-endian bit range [start, start+length) as a signed value.
// func (d *Data) SignedBitsBigEndian(start, length uint8) int64 {
// unsigned := d.UnsignedBitsBigEndian(start, length)
// return reinterpret.AsSigned(unsigned, length)
// }

// // SetUnsignedBitsBigEndian sets the little-endian bit range [start, start+length) to the provided unsigned value.
// TODO: Implement SetUnsignedBitsLittleEndian for Payload
// SetUnsignedBitsLittleEndian sets the little-endian bit range [start, start+length) to the provided unsigned value.
// func (d *Data) SetUnsignedBitsLittleEndian(start, length uint8, value uint64) {
// // pack bits into one continuous value
// packed := d.PackLittleEndian()
Expand All @@ -190,7 +180,8 @@ func (p *Payload) SignedBitsBigEndian(start, length uint16) int64 {
// d.UnpackLittleEndian(newPacked)
// }

// // SetUnsignedBitsBigEndian sets the big-endian bit range [start, start+length) to the provided unsigned value.
// TODO: Implement SetUnsignedBitsBigEndian for Payload
// SetUnsignedBitsBigEndian sets the big-endian bit range [start, start+length) to the provided unsigned value.
// func (d *Data) SetUnsignedBitsBigEndian(start, length uint8, value uint64) {
// // pack bits into one continuous value
// packed := d.PackBigEndian()
Expand All @@ -208,12 +199,14 @@ func (p *Payload) SignedBitsBigEndian(start, length uint16) int64 {
// d.UnpackBigEndian(newPacked)
// }

// // SetSignedBitsLittleEndian sets the little-endian bit range [start, start+length) to the provided signed value.
// TODO: Implement SetSignedBitsLittleEndian for Payload
// SetSignedBitsLittleEndian sets the little-endian bit range [start, start+length) to the provided signed value.
// func (d *Data) SetSignedBitsLittleEndian(start, length uint8, value int64) {
// d.SetUnsignedBitsLittleEndian(start, length, reinterpret.AsUnsigned(value, length))
// }

// // SetSignedBitsBigEndian sets the big-endian bit range [start, start+length) to the provided signed value.
// TODO: Implement SetSignedBitsBigEndian for Payload
// SetSignedBitsBigEndian sets the big-endian bit range [start, start+length) to the provided signed value.
// func (d *Data) SetSignedBitsBigEndian(start, length uint8, value int64) {
// d.SetUnsignedBitsBigEndian(start, length, reinterpret.AsUnsigned(value, length))
// }
Expand Down Expand Up @@ -247,20 +240,6 @@ func (p *Payload) SetBit(i uint16, value bool) {
}
}

// PackLittleEndian packs the data into a contiguous uint64 value for little-endian signals.
// func (d *Data) PackLittleEndian() uint64 {
// var packed uint64
// packed |= uint64(d[0]) << (0 * 8)
// packed |= uint64(d[1]) << (1 * 8)
// packed |= uint64(d[2]) << (2 * 8)
// packed |= uint64(d[3]) << (3 * 8)
// packed |= uint64(d[4]) << (4 * 8)
// packed |= uint64(d[5]) << (5 * 8)
// packed |= uint64(d[6]) << (6 * 8)
// packed |= uint64(d[7]) << (7 * 8)
// return packed
// }

// PackLittleEndian packs the byte array into a continuous little endian big.Int
func (p *Payload) PackLittleEndian() *big.Int {
if p.PackedLittleEndian == nil {
Expand All @@ -279,20 +258,6 @@ func reverse(data []byte) []byte {
return reversedArray
}

// // PackBigEndian packs the data into a contiguous uint64 value for big-endian signals.
// func (d *Data) PackBigEndian() uint64 {
// var packed uint64
// packed |= uint64(d[0]) << (7 * 8)
// packed |= uint64(d[1]) << (6 * 8)
// packed |= uint64(d[2]) << (5 * 8)
// packed |= uint64(d[3]) << (4 * 8)
// packed |= uint64(d[4]) << (3 * 8)
// packed |= uint64(d[5]) << (2 * 8)
// packed |= uint64(d[6]) << (1 * 8)
// packed |= uint64(d[7]) << (0 * 8)
// return packed
// }

// PackBigEndian packs the byte array into a continuous big endian big.Int
func (p *Payload) PackBigEndian() *big.Int {
if p.PackedBigEndian == nil {
Expand All @@ -302,7 +267,8 @@ func (p *Payload) PackBigEndian() *big.Int {
return new(big.Int).Set(p.PackedBigEndian)
}

// // UnpackLittleEndian sets the value of d.Bytes by unpacking the provided value as sequential little-endian bits.
// TODO: Implement UnpackLittleEndian for Payload
// UnpackLittleEndian sets the value of d.Bytes by unpacking the provided value as sequential little-endian bits.
// func (d *Data) UnpackLittleEndian(packed uint64) {
// d[0] = uint8(packed >> (0 * 8))
// d[1] = uint8(packed >> (1 * 8))
Expand All @@ -314,7 +280,8 @@ func (p *Payload) PackBigEndian() *big.Int {
// d[7] = uint8(packed >> (7 * 8))
// }

// // UnpackBigEndian sets the value of d.Bytes by unpacking the provided value as sequential big-endian bits.
// TODO: Implement UnpackBigEndian for Payload
// UnpackBigEndian sets the value of d.Bytes by unpacking the provided value as sequential big-endian bits.
// func (d *Data) UnpackBigEndian(packed uint64) {
// d[0] = uint8(packed >> (7 * 8))
// d[1] = uint8(packed >> (6 * 8))
Expand All @@ -335,41 +302,6 @@ func (p *Payload) invertEndian(i uint16) uint16 {
return bitIndex
}

// // CheckBitRangeLittleEndian checks that a little-endian bit range fits in the data.
// func CheckBitRangeLittleEndian(frameLength, rangeStart, rangeLength uint8) error {
// lsbIndex := rangeStart
// msbIndex := rangeStart + rangeLength - 1
// upperBound := frameLength * 8
// if msbIndex >= upperBound {
// return fmt.Errorf("bit range out of bounds [0, %v): [%v, %v]", upperBound, lsbIndex, msbIndex)
// }
// return nil
// }

// // CheckBitRangeBigEndian checks that a big-endian bit range fits in the data.
// func CheckBitRangeBigEndian(frameLength, rangeStart, rangeLength uint8) error {
// upperBound := frameLength * 8
// if rangeStart >= upperBound {
// return fmt.Errorf("bit range starts out of bounds [0, %v): %v", upperBound, rangeStart)
// }
// msbIndex := invertEndian(rangeStart)
// lsbIndex := msbIndex - rangeLength + 1
// end := invertEndian(lsbIndex)
// if end >= upperBound {
// return fmt.Errorf("bit range ends out of bounds [0, %v): %v", upperBound, end)
// }
// return nil
// }

// // CheckValue checks that a value fits in a number of bits.
// func CheckValue(value uint64, bits uint8) error {
// upperBound := uint64(1 << bits)
// if value >= upperBound {
// return fmt.Errorf("value out of bounds [0, %v): %v", upperBound, value)
// }
// return nil
// }

// AsSigned reinterprets the provided unsigned value as a signed value.
func AsSigned(unsigned uint64, bits uint16) int64 {
switch bits {
Expand Down
Loading

0 comments on commit cddec59

Please sign in to comment.