Skip to content

Commit 87ca6b9

Browse files
committed
Merge pull request pyocd#207 from c1728p9/pydaplink_preparation
Refactor pyOCD in preperation for pyDAPAccess
2 parents 0524caa + 39d055a commit 87ca6b9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1466
-942
lines changed

README.rst

-11
Original file line numberDiff line numberDiff line change
@@ -222,17 +222,6 @@ gdb server:
222222

223223
Architecture
224224
------------
225-
226-
Interface
227-
~~~~~~~~~
228-
229-
An interface does the link between the target and the computer.
230-
This module contains basic functionalities to write and read data to and from
231-
an interface. You can inherit from ``Interface`` and overwrite
232-
``read()``, ``write()``, etc
233-
234-
Then declare your interface in ``INTERFACE`` (in ``pyOCD.interface.__init__.py``)
235-
236225
Target
237226
~~~~~~
238227

pyOCD/__init__.py

-2
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@
1818
import board
1919
import flash
2020
import gdbserver
21-
import interface
2221
import target
23-
import transport
2422
import utility
2523

2624
from ._version import version as __version__

pyOCD/board/board.py

+12-35
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,18 @@
1616
"""
1717

1818
from pyOCD.target import TARGET
19-
from pyOCD.transport import TRANSPORT
20-
from pyOCD.interface import INTERFACE
2119
from pyOCD.flash import FLASH
2220

2321
import logging
2422
import traceback
2523

2624
class Board(object):
2725
"""
28-
This class associates a target, a flash, a transport and an interface
29-
to create a board
26+
This class associates a target, a flash and a link to create a board
3027
"""
31-
def __init__(self, target, flash, interface, transport="cmsis_dap", frequency=1000000):
32-
self.interface = interface
33-
self.transport = TRANSPORT[transport](self.interface)
34-
self.target = TARGET[target](self.transport)
28+
def __init__(self, target, flash, link, frequency=1000000):
29+
self.link = link
30+
self.target = TARGET[target](self.link)
3531
self.flash = FLASH[flash](self.target)
3632
self.target.setFlash(self.flash)
3733
self.debug_clock_frequency = frequency
@@ -47,22 +43,15 @@ def __exit__(self, type, value, traceback):
4743

4844
def init(self):
4945
"""
50-
Initialize the board: interface, transport and target
46+
Initialize the board
5147
"""
5248
logging.debug("init board %s", self)
53-
self.interface.init()
54-
packet_count = self.getPacketCount()
55-
logging.info("board allows %i concurrent packets", packet_count)
56-
if packet_count < 1:
57-
logging.error('packet count of %i outside of expected range', packet_count)
58-
packet_count = 1
59-
self.interface.setPacketCount(packet_count)
60-
self.transport.init(self.debug_clock_frequency)
49+
self.link.set_clock(self.debug_clock_frequency)
6150
self.target.init()
6251

6352
def uninit(self, resume=True):
6453
"""
65-
Uninitialize the board: interface, transport and target.
54+
Uninitialize the board: link and target.
6655
This function resumes the target
6756
"""
6857
if self.closed:
@@ -77,27 +66,15 @@ def uninit(self, resume=True):
7766
logging.error("target exception during uninit:")
7867
traceback.print_exc()
7968
try:
80-
self.transport.uninit()
69+
self.link.disconnect()
8170
except:
82-
logging.error("transport exception during uninit:")
71+
logging.error("link exception during disconnect:")
8372
traceback.print_exc()
8473
try:
85-
self.interface.close()
74+
self.link.close()
8675
except:
87-
logging.error("interface exception during uninit:")
76+
logging.error("link exception during uninit:")
8877
traceback.print_exc()
8978

9079
def getInfo(self):
91-
# If the product name starts with the vendor name, we don't want to duplicate
92-
# the vendor name, so just return the product name. Otherwise combined the two.
93-
if self.interface.product_name.startswith(self.interface.vendor_name):
94-
info = self.interface.product_name
95-
else:
96-
info = self.interface.vendor_name + " " + self.interface.product_name
97-
return info
98-
99-
def getPacketCount(self):
100-
"""
101-
Return the number of commands the remote device's buffer can hold.
102-
"""
103-
return 1
80+
return ""

pyOCD/board/mbed_board.py

+39-72
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
from time import sleep
2222
from board import Board
23-
from pyOCD.interface import INTERFACE, usb_backend
23+
from pyOCD.pyDAPAccess import DAPAccess
2424

2525
class BoardInfo(object):
2626
def __init__(self, name, target, binary):
@@ -65,13 +65,15 @@ class MbedBoard(Board):
6565
Particularly, this class allows you to dynamically determine
6666
the type of all boards connected based on the id board
6767
"""
68-
def __init__(self, interface, board_id, unique_id, target=None, transport="cmsis_dap", frequency=1000000):
68+
def __init__(self, link, target=None, frequency=1000000):
6969
"""
7070
Init the board
7171
"""
72-
self.name = None
72+
self.name = ""
7373
self.native_target = None
7474
self.test_binary = None
75+
unique_id = link.get_unique_id()
76+
board_id = unique_id[0:4]
7577
if board_id in BOARD_ID_TO_INFO:
7678
board_info = BOARD_ID_TO_INFO[board_id]
7779
self.name = board_info.name
@@ -85,7 +87,7 @@ def __init__(self, interface, board_id, unique_id, target=None, transport="cmsis
8587
if target is None:
8688
raise Exception("Unknown board target")
8789

88-
super(MbedBoard, self).__init__(target, target, interface, transport, frequency)
90+
super(MbedBoard, self).__init__(target, target, link, frequency)
8991
self.unique_id = unique_id
9092
self.target_type = target
9193

@@ -117,14 +119,15 @@ def getInfo(self):
117119
"""
118120
Return info on the board
119121
"""
120-
return Board.getInfo(self) + " [" + self.target_type + "]"
122+
return self.name + " [" + self.target_type + "]"
121123

122124
@staticmethod
123-
def listConnectedBoards(transport="cmsis_dap"):
125+
def listConnectedBoards(dap_class=DAPAccess):
124126
"""
125127
List the connected board info
126128
"""
127-
all_mbeds = MbedBoard.getAllConnectedBoards(close=True, blocking=False)
129+
all_mbeds = MbedBoard.getAllConnectedBoards(dap_class, close=True,
130+
blocking=False)
128131
index = 0
129132
if len(all_mbeds) > 0:
130133
for mbed in all_mbeds:
@@ -134,74 +137,44 @@ def listConnectedBoards(transport="cmsis_dap"):
134137
print("No available boards are connected")
135138

136139
@staticmethod
137-
def getAllConnectedBoards(transport="cmsis_dap", close=False, blocking=True,
138-
target_override=None, frequency=1000000):
140+
def getAllConnectedBoards(dap_class=DAPAccess, close=False, blocking=True,
141+
target_override=None, frequency=1000000):
139142
"""
140143
Return an array of all mbed boards connected
141144
"""
142-
first = True
143-
while True:
144-
while True:
145-
if not first:
146-
# Don't eat up all the cpu if an unsupported board is connected.
147-
# Sleep before getting connected interfaces. This way if a keyboard
148-
# exception comes in there will be no resources to close
149-
sleep(0.2)
150-
151-
all_mbeds = INTERFACE[usb_backend].getAllConnectedInterface(mbed_vid, mbed_pid)
152-
if all_mbeds == None:
153-
all_mbeds = []
154-
155-
if not blocking:
156-
# No blocking so break from loop
157-
break
158-
159-
if len(all_mbeds) > 0:
160-
# A board has been found so break from loop
161-
break
162145

163-
if (first == True):
164-
logging.info("Waiting for a USB device connected")
165-
first = False
146+
mbed_list = []
147+
while True:
166148

167-
mbed_boards = []
168-
for mbed in all_mbeds:
169-
try:
170-
mbed.write([0x80])
171-
u_id_ = mbed.read()
172-
board_id = array.array('B', [i for i in u_id_[2:6]]).tostring()
173-
unique_id = array.array('B', [i for i in u_id_[2:2 + u_id_[1]]]).tostring()
174-
if board_id not in BOARD_ID_TO_INFO:
175-
logging.info("Unsupported board found: %s" % board_id)
176-
if target_override is None:
177-
# TODO - if no board can be determined treat this as a generic cortex-m device
178-
logging.info("Target could not be determined. Specify target manually to use board")
179-
mbed.close()
180-
continue
149+
connected_daps = dap_class.get_connected_devices()
150+
for dap_access in connected_daps:
151+
new_mbed = MbedBoard(dap_access, target_override, frequency)
152+
mbed_list.append(new_mbed)
181153

182-
new_mbed = MbedBoard(mbed, board_id, unique_id, target_override, transport, frequency)
183-
logging.info("new board id detected: %s", unique_id)
184-
mbed_boards.append(new_mbed)
185-
if close:
186-
mbed.close()
187-
except:
188-
#TODO - close all boards when an exception occurs
189-
mbed.close()
190-
raise
154+
#TODO - handle exception on open
155+
if not close:
156+
for dap_access in connected_daps:
157+
dap_access.open()
191158

192-
if len(mbed_boards) > 0 or not blocking:
193-
return mbed_boards
159+
if not blocking:
160+
break
161+
elif len(mbed_list) > 0:
162+
break
163+
else:
164+
sleep(0.01)
165+
assert len(mbed_list) == 0
194166

195-
if (first == True):
196-
logging.info("Waiting for a USB device connected")
197-
first = False
167+
return mbed_list
198168

199169
@staticmethod
200-
def chooseBoard(transport="cmsis_dap", blocking=True, return_first=False, board_id=None, target_override=None, frequency=1000000, init_board=True):
170+
def chooseBoard(dap_class=DAPAccess, blocking=True, return_first=False,
171+
board_id=None, target_override=None, frequency=1000000,
172+
init_board=True):
201173
"""
202174
Allow you to select a board among all boards connected
203175
"""
204-
all_mbeds = MbedBoard.getAllConnectedBoards(transport, False, blocking, target_override, frequency)
176+
all_mbeds = MbedBoard.getAllConnectedBoards(dap_class, False, blocking,
177+
target_override, frequency)
205178

206179
# If a board ID is specified close all other boards
207180
if board_id != None:
@@ -210,7 +183,7 @@ def chooseBoard(transport="cmsis_dap", blocking=True, return_first=False, board_
210183
if mbed.unique_id == (board_id):
211184
new_mbed_list.append(mbed)
212185
else:
213-
mbed.interface.close()
186+
mbed.link.close()
214187
assert len(new_mbed_list) <= 1
215188
all_mbeds = new_mbed_list
216189

@@ -225,7 +198,7 @@ def chooseBoard(transport="cmsis_dap", blocking=True, return_first=False, board_
225198
# Select first board and close others if True
226199
if return_first:
227200
for i in range(1, len(all_mbeds)):
228-
all_mbeds[i].interface.close()
201+
all_mbeds[i].link.close()
229202
all_mbeds = all_mbeds[0:1]
230203

231204
# Ask use to select boards if there is more than 1 left
@@ -255,7 +228,7 @@ def chooseBoard(transport="cmsis_dap", blocking=True, return_first=False, board_
255228
# close all others mbed connected
256229
for mbed in all_mbeds:
257230
if mbed != all_mbeds[ch]:
258-
mbed.interface.close()
231+
mbed.link.close()
259232
all_mbeds = all_mbeds[ch:ch + 1]
260233

261234
assert len(all_mbeds) == 1
@@ -264,12 +237,6 @@ def chooseBoard(transport="cmsis_dap", blocking=True, return_first=False, board_
264237
try:
265238
mbed.init()
266239
except:
267-
mbed.interface.close()
240+
mbed.link.close()
268241
raise
269242
return mbed
270-
271-
def getPacketCount(self):
272-
"""
273-
Return the number of commands the remote device's buffer can hold.
274-
"""
275-
return self.transport.info('PACKET_COUNT')

pyOCD/gdbserver/gdbserver.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"""
1717

1818
from ..target.target import Target
19-
from ..transport.transport import Transport
19+
from pyOCD.pyDAPAccess import DAPAccess
2020
from ..utility.conversion import hexToByteList, hexEncode, hexDecode
2121
from gdb_socket import GDBSocket
2222
from gdb_websocket import GDBWebSocket
@@ -789,7 +789,7 @@ def getMemory(self, data):
789789
val += hex(x)[2:4]
790790
else:
791791
val += '0' + hex(x)[2:3]
792-
except Transport.TransferError:
792+
except DAPAccess.TransferError:
793793
logging.debug("getMemory failed at 0x%x" % addr)
794794
val = 'E01' #EPERM
795795
return self.createRSPPacket(val)
@@ -813,7 +813,7 @@ def writeMemoryHex(self, data):
813813
# Flush so an exception is thrown now if invalid memory was accessed
814814
self.target.flush()
815815
resp = "OK"
816-
except Transport.TransferError:
816+
except DAPAccess.TransferError:
817817
logging.debug("writeMemory failed at 0x%x" % addr)
818818
resp = 'E01' #EPERM
819819

@@ -843,7 +843,7 @@ def writeMemory(self, data):
843843
# Flush so an exception is thrown now if invalid memory was accessed
844844
self.target.flush()
845845
resp = "OK"
846-
except Transport.TransferError:
846+
except DAPAccess.TransferError:
847847
logging.debug("writeMemory failed at 0x%x" % addr)
848848
resp = 'E01' #EPERM
849849

pyOCD/transport/__init__.py pyOCD/pyDAPAccess/__init__.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
See the License for the specific language governing permissions and
1515
limitations under the License.
1616
"""
17+
from .dap_access_api import DAPAccessIntf
18+
from .dap_access_usb import DAPAccessUSB
1719

18-
from cmsis_dap import CMSIS_DAP
19-
20-
TRANSPORT = {'cmsis_dap': CMSIS_DAP
21-
}
20+
# alias DAPAccessUSB as main DAPAccess class
21+
DAPAccess = DAPAccessUSB

0 commit comments

Comments
 (0)