Skip to content

Commit

Permalink
CANIDBuilder improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
FerroO2000 committed May 24, 2024
1 parent c34a2be commit 8a68d61
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 9 deletions.
3 changes: 3 additions & 0 deletions bus.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,9 @@ func (b *Bus) Baudrate() int {

// SetCANIDBuilder sets the [CANIDBuilder] of the [Bus].
func (b *Bus) SetCANIDBuilder(canIDBuilder *CANIDBuilder) {
if b.canIDBuilder != nil {
b.canIDBuilder.removeRef(b.entityID)
}
b.canIDBuilder = canIDBuilder
}

Expand Down
32 changes: 31 additions & 1 deletion canid_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"strings"
)

var defaulCANIDBuilder = NewCANIDBuilder("default CAN-ID builder").UseNodeID(0, 4).UseMessageID(4, 7)
var defaulCANIDBuilder = NewCANIDBuilder("default CAN-ID builder").UseNodeID(0, 4).UseMessageID(4, 7).UseCAN2A()

// CANID is the CAN-ID of a [Message] within a [Bus].
// Every message should have a different CAN-ID.
Expand All @@ -25,6 +25,8 @@ const (
// CANIDBuilderOpKindNodeID represents an operation
// that involves the node id.
CANIDBuilderOpKindNodeID
// CANIDBuilderOpKindBitMask represents a bit masking operation.
CANIDBuilderOpKindBitMask
)

func (bok CANIDBuilderOpKind) String() string {
Expand All @@ -35,6 +37,8 @@ func (bok CANIDBuilderOpKind) String() string {
return "message-id"
case CANIDBuilderOpKindNodeID:
return "node-id"
case CANIDBuilderOpKindBitMask:
return "bit-mask"
default:
return "unknown"
}
Expand Down Expand Up @@ -115,6 +119,12 @@ func (b *CANIDBuilder) Calculate(messagePriority MessagePriority, messageID Mess
canID := uint32(0)

for _, op := range b.operations {
if op.kind == CANIDBuilderOpKindBitMask {
mask := uint32(0xFFFFFFFF) >> uint32(32-op.len)
canID &= (mask << uint32(op.from))
continue
}

tmpVal := uint32(0)
switch op.kind {
case CANIDBuilderOpKindMessagePriority:
Expand Down Expand Up @@ -165,3 +175,23 @@ func (b *CANIDBuilder) UseNodeID(from, len int) *CANIDBuilder {
})
return b
}

// UseCAN2A adds a bit mask from 0 with a length of 11,
// which makes the calculated CAN-ID conformed to the CAN 2.0A.
func (b *CANIDBuilder) UseCAN2A() *CANIDBuilder {
b.operations = append(b.operations, &CANIDBuilderOp{
kind: CANIDBuilderOpKindBitMask,
from: 0,
len: 11,
})
return b
}

// UseBitMask adds a bit mask operation from the given index and length.
func (b *CANIDBuilder) UseBitMask(from, len int) {
b.operations = append(b.operations, &CANIDBuilderOp{
kind: CANIDBuilderOpKindBitMask,
from: from,
len: len,
})
}
17 changes: 13 additions & 4 deletions canid_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
func Test_CANIDBuilder(t *testing.T) {
assert := assert.New(t)

b := NewCANIDBuilder("canid_builder")
b.UseMessagePriority(30).UseMessageID(4, 10).UseNodeID(0, 4)
b0 := NewCANIDBuilder("canid_builder_0")
b0.UseMessagePriority(30).UseMessageID(4, 10).UseNodeID(0, 4)

msgPriority := MessagePriorityLow
msgID := MessageID(0b1111111111)
Expand All @@ -20,7 +20,16 @@ func Test_CANIDBuilder(t *testing.T) {
expected |= uint32(msgID << 4)
expected |= uint32(nodeID)

res := b.Calculate(msgPriority, msgID, nodeID)
res0 := b0.Calculate(msgPriority, msgID, nodeID)

assert.Equal(expected, uint32(res))
assert.Equal(expected, uint32(res0))

b1 := NewCANIDBuilder("canid_builder_1")
b1.UseMessageID(4, 10).UseCAN2A()

expected = uint32(msgID<<4) & 0b11111111111

res1 := b1.Calculate(msgPriority, msgID, nodeID)

assert.Equal(expected, uint32(res1))
}
7 changes: 4 additions & 3 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,21 @@ func CalculateBusLoad(bus *Bus, defCycleTime int) (float64, error) {

var headerBits int
var trailerBits int
var stuffingBits int
var headerStuffingBits int
switch bus.typ {
case BusTypeCAN2A:
// start of frame + id + rtr + ide + r0 + dlc
headerBits = 19
// crc + delim crc + slot ack + delim ack + eof
trailerBits = 25
// worst case scenario
stuffingBits = 19
// from wikipedia
headerStuffingBits = 34
}

consumedBitsPerSec := float64(0)
for _, tmpInt := range bus.nodeInts.getValues() {
for _, tmpMsg := range tmpInt.messages.getValues() {
stuffingBits := (headerStuffingBits + tmpMsg.sizeByte*8 - 1) / 4
msgBits := tmpMsg.sizeByte*8 + headerBits + trailerBits + stuffingBits

var cycleTime int
Expand Down
3 changes: 2 additions & 1 deletion utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ func Test_CalculateBusLoad(t *testing.T) {

load, err := CalculateBusLoad(bus, 500)
assert.NoError(err)
assert.Equal(10.16, load)
assert.Greater(load, 10.0)
assert.Less(load, 11.0)

argErr := &ArgumentError{}

Expand Down

0 comments on commit 8a68d61

Please sign in to comment.