Skip to content

Commit c8d2e31

Browse files
committed
fix NMT states for SDO server
1 parent 6ef349c commit c8d2e31

File tree

3 files changed

+43
-11
lines changed

3 files changed

+43
-11
lines changed

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
# 0.4.4
2+
3+
* fix SDO server startup when entering OPERATIONAL directly
4+
5+
## 0.4.3
6+
7+
* fix eds generation
8+
9+
## 0.4.2
10+
11+
* fix size in PDO mapping (it's bits not bytes)
12+
13+
## 0.4.1
14+
15+
* fix eds format datatype
16+
117
## 0.4.0
218

319
* rename "adapter" to "network"

src/durand/object_dictionary.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ def lookup(self, index: int, subindex: int = None) -> TObject:
189189
return obj[subindex]
190190

191191
def write(self, index: int, subindex: int, value: Any, downloaded: bool = False):
192-
""" Write the given value to the according variable.
192+
"""Write the given value to the according variable.
193193
WARNING: The datatype and range has to be checked before calling this function!
194194
195195
:param index: object index
@@ -198,7 +198,9 @@ def write(self, index: int, subindex: int, value: Any, downloaded: bool = False)
198198
:param downloaded: flag is set, when the write is caused by an actual download
199199
(instead of a internal value change)
200200
"""
201-
assert isinstance(value, (bytes, bool, int, float)), 'Only bytes, bool, int or float are allowed in object dictionary'
201+
assert isinstance(
202+
value, (bytes, bool, int, float)
203+
), "Only bytes, bool, int or float are allowed in object dictionary"
202204

203205
if index in self._variables:
204206
multiplexor = (index, 0)

src/durand/services/sdo/server.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import struct
22
from enum import Enum
3-
from typing import TYPE_CHECKING, Tuple
3+
from typing import TYPE_CHECKING
44
import logging
55

66
from durand.datatypes import DatatypeEnum as DT
@@ -32,6 +32,7 @@ class SDOServer:
3232
def __init__(self, node: "Node", index=0):
3333
self._node = node
3434
self._index = index
35+
self._stopped = True
3536

3637
from .download import DownloadManager
3738
from .upload import UploadManager
@@ -84,28 +85,41 @@ def __init__(self, node: "Node", index=0):
8485
2: self.upload_manager.init_upload,
8586
3: self.upload_manager.upload_segment,
8687
5: self.upload_manager.init_upload,
87-
6: self._handle_download_block
88+
6: self._handle_download_block,
8889
}
8990

9091
@property
9192
def node(self):
9293
return self._node
9394

9495
def _update_subscription(self, state: StateEnum):
95-
if state == StateEnum.STOPPED:
96+
if not self._stopped and state == StateEnum.STOPPED:
9697
self._node.network.remove_subscription(self._cob_rx)
97-
elif state == StateEnum.PRE_OPERATIONAL and not (
98-
self._cob_rx | self._cob_tx
99-
) & (1 << 31):
98+
self._stopped = True
99+
return
100+
101+
if (
102+
self._stopped
103+
and state in (StateEnum.PRE_OPERATIONAL, StateEnum.OPERATIONAL)
104+
and not (self._cob_rx | self._cob_tx) & (1 << 31)
105+
):
100106
self._node.network.add_subscription(self._cob_rx, self.handle_msg)
107+
self._stopped = False
101108

102109
def _update_node(self, state: StateEnum):
103-
if state == StateEnum.STOPPED:
110+
if not self._stopped and state == StateEnum.STOPPED:
104111
self._node.network.remove_subscription(self._cob_rx)
105-
elif state == StateEnum.PRE_OPERATIONAL:
112+
self._stopped = True
113+
return
114+
115+
if self._stopped and state in (
116+
StateEnum.PRE_OPERATIONAL,
117+
StateEnum.OPERATIONAL,
118+
):
106119
self._cob_rx = 0x600 + self._node.node_id
107120
self._cob_tx = 0x580 + self._node.node_id
108121
self._node.network.add_subscription(self._cob_rx, self.handle_msg)
122+
self._stopped = False
109123

110124
def _update_cob_rx(self, value: int):
111125
# bit 31: 0 - valid, 1 - invalid
@@ -182,7 +196,7 @@ def handle_msg(self, cob_id: int, msg: bytes) -> None:
182196
try:
183197
return self._handle_cs_dict[ccs](msg)
184198
except KeyError as exc: # ccs not found
185-
raise SDODomainAbort(0x05040001) from exc # SDO command not implemented
199+
raise SDODomainAbort(0x05040001) from exc # SDO command not implemented
186200
except SDODomainAbort as exc:
187201
index, subindex = 0, 0
188202
if exc.multiplexor:

0 commit comments

Comments
 (0)