You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by ld...@apache.org on 2020/10/21 08:43:09 UTC
[plc4x] 09/21: Sketch of support for SDO operations.
This is an automated email from the ASF dual-hosted git repository.
ldywicki pushed a commit to branch feature/socketcan
in repository https://gitbox.apache.org/repos/asf/plc4x.git
commit d5ff622042011eb3392a2a1eab34518f925f130b
Author: Ćukasz Dywicki <lu...@code-house.org>
AuthorDate: Sat Aug 29 10:09:57 2020 +0200
Sketch of support for SDO operations.
---
.../src/main/resources/protocols/can/canopen.mspec | 40 ++++++-
.../apache/plc4x/java/can/CANOpenPlcDriver.java | 17 +--
.../java/can/configuration/CANConfiguration.java | 12 +++
.../java/can/protocol/CANOpenProtocolLogic.java | 58 ++++++-----
.../test/java/org/apache/plc4x/java/can/Main.java | 2 +-
.../testsuite/CANOpenPayloadTestSuite.xml | 115 ++++++++++++++++++++-
6 files changed, 196 insertions(+), 48 deletions(-)
diff --git a/protocols/can/src/main/resources/protocols/can/canopen.mspec b/protocols/can/src/main/resources/protocols/can/canopen.mspec
index 54337b4..d5160c6 100644
--- a/protocols/can/src/main/resources/protocols/can/canopen.mspec
+++ b/protocols/can/src/main/resources/protocols/can/canopen.mspec
@@ -18,8 +18,10 @@
*/
[enum uint 4 'CANOpenService'
- ['0x00' BROADCAST]
- ['0x07' NMT]
+ ['0b0000' BROADCAST ]
+ ['0b1110' NMT ]
+ ['0b1100' SDO_REQUEST ]
+ ['0b1011' SDO_RESPONSE]
]
[enum uint 8 'NMTStateRequest'
@@ -41,11 +43,41 @@
[typeSwitch 'function'
['CANOpenService.BROADCAST' CANOpenBroadcastPayload
[enum NMTStateRequest 'request']
- [reserved uint 1 '0x0']
+ [reserved uint 1 '0x00']
[simple uint 7 'node']
]
['CANOpenService.NMT' CANOpenNetworkPayload
[enum NMTState 'state']
]
+ ['CANOpenService.SDO_REQUEST' CANOpenSDORequest
+ [enum SDOCommand 'command']
+ [reserved uint 1 '0x00']
+ [implicit uint 2 'size' 'COUNT(data)']
+ [simple bit 'expedited'] // segmented
+ [simple bit 'placement']
+ [simple uint 16 'index']
+ [simple uint 8 'subindex']
+ [array uint 8 'data' COUNT 'size']
+ ]
+ ['CANOpenService.SDO_RESPONSE' CANOpenSDOResponse
+ [enum SDOCommand 'command']
+ [reserved uint 1 '0x00']
+ [implicit uint 2 'size' 'COUNT(data)']
+ [simple bit 'expedited'] // segmented
+ [simple bit 'placement']
+ [simple uint 16 'index']
+ [simple uint 8 'subindex']
+ [array uint 8 'data' COUNT 'size']
+ ]
]
-]
\ No newline at end of file
+]
+
+[enum uint 3 'SDOCommand'
+ ['0x00' SEGMENT_DOWNLOAD]
+ ['0x01' INITIALIZE_DOWNLOAD]
+ ['0x02' INITIALIZE_UPLOAD]
+ ['0x03' SEGMENT_UPLOAD]
+ ['0x04' ABORT]
+ ['0x05' BLOCK_UPLOAD]
+ ['0x06' BLOCK_DOWNLOAD]
+]
diff --git a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/CANOpenPlcDriver.java b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/CANOpenPlcDriver.java
index 4255ff2..6acff67 100644
--- a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/CANOpenPlcDriver.java
+++ b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/CANOpenPlcDriver.java
@@ -78,25 +78,10 @@ public class CANOpenPlcDriver extends GeneratedDriverBase<SocketCANFrame> {
@Override
public int applyAsInt(ByteBuf byteBuf) {
if (byteBuf.readableBytes() >= 5) {
-
- System.out.println(ByteBufUtil.prettyHexDump(byteBuf));
- byte len = byteBuf.getByte(4);
- System.out.println("Length " + (int) len);
-
- CanFrame frame = CanFrame.create(byteBuf.nioBuffer());
- System.out.println(frame);
-
- return len + 8 /* overhead */;
+ return 16; // socketcan transport always returns 16 bytes padded with zeros;
}
return -1; //discard
}
}
- public class CANCleaner implements Consumer<ByteBuf> {
- @Override
- public void accept(ByteBuf byteBuf) {
- System.out.println("Discard");
- byteBuf.readByte();
- }
- }
}
diff --git a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/configuration/CANConfiguration.java b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/configuration/CANConfiguration.java
index 925ca15..214794d 100644
--- a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/configuration/CANConfiguration.java
+++ b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/configuration/CANConfiguration.java
@@ -27,6 +27,9 @@ public class CANConfiguration implements Configuration, CANTransportConfiguratio
@ConfigurationParameter
private int nodeId;
+ @ConfigurationParameter
+ private boolean hearbeat;
+
public int getNodeId() {
return nodeId;
}
@@ -34,4 +37,13 @@ public class CANConfiguration implements Configuration, CANTransportConfiguratio
public void setNodeId(int nodeId) {
this.nodeId = nodeId;
}
+
+ public boolean isHeartbeat() {
+ return hearbeat;
+ }
+
+ public void setHearbeat(boolean hearbeat) {
+ this.hearbeat = hearbeat;
+ }
+
}
diff --git a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/protocol/CANOpenProtocolLogic.java b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/protocol/CANOpenProtocolLogic.java
index 555ef92..9cc2fdb 100644
--- a/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/protocol/CANOpenProtocolLogic.java
+++ b/sandbox/test-java-can-driver/src/main/java/org/apache/plc4x/java/can/protocol/CANOpenProtocolLogic.java
@@ -45,6 +45,7 @@ public class CANOpenProtocolLogic extends Plc4xProtocolBase<SocketCANFrame> impl
private CANConfiguration configuration;
private RequestTransactionManager tm;
+ private Timer heartbeat;
@Override
public void setConfiguration(CANConfiguration configuration) {
@@ -55,39 +56,46 @@ public class CANOpenProtocolLogic extends Plc4xProtocolBase<SocketCANFrame> impl
@Override
public void onConnect(ConversationContext<SocketCANFrame> context) {
- CANOpenNetworkPayload state = new CANOpenNetworkPayload(NMTState.BOOTED_UP);
- WriteBuffer buffer = new WriteBuffer(1);
try {
- CANOpenNetworkPayloadIO.staticSerialize(buffer, state);
- context.sendToWire(new SocketCANFrame(cobId(CANOpenService.NMT), buffer.getData()));
- context.fireConnected();
-
- Timer heartbeat = new Timer();
- heartbeat.scheduleAtFixedRate(new TimerTask() {
- @Override
- public void run() {
- CANOpenNetworkPayload state = new CANOpenNetworkPayload(NMTState.OPERATIONAL);
- WriteBuffer buffer = new WriteBuffer(1);
- context.sendToWire(new SocketCANFrame(cobId(CANOpenService.NMT), buffer.getData()));
- }
- }, 5000, 5000);
+ if (configuration.isHeartbeat()) {
+ context.sendToWire(createFrame(new CANOpenNetworkPayload(NMTState.BOOTED_UP)));
+ context.fireConnected();
+
+ this.heartbeat = new Timer();
+ this.heartbeat.scheduleAtFixedRate(new TimerTask() {
+ @Override
+ public void run() {
+ try {
+ context.sendToWire(createFrame(new CANOpenNetworkPayload(NMTState.OPERATIONAL)));
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ }
+ }, 5000, 5000);
+ }
} catch (ParseException e) {
e.printStackTrace();
}
}
+ private SocketCANFrame createFrame(CANOpenNetworkPayload state) throws ParseException {
+ WriteBuffer buffer = new WriteBuffer(state.getLengthInBytes());
+ CANOpenNetworkPayloadIO.staticSerialize(buffer, state);
+ return new SocketCANFrame(cobId(CANOpenService.NMT), buffer.getData());
+ }
+
@Override
protected void decode(ConversationContext<SocketCANFrame> context, SocketCANFrame msg) throws Exception {
logger.info("Decode CAN message {}", msg);
- int identifier = msg.getIdentifier();
- CANOpenService service = CANOpenService.valueOf((byte) (identifier >> 7));
- if (service != null) {
- ReadBuffer buffer = new ReadBuffer(msg.getData());
- CANOpenPayload payload = CANOpenPayloadIO.staticParse(buffer, service);
-
-
- }
+// int identifier = msg.getIdentifier();
+// CANOpenService service = CANOpenService.valueOf((byte) (identifier >> 7));
+// if (service != null) {
+// ReadBuffer buffer = new ReadBuffer(msg.getData());
+// CANOpenPayload payload = CANOpenPayloadIO.staticParse(buffer, service);
+//
+//
+// }
}
@Override
@@ -101,7 +109,9 @@ public class CANOpenProtocolLogic extends Plc4xProtocolBase<SocketCANFrame> impl
}
private int cobId(CANOpenService service) {
- return service.getValue() & configuration.getNodeId();
+ // form 32 bit socketcan identifier
+ return (configuration.getNodeId() << 24) & 0xff000000 |
+ (service.getValue() << 16 ) & 0x00ff0000;
}
}
diff --git a/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/Main.java b/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/Main.java
index e8279b6..8212bea 100644
--- a/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/Main.java
+++ b/sandbox/test-java-can-driver/src/test/java/org/apache/plc4x/java/can/Main.java
@@ -29,7 +29,7 @@ public class Main {
public static void main(String[] args) throws Exception {
PlcDriverManager driverManager = new PlcDriverManager();
- PlcConnection connection = driverManager.getConnection("canopen:javacan://vcan0?nodeId=15");
+ PlcConnection connection = driverManager.getConnection("canopen:javacan://vcan0?nodeId=11");
}
diff --git a/sandbox/test-java-can-driver/src/test/resources/testsuite/CANOpenPayloadTestSuite.xml b/sandbox/test-java-can-driver/src/test/resources/testsuite/CANOpenPayloadTestSuite.xml
index 773f608..d7c1a33 100644
--- a/sandbox/test-java-can-driver/src/test/resources/testsuite/CANOpenPayloadTestSuite.xml
+++ b/sandbox/test-java-can-driver/src/test/resources/testsuite/CANOpenPayloadTestSuite.xml
@@ -19,10 +19,10 @@
-->
<test:testsuite xmlns:test="https://plc4x.apache.org/schemas/parser-serializer-testsuite.xsd">
- <name>Tests of socketcan/CANopen frames.</name>
+ <name>Tests of CANopen frames payload.</name>
<testcase>
- <name>Network heartbeat payload: 00</name>
+ <name>Network heartbeat, payload: 00</name>
<raw>00</raw>
<root-type>CANOpenPayload</root-type>
<parser-arguments>
@@ -36,7 +36,7 @@
</testcase>
<testcase>
- <name>Network heartbeat payload: 7F</name>
+ <name>Network heartbeat, payload: 7F</name>
<raw>7F</raw>
<root-type>CANOpenPayload</root-type>
<parser-arguments>
@@ -49,4 +49,113 @@
</xml>
</testcase>
+ <testcase>
+ <name>SDO request, payload: 4317100000000000</name>
+ <raw>4317100000000000</raw>
+ <root-type>CANOpenPayload</root-type>
+ <parser-arguments>
+ <arg1>SDO_REQUEST</arg1>
+ </parser-arguments>
+ <xml>
+ <CANOpenSDORequest className="org.apache.plc4x.java.canopen.readwrite.CANOpenSDORequest">
+ <command>INITIALIZE_UPLOAD</command>
+ <expedited>true</expedited>
+ <placement>true</placement>
+ <index>4119</index>
+ <subindex>0</subindex>
+ <data/>
+ </CANOpenSDORequest>
+ </xml>
+ </testcase>
+
+ <testcase>
+ <name>SDO request, payload: 00171000A00F0000</name>
+ <raw>00171000A00F0000</raw>
+ <root-type>CANOpenPayload</root-type>
+ <parser-arguments>
+ <arg1>SDO_REQUEST</arg1>
+ </parser-arguments>
+ <xml>
+ <CANOpenSDORequest className="org.apache.plc4x.java.canopen.readwrite.CANOpenSDORequest">
+ <command>SEGMENT_DOWNLOAD</command>
+ <expedited>false</expedited>
+ <placement>false</placement>
+ <index>4119</index>
+ <subindex>0</subindex>
+ <data/>
+ </CANOpenSDORequest>
+ </xml>
+ </testcase>
+
+ <testcase>
+ <name>SDO write request, payload: 2B171000D00F</name>
+ <raw>2B171000D00F</raw>
+ <root-type>CANOpenPayload</root-type>
+ <parser-arguments>
+ <arg1>SDO_REQUEST</arg1>
+ </parser-arguments>
+ <xml>
+ <CANOpenSDORequest className="org.apache.plc4x.java.canopen.readwrite.CANOpenSDORequest">
+ <command>INITIALIZE_DOWNLOAD</command>
+ <expedited>true</expedited>
+ <placement>true</placement>
+ <index>4119</index>
+ <subindex>0</subindex>
+ <data>
+ <data>208</data>
+ <data>15</data>
+ </data>
+ </CANOpenSDORequest>
+ </xml>
+ </testcase>
+
+ <testcase>
+ <name>SDO write result, payload: 60171000D0F00000</name>
+ <raw>00171000A00F0000</raw>
+ <root-type>CANOpenPayload</root-type>
+ <parser-arguments>
+ <arg1>SDO_REQUEST</arg1>
+ </parser-arguments>
+ <xml>
+ <CANOpenSDORequest className="org.apache.plc4x.java.canopen.readwrite.CANOpenSDORequest">
+ <command>SEGMENT_DOWNLOAD</command>
+ <expedited>false</expedited>
+ <placement>false</placement>
+ <index>4119</index>
+ <subindex>0</subindex>
+ <data/>
+ </CANOpenSDORequest>
+ </xml>
+ </testcase>
+
+ <!-- samples -->
+ <testcase>
+ <name>SDO response, payload: 6000200000</name>
+ <raw>6000200000</raw>
+ <root-type>CANOpenPayload</root-type>
+ <parser-arguments>
+ <arg1>SDO_RESPONSE</arg1>
+ </parser-arguments>
+ <xml>
+ <CANOpenNetworkPayload className="org.apache.plc4x.java.canopen.readwrite.CANOpenNetworkPayload">
+ <state>PRE_OPERATIONAL</state>
+ </CANOpenNetworkPayload>
+ </xml>
+ </testcase>
+
+ <testcase>
+ <name>PDO, payload: 78563412</name>
+ <raw>78563412</raw>
+ <root-type>CANOpenPayload</root-type>
+ <parser-arguments>
+ <arg1>SDO_RESPONSE</arg1>
+ </parser-arguments>
+ <xml>
+ <CANOpenNetworkPayload className="org.apache.plc4x.java.canopen.readwrite.CANOpenNetworkPayload">
+ <state>PRE_OPERATIONAL</state>
+ </CANOpenNetworkPayload>
+ </xml>
+
+ </testcase>
+
</test:testsuite>
\ No newline at end of file