Skip to content

Commit 4e109af

Browse files
committed
Merged code base with CanBus improvements
2 parents 5eeb370 + 5387184 commit 4e109af

File tree

8 files changed

+228
-24
lines changed

8 files changed

+228
-24
lines changed

ArrowPoint-CANbus-Test/ArrowPointCANBusTest.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,11 @@
6767
<Content Include="Test-Data\Configuration\CanConfig.xml">
6868
<SubType>Designer</SubType>
6969
</Content>
70+
<Content Include="Test-Data\Configuration\dbc standard.txt" />
7071
</ItemGroup>
7172
<ItemGroup>
7273
<None Include="packages.config" />
74+
<None Include="Test-Data\Configuration\WaveSculter.dbc" />
7375
</ItemGroup>
7476
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
7577
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Scope
2+
This document doesn't claim to specifiy the complete [Vector DBC standard](http://vector.com/vi_candb_en.html)
3+
4+
# Format description
5+
`<...>`: Required field
6+
`[...]`: Optional field
7+
` | `: Or (eg. <A|B>)
8+
9+
# Supported Keywords
10+
## VERSION
11+
Version identifier of the DBC file.
12+
Format: `VERSION "<VersionIdentifier>"`
13+
14+
## BS_
15+
Bus configuration.
16+
Format:: `BS_: <Speed>`
17+
Speed in kBit/s
18+
19+
## BU_
20+
List of all CAN-Nodes, seperated by whitespaces.
21+
22+
## BO_
23+
Message definition.
24+
Format: `BO_ <CAN-ID> <MessageName>: <MessageLength> <SendingNode>`
25+
MessageLength in bytes.
26+
27+
## SG_
28+
Signal definition.
29+
Format: `SG_ <SignalName> [M|m<MultiplexerIdentifier>] : <StartBit>|<Length>@<Endianness><Signed> (<Factor>,<Offset>) [<Min>|<Max>] "[Unit]" [ReceivingNodes]`
30+
Length in bits.
31+
Signed: + = unsigned; - = signed
32+
Endianness: 1 = little-endian, Intel; 0 = big-endian, Motorola
33+
M: If M than this signals contains a multiplexer identifier.
34+
MultiplexerIdentifier: Signal definition is only used if the value of the multiplexer signal equals to this value.
35+
36+
## CM_
37+
Description field.
38+
Format: `CM_ [<BU_|BO_|SG_> [CAN-ID] [SignalName]] "<DescriptionText>";`
39+
40+
## BA_DEF_
41+
Attribute definition.
42+
Format: `BA_DEF_ [BU_|BO_|SG_] "<AttributeName>" <DataType> [Config];`
43+
44+
DataType | Description | Config format
45+
---------|---------------------|----------------
46+
INT | integer | `<min> <max>`
47+
FLOAT | floating point | `<min> <max>`
48+
STRING | string |
49+
ENUM | enumeration | `"<Value0>","<Value1>"...`
50+
51+
## BA_DEF_DEF_
52+
Attribute default value
53+
Format: `BA_DEF_DEF_ "<AttributeName>" ["]<DefaultValue>["];`
54+
55+
## BA_
56+
Attribute
57+
Format: `BA_ "<AttributeName>" [BU_|BO_|SG_] [Node|CAN-ID] [SignalName] <AttributeValue>;`
58+
59+
## VAL_
60+
Value definitions for signals.
61+
Format: `VAL_ <CAN-ID> <SignalsName> <ValTableName|ValTableDefinition>;`
62+
63+
## VAL_TABLE_
64+
Value table definition for signals.
65+
Format: `VAL_TABLE_ <ValueTableName> <ValueTableDefinition>;`
66+
ValueTableDefinition: List of `IntValue "StringValue"` Pairs, seperated by whitespaces
67+
68+
# Attributes
69+
In this sections are standard attributes used by [CANpy](https://github.com/stefanhoelzl/CANpy) defined. The attributes can be overwritten within a DBC file.
70+
## Message Attributes
71+
72+
### GenMsgSendType
73+
Defines the send type of a message.
74+
Supported types:
75+
* cyclic
76+
* triggered
77+
* cyclicIfActive
78+
* cyclicAndTriggered
79+
* cyclicIfActiveAndTriggered
80+
* none
81+
Definition: `BA_DEF BO_ "GenMsgSendType" ENUM "cyclic","triggered","cyclicIfActive","cyclicAndTriggered","cyclicIfActiveAndTriggered","none"`
82+
Default: none
83+
Definition: `BA_DEF_DEF "GenMsgSendType" "none"`
84+
85+
### GenMsgCycleTime
86+
Defines the cycle time of a message in ms.
87+
Definition: `BA_DEF BO_ "GenMsgCycleTime" INT 0 0`
88+
Default: 0
89+
Definition: `BA_DEF_DEF "GenMsgCycleTime" 0`
90+
91+
### GenMsgStartDelayTime
92+
Defines the allowed delay after startup this message must occure the first time in ms.
93+
Definition: `BA_DEF BO_ "GenMsgStartDelayTime" INT 0 0`
94+
Default: 0 (=GenMsgCycleTime)
95+
Definition: `BA_DEF_DEF "GenMsgStartDelayTime" 0`
96+
97+
### GenMsgDelayTime
98+
Defines the allowed delay for a message in ms.
99+
Definition: `BA_DEF BO_ "GenMsgDelayTime" INT 0 0`
100+
Default: 0
101+
Definition: `BA_DEF_DEF "GenMsgDelayTime" 0`
102+
103+
## Signal Attributes
104+
### GenSigStartValue
105+
Defines the value as long as no value is set/received for this signal.
106+
Definition: `BA_DEF SG_ "GenSigStartValue" INT 0 0`
107+
Default: 0
108+
Definition: `BA_DEF_DEF "GenSigStartValue" 0`
109+
110+
# Sources
111+
http://pisnoop.s3.amazonaws.com/snoop_help_dbc.htm
112+
http://www.racelogic.co.uk/_downloads/vbox/Application_Notes/CAN%20Format%20for%20VBOXII%20and%20PRO%20v4.pdf
113+
https://hackage.haskell.org/package/ecu-0.0.8/src/src/j1939_utf8.dbc
114+
http://www.ingenieurbuerobecker.de/downloads/CANtool_Manual.pdf

ArrowPoint-CANbus-Tools/Canbus/CanOverEthernet.cs

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@ public class CanOverEthernet : ICanTrafficInterface
2525
private const int DEFAULT_PORT = 4876;
2626

2727
private Thread UdpReceiverThread;
28-
private UdpClient udpConnection;
28+
private UdpClient udpReceiverConnection;
29+
private UdpClient udpSenderConnection;
2930
private Boolean isConnected;
30-
private IPAddress ipAddress;
31-
private IPEndPoint ipEndPoint;
31+
private IPAddress ipAddressMulticast;
32+
private IPEndPoint ipEndPointMulticast;
33+
private IPEndPoint localEndPoint;
3234

3335
public string Ip;
3436
public int Port;
@@ -61,16 +63,30 @@ internal void Close()
6163
public Boolean Connect()
6264
{
6365

64-
// Sender
65-
ipAddress = IPAddress.Parse(this.Ip);
66-
ipEndPoint = new IPEndPoint(this.ipAddress, this.Port);
66+
// Both the sender the receiver
67+
ipAddressMulticast = IPAddress.Parse(this.Ip);
68+
ipEndPointMulticast = new IPEndPoint(this.ipAddressMulticast, this.Port);
69+
localEndPoint = new IPEndPoint(IPAddress.Any, this.Port);
6770

68-
// Receiver
71+
// Setup sender and receiver
6972
try
7073
{
71-
this.udpConnection = new UdpClient(this.Port);
72-
this.udpConnection.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
73-
this.udpConnection.JoinMulticastGroup(ipAddress, 50);
74+
udpSenderConnection = new UdpClient()
75+
{
76+
ExclusiveAddressUse = false
77+
};
78+
udpSenderConnection.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
79+
udpSenderConnection.Client.Bind(localEndPoint);
80+
udpSenderConnection.JoinMulticastGroup(ipAddressMulticast);
81+
udpSenderConnection.Client.MulticastLoopback = true;
82+
83+
this.udpReceiverConnection = new UdpClient()
84+
{
85+
ExclusiveAddressUse = false
86+
};
87+
udpReceiverConnection.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
88+
udpReceiverConnection.Client.Bind(localEndPoint);
89+
udpReceiverConnection.JoinMulticastGroup(ipAddressMulticast, 50);
7490
}
7591
catch
7692
{
@@ -88,7 +104,8 @@ public Boolean Disconnect()
88104
{
89105
if (!isConnected) return false;
90106

91-
udpConnection.Close();
107+
udpReceiverConnection.Close();
108+
udpSenderConnection.Close();
92109
StopReceiver();
93110

94111
isConnected = false;
@@ -101,7 +118,7 @@ public int SendMessage(CanPacket canPacket)
101118
if (!isConnected) return -1;
102119

103120
var data = canPacket.RawBytes;
104-
return udpConnection.Send(data, data.Length, ipEndPoint);
121+
return udpSenderConnection.Send(data, data.Length, ipEndPointMulticast);
105122
}
106123

107124
public Boolean IsConnected()
@@ -137,15 +154,15 @@ private void UdpReceiverLoop()
137154
try
138155
{
139156
var ipEndPoint = new IPEndPoint(IPAddress.Any, this.Port);
140-
byte[] data = udpConnection.Receive(ref ipEndPoint);
157+
byte[] data = udpReceiverConnection.Receive(ref ipEndPoint);
141158
IPAddress sourceAddress = ipEndPoint.Address;
142159
int port = ipEndPoint.Port;
143160

144161
if (CheckIfTritiumDatagram(data)) {
145162
SplitCanPackets(data, sourceAddress, port);
146163
}
147164
}
148-
catch {
165+
catch (Exception ex) {
149166
Disconnect();
150167
}
151168
}
@@ -155,7 +172,8 @@ private bool CheckIfTritiumDatagram(byte[] data) {
155172
string dataString = MyExtensions.ByteArrayToText(data);
156173

157174
// Some tritium Can Bridges uses Tritiub rather that Tritium
158-
return dataString.Contains("Tritiu");
175+
// The latest release seems to just use Tri
176+
return dataString.Contains("Tri");
159177
}
160178

161179
private void SplitCanPackets(byte[] data, IPAddress sourceIPAddress, int sourcePort) {

ArrowPoint-CANbus-Tools/Canbus/CanPacket.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace ArrowPointCANBusTool.Canbus
1010
{
1111
public class CanPacket
1212
{
13-
private string SamplePacket { get; set; } = "005472697469756d006508a8c0007f5d0000040400080000000000000000";
13+
private string SamplePacket { get; set; } = "00547269fdd6000d006508a8c0007f5d0000040400080000000000000000";
1414

1515
public Boolean IsLittleEndian { get; set; } = true;
1616
public int PacketIndex { get; set; } = 0;
@@ -163,7 +163,8 @@ public uint CanIdBase10 {
163163
{
164164
try
165165
{
166-
return uint.Parse(CanIdAsHex.TrimStart('0', 'x'), System.Globalization.NumberStyles.HexNumber);
166+
string trimmedValue = MyExtensions.Trim0x(CanIdAsHex);
167+
return uint.Parse(trimmedValue, System.Globalization.NumberStyles.HexNumber);
167168
}
168169
catch
169170
{

ArrowPoint-CANbus-Tools/Canbus/MyExtensions.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ public static String AlignLeft(String value, int stringPadSize, Boolean commaSpa
2727
return textString.Substring(0, stringPadSize);
2828
}
2929

30+
public static String Trim0x(String value)
31+
{
32+
if (value.Trim().Substring(0, 2).Equals("0x"))
33+
return value.Trim().Substring(2);
34+
return value;
35+
}
36+
3037
public static byte[] StringToByteArray(string hex)
3138
{
3239
int NumberChars = hex.Length;

ArrowPoint-CANbus-Tools/Forms/NetworkMessageForm.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System;
1+
using ArrowPointCANBusTool.Canbus;
2+
using System;
23
using System.Collections.Generic;
34
using System.ComponentModel;
45
using System.Data;
@@ -21,7 +22,7 @@ public Configuration.Message Message
2122
{
2223
if (message == null) message = new Configuration.Message();
2324
message.name = MessageNameTextBox.Text;
24-
message.id = "0x" + CanIdTextBox.Text.TrimStart('0','x');
25+
message.id = "0x" + MyExtensions.Trim0x(CanIdTextBox.Text);
2526
return message;
2627
}
2728
}

ArrowPoint-CANbus-Tools/Forms/SendPacketForm.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public partial class SendPacketForm : Form
1919
private Timer timer;
2020
private Boolean looping;
2121

22-
private string samplePacket = "005472697469756d006508a8c0007f5d0000040400080000000000000000";
22+
private string samplePacket = "00547269fdd6000d006508a8c0007f5d0000040400080000000000000000";
2323

2424
public SendPacketForm()
2525
{
@@ -127,8 +127,8 @@ private void TbId_Leave(object sender, EventArgs e)
127127
MessageBox.Show("ID is not hex");
128128
}
129129

130-
this.canPacket.CanIdBase10 = uint.Parse(this.tbId.Text, System.Globalization.NumberStyles.HexNumber);
131-
UpdateInputFields();
130+
this.canPacket.CanIdBase10 = uint.Parse(MyExtensions.Trim0x(this.tbId.Text), System.Globalization.NumberStyles.HexNumber);
131+
UpdateInputFields();
132132
}
133133

134134
private void TbIdBase10_Leave(object sender, EventArgs e)
@@ -233,7 +233,7 @@ private void TimerTick(object sender, EventArgs e)
233233

234234
private Boolean IsHexString(String text)
235235
{
236-
return System.Text.RegularExpressions.Regex.IsMatch(text, @"\A\b[0-9a-fA-F]+\b\Z");
236+
return System.Text.RegularExpressions.Regex.IsMatch(MyExtensions.Trim0x(text), @"\A\b[0-9a-fA-F]+\b\Z");
237237
}
238238

239239
private bool UpdateByte(int index, string byteString)

ArrowPoint-CANbus-Tools/Services/ConfigService.cs

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,67 @@ public void SaveConfig(string filename)
5858
}
5959

6060

61+
public void LoadDBCFile(string filename)
62+
{
63+
string[] lines = System.IO.File.ReadAllLines(filename);
64+
65+
const int VERSION = 0;
66+
const int BS = 1;
67+
const int BU = 2;
68+
const int BO = 3;
69+
const int SG = 4;
70+
const int CM = 5;
71+
const int BA_DEF = 6;
72+
const int BA_DEF_DEF = 7;
73+
const int BA = 8;
74+
const int VAL = 9;
75+
const int VAL_TABLE = 10;
76+
77+
int parseState = -1;
78+
79+
Configuration = new NetworkDefinition();
80+
81+
foreach (string line in lines)
82+
{
83+
84+
int marker = line.IndexOf(' ');
85+
if (marker < 3) marker = 3;
86+
string checktag = line.Trim().Substring(0, marker);
87+
88+
switch (checktag)
89+
{
90+
case "VERSION": parseState = VERSION; break;
91+
case "BS_": parseState = BS; break;
92+
case "BU_": parseState = BU; break;
93+
case "BO_": parseState = BO; break;
94+
case "SG_": parseState = SG; break;
95+
case "CM_": parseState = CM; break;
96+
case "BA_DEF_": parseState = BA_DEF; break;
97+
case "BA_DEF_DEF_": parseState = BA_DEF_DEF; break;
98+
case "BA_": parseState = BA; break;
99+
case "VAL_": parseState = VAL; break;
100+
case "VAL_TABLE_": parseState = VAL_TABLE; break;
101+
}
102+
103+
switch (parseState)
104+
{
105+
case VERSION: Configuration.Document.version = line.Substring(9); break;
106+
case BS: Configuration.Bus[0].baudrate = line.Substring(4); break;
107+
case BU: break;
108+
case BO: break;
109+
case SG: break;
110+
case CM: break;
111+
case BA_DEF: break;
112+
case BA_DEF_DEF: break;
113+
case BA: break;
114+
case VAL: break;
115+
case VAL_TABLE: break;
116+
}
117+
}
118+
}
119+
120+
121+
61122
public List<CanPacket> UnknownCanIds(Bus bus)
62123
{
63124
List<CanPacket> unknownPackets = null;
@@ -148,7 +209,7 @@ public Configuration.Message AddMessage(string messageName, string canId, Config
148209
Configuration.Message message = new Configuration.Message
149210
{
150211
name = messageName,
151-
id = "0x" + canId.TrimStart('0','x')
212+
id = "0x" + MyExtensions.Trim0x(canId)
152213
};
153214

154215
NodeRef nodeRef = new NodeRef

0 commit comments

Comments
 (0)