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/07 10:02:06 UTC

[plc4x] 11/19: 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 5196344464d048afe0edc1c6f6a858895a77f9b4
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