From 6b6bc938c51269a272e29cab256a15bc9ab0e34f Mon Sep 17 00:00:00 2001 From: Emilio Monti Date: Mon, 21 Oct 2013 16:59:08 +0100 Subject: [PATCH] pyOCD development moved to https://github.com/OpenHDK/pyOCD --- workspace_tools/debugger/README.md | 148 ----- workspace_tools/debugger/__init__.py | 16 - .../debugger/binaries/l1_kl25z.bin | Bin 1904 -> 0 bytes .../debugger/binaries/l1_lpc11u24.bin | Bin 3828 -> 0 bytes .../debugger/binaries/l1_lpc1768.bin | Bin 4132 -> 0 bytes .../debugger/binaries/l1_lpc800.bin | Bin 2592 -> 0 bytes .../elf_files/lpc11u24_l1_gcc_arm.elf | Bin 143556 -> 0 bytes .../debugger/elf_files/lpc1768_l1_gcc_arm.elf | Bin 154417 -> 0 bytes workspace_tools/debugger/pyOCD/__init__.py | 16 - .../debugger/pyOCD/board/__init__.py | 18 - workspace_tools/debugger/pyOCD/board/board.py | 60 -- .../debugger/pyOCD/board/mbed_board.py | 160 ----- .../debugger/pyOCD/flash/__init__.py | 27 - workspace_tools/debugger/pyOCD/flash/flash.py | 145 ----- .../debugger/pyOCD/flash/flash_kl25z.py | 92 --- .../debugger/pyOCD/flash/flash_lpc11u24.py | 57 -- .../debugger/pyOCD/flash/flash_lpc1768.py | 61 -- .../debugger/pyOCD/flash/flash_lpc800.py | 56 -- .../debugger/pyOCD/gdbserver/__init__.py | 18 - .../debugger/pyOCD/gdbserver/gdb_socket.py | 55 -- .../debugger/pyOCD/gdbserver/gdb_websocket.py | 51 -- .../debugger/pyOCD/gdbserver/gdbserver.py | 594 ------------------ .../debugger/pyOCD/interface/__init__.py | 23 - .../debugger/pyOCD/interface/interface.py | 45 -- .../debugger/pyOCD/interface/pyusb_backend.py | 138 ---- .../pyOCD/interface/pywinusb_backend.py | 116 ---- .../debugger/pyOCD/target/__init__.py | 29 - .../debugger/pyOCD/target/cortex_m.py | 554 ---------------- .../debugger/pyOCD/target/target.py | 82 --- .../debugger/pyOCD/target/target_kl25z.py | 57 -- .../debugger/pyOCD/target/target_lpc11u24.py | 24 - .../debugger/pyOCD/target/target_lpc1768.py | 40 -- .../debugger/pyOCD/target/target_lpc800.py | 24 - .../debugger/pyOCD/transport/__init__.py | 21 - .../debugger/pyOCD/transport/cmsis_dap.py | 229 ------- .../pyOCD/transport/cmsis_dap_core.py | 315 ---------- .../debugger/pyOCD/transport/transport.py | 64 -- workspace_tools/debugger/setup.py | 33 - workspace_tools/debugger/test/basic_test.py | 165 ----- workspace_tools/debugger/test/gdb_test.py | 36 -- 40 files changed, 3569 deletions(-) delete mode 100644 workspace_tools/debugger/README.md delete mode 100644 workspace_tools/debugger/__init__.py delete mode 100644 workspace_tools/debugger/binaries/l1_kl25z.bin delete mode 100644 workspace_tools/debugger/binaries/l1_lpc11u24.bin delete mode 100644 workspace_tools/debugger/binaries/l1_lpc1768.bin delete mode 100644 workspace_tools/debugger/binaries/l1_lpc800.bin delete mode 100644 workspace_tools/debugger/elf_files/lpc11u24_l1_gcc_arm.elf delete mode 100644 workspace_tools/debugger/elf_files/lpc1768_l1_gcc_arm.elf delete mode 100644 workspace_tools/debugger/pyOCD/__init__.py delete mode 100644 workspace_tools/debugger/pyOCD/board/__init__.py delete mode 100644 workspace_tools/debugger/pyOCD/board/board.py delete mode 100644 workspace_tools/debugger/pyOCD/board/mbed_board.py delete mode 100644 workspace_tools/debugger/pyOCD/flash/__init__.py delete mode 100644 workspace_tools/debugger/pyOCD/flash/flash.py delete mode 100644 workspace_tools/debugger/pyOCD/flash/flash_kl25z.py delete mode 100644 workspace_tools/debugger/pyOCD/flash/flash_lpc11u24.py delete mode 100644 workspace_tools/debugger/pyOCD/flash/flash_lpc1768.py delete mode 100644 workspace_tools/debugger/pyOCD/flash/flash_lpc800.py delete mode 100644 workspace_tools/debugger/pyOCD/gdbserver/__init__.py delete mode 100644 workspace_tools/debugger/pyOCD/gdbserver/gdb_socket.py delete mode 100644 workspace_tools/debugger/pyOCD/gdbserver/gdb_websocket.py delete mode 100644 workspace_tools/debugger/pyOCD/gdbserver/gdbserver.py delete mode 100644 workspace_tools/debugger/pyOCD/interface/__init__.py delete mode 100644 workspace_tools/debugger/pyOCD/interface/interface.py delete mode 100644 workspace_tools/debugger/pyOCD/interface/pyusb_backend.py delete mode 100644 workspace_tools/debugger/pyOCD/interface/pywinusb_backend.py delete mode 100644 workspace_tools/debugger/pyOCD/target/__init__.py delete mode 100644 workspace_tools/debugger/pyOCD/target/cortex_m.py delete mode 100644 workspace_tools/debugger/pyOCD/target/target.py delete mode 100644 workspace_tools/debugger/pyOCD/target/target_kl25z.py delete mode 100644 workspace_tools/debugger/pyOCD/target/target_lpc11u24.py delete mode 100644 workspace_tools/debugger/pyOCD/target/target_lpc1768.py delete mode 100644 workspace_tools/debugger/pyOCD/target/target_lpc800.py delete mode 100644 workspace_tools/debugger/pyOCD/transport/__init__.py delete mode 100644 workspace_tools/debugger/pyOCD/transport/cmsis_dap.py delete mode 100644 workspace_tools/debugger/pyOCD/transport/cmsis_dap_core.py delete mode 100644 workspace_tools/debugger/pyOCD/transport/transport.py delete mode 100644 workspace_tools/debugger/setup.py delete mode 100644 workspace_tools/debugger/test/basic_test.py delete mode 100644 workspace_tools/debugger/test/gdb_test.py diff --git a/workspace_tools/debugger/README.md b/workspace_tools/debugger/README.md deleted file mode 100644 index 4155499d6d..0000000000 --- a/workspace_tools/debugger/README.md +++ /dev/null @@ -1,148 +0,0 @@ -pyOCD -===== -pyOCD is an Open Source python library in order to program and -debug ARM Cortex-M microcontrollers using CMSIS-DAP. You can either -use a python interpreter to control your target or start a GDB server. - - -What allows this library? -------------------------- -1. From a python interpretor: - * halt, step, resume execution - * read/write memory - * read/write block memory - * read-write core register - * set/remove hardware breakpoints - * flash new binary - * reset - -2. From a GDB client, you have all the features provided by gdb: - * load a .elf file - * read/write memory - * read/write core register - * set/remove hardware breakpoints - * high level stepping - * ... - - -DEPENDANCIES: -------------- -pyOCD relies on external libraries: -* pyOCD has been tested with python 2.7 -* distutils -* Windows: [pyWinUSB](https://github.com/rene-aguirre/pywinusb): - ``` - $ cd /path-to-pywinusb/ - $ python setup.py install - ``` -* Linux: [pyUSB](https://github.com/walac/pyusb): - ``` - $ sudo apt-get install python libusb-1.0-0-dev - $ cd /path-to-pyusb/ - $ sudo python setup.py install - ``` -* Mac: - - So far Mac OS X is not supported - - -Installation: -------------- - - $ cd /path-to-pyOCD/ - $ python setup.py install - - -Examples: ---------- -## Tests -A series of tests are on the test directory: -* basic_test.py: simple test that checks: - 1. read/write core registers - 2. read/write memory - 3. stop/resume/step the execution - 4. reset the target - 5. flash a binary -* gdb_test.py: launch a gdbserver - -## Hello World example: - - from pyOCD.board import MbedBoard - - import logging - logging.basicConfig(level=logging.INFO) - - board = MbedBoard.chooseBoard() - - target = board.target - flash = board.flash - target.resume() - target.halt() - print "pc: 0x%X" % target.readCoreRegister("pc") - pc: 0xA64 - target.step() - print "pc: 0x%X" % target.readCoreRegister("pc") - pc: 0xA30 - target.step() - print "pc: 0x%X" % target.readCoreRegister("pc") - pc: 0xA32 - flash.flashBinary("binaries/l1_lpc1768.bin") - print "pc: 0x%X" % target.readCoreRegister("pc") - pc: 0x10000000 - target.reset() - target.halt() - print "pc: 0x%X" % target.readCoreRegister("pc") - pc: 0xAAC - board.uninit() - -##GDB server example: -Python: - - from pyOCD.gdbserver import GDBServer - from pyOCD.board import MbedBoard - - import logging - logging.basicConfig(level=logging.INFO) - - board = MbedBoard.chooseBoard() - - # start gdbserver - gdb = GDBServer(board, 3333) - -gdb server: - - arm-none-eabi-gdb basic.elf - - target remote localhost:3333 - load - continue - - -Architecture: -------------- - -# interface: -An interface does the link between the target and the computer. -This package contains basic functions to write and read data to and from -an interface. You can inherit from Interface and overwrite read(), write(),... -Then declare your interface in INTERFACE (in pyOCD.interface.__init__.py) - -# target: -A target defines basic functionalities such as step, resume, halt, readMemory,... -You can inherit from Target to implement your own functions. -Then declare your target in TARGET (in pyOCD.target.__init__.py) - -# transport: -Defines the transport used to communicate. In particular, you can find CMSIS-DAP. -Defines functions such as memWriteAP, memReadAP, writeDP, readDP,... -You can inherit from Transport and implement your own functions. -Then declare your transport in TRANSPORT (in pyOCD.transport.__init__.py) - -# flash: -Contains flash algorithm in order to flash a new binary into the target. - -# gdbserver: -Start a GDB server. The server listens on a specific port. You can then -connect a GDB client to it and debug/program the target - -Then you can debug a board which is composed by an interface, a target, a transport and a flash \ No newline at end of file diff --git a/workspace_tools/debugger/__init__.py b/workspace_tools/debugger/__init__.py deleted file mode 100644 index 74a91f20af..0000000000 --- a/workspace_tools/debugger/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" \ No newline at end of file diff --git a/workspace_tools/debugger/binaries/l1_kl25z.bin b/workspace_tools/debugger/binaries/l1_kl25z.bin deleted file mode 100644 index eeae1524a747860f7e55a00855c5d1f70f89015f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1904 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 diff --git a/workspace_tools/debugger/binaries/l1_lpc1768.bin b/workspace_tools/debugger/binaries/l1_lpc1768.bin deleted file mode 100644 index f04a05c26314248f79ea8c4ad2ba5a349754a95c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4132 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 AwEzGB diff --git a/workspace_tools/debugger/binaries/l1_lpc800.bin b/workspace_tools/debugger/binaries/l1_lpc800.bin deleted file mode 100644 index 5109f7bbf196e796a733de8ee76ccf92169d854f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2592 zcmaJ?ZEPE79si$w_MPn}zNBPvUYguF$(m$=*iAbM`_Lmt&v!m|YpP0Y>j1~8gzEr` z5HAw~bZt7x+7N2Pi&zHQD#WKv2*JEc8&({UAVosh>4uU9X;+03_5n3~p-wyqzvt{& z;YFPF^Yedyd7l40m-mqL4=+&*Pviss-yb?M_8VC50r!C&z-v6G({}cKGAQv5{PXCCwim0WLAgC8z~?ny_sTXeYo|>y zpiwZQrk5ay|?n8WzhZu&xaA zYXmh#*^w*m)+T0lTcBQ5?wB7>RQUZwKLml-_-rf}*p(*#Qlk7$B-`T>3 zl}NR1Ud7f*Qh^3PW2m{3kHQ#ga(f|pHB4vT|g($ z0UQR}fH2Skgn$4b06xGAZ~!gQ(i1F$-)_C!E2IA})p$K=s4<$g1v~67bJ%0g@KD)1 z{E5ntbKW?QI?p+i%p!ZxA_xnq5^^jf1&fel8cD2zL$ZO@>zp=ptSsMzqZxcU=EVOk zMk}&Bgc#9Er!#8U*^?msZteewW^nM!FgPW*n?|PHuxC{zkIM5it!^Kj zV)CLEayywz1k6%g%y5d3EFGK5pl0x9?v`*1-EayA>Ge##X1c&$&DlN^^{f6gX;d#tq zyZxTEafutest!zs%G|)bdM~v(Jx_mb*!>B1L5IoTO$}t`>25>*F60~5o!p&F*qNt0 z4e1)B^R(9B{s4~L9I;~Ax{#}9IaU6h)swB$LV2Ek+pu1Nb=>)Nvl^-VE9*kTE(p8j zhTRhESUqo{&Nr=|MpUVM)9PvT!K`mKtP2h6pQ3u^^^?>LcKD4gDv-SQ;Hf<-Qh@_? z-laUCo^UBIsH98rpiaA#50vUseo&9OlmO~cP(Q%5vfFSG)B2)epH#Dfj=c6g)BcE& z7Insn+P7V9E>SJ;dWYVp`(OT+QH|Z8(`OYu5;uNE+mG(hha#2d5Q|f8sCn%Qdn?9; zim1~iCK0u7nBw%q&esgpwGg$hnnt?MdA8vpYF~y2%U8Gl0<;JH^V;X(?{_|H?8nQ2 zuNJe(_AJ|-?#Z?ajR=*C$#a)nUdvcdPq#YhNhz|M}!X z!~dMM2>-Lm)rSA$)*bk#ntT%cT!PaL+-F?$c~zR^%AAa8m*3yg%s`flUQyd7y%kQm zte#3v;XRNF9-U-)L|9ebIr=6h*9RZ3vp2$39;&5#s`CzNSUYm5it_=h7rc#Mr2gnzh5ma)xFPT7?l2C)to4)6uOKgp9^p%EFkx z%yjj0<00LjiLq+6h|j)6D!np{)c~>p``(a3uTT__fj2(4(VASyEr<(r$Xd+Mu&>;$ zFXXs^ZcSwTh_CF2-UFToKbQEWf3=lUuB)D88_s~mr@Q2!?=;)@RiRCjp`oRI)6CLH ztumKD-|j6dV86S}m2?-I`rZgU*co=RDU2?7B<%x9DUBN&Z-E`XrnM#QkDg6Sm`Xb; zX)P{Cau7D6!KIncsvv1T@SJ=t9hBLb`>bwcMpcBm-0!N}FY1dGLORDLAj%B}oEH5Z z^@o$b+eh^8s%Fm+{?)Dy{ahb?@Na*N75yo0$p5&{k@d~2u=0rZ{e*P<^~ndf_Z~c7 zs|JW7L892}U(_%54Ly6Y_ti=M_RJ?Q&}Jm|i%8;#UfuFI;!1nJxJ;wF=$=g_=WxsI f{WQvUqwdeX12`XALp&MrKuflV=r7b-tWx&em=k7Ki?ZZx2jH^ zQ>Ut)syess?Yf7vM~um6tyT8VP_>HGwr!UwwJqXa zHsp9&-o^52B?I?wC**hqNUl_(e-pw@O2wF8i0q?r<>1=C97+GrN5DtGN5DtGN5DtG zN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtG zN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtG zN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtG zN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtG zN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN5DtGN8tYo0x=bP92IRamAW6-|Md6Ze*A}# z-iYh*{~y<5DDxz)r*S=t>v>!+;(8g^tGKq{q71Lsac#x*mPfyh_+4B(aJ`Q!ILaPv zH(gg2*rBTJX|V~`!0Q{neK*j!a%7-UjZ|u9M5#?m#ooa66*{-kKw`t7rpv0XQl-<9 z$yMuB)j8?X31zeN&-8WA_RiV1DWk8~1NBwD6X_%9qGi+ha z=y1b#n^VclQdhKGukxp@OrDd@pP-Y4i4R-5jnH>P%JOxAC1eq(B(#45EGHEfyl`kXCuHZRN@WwC}TXJ$BovI|09*-g;; zTq-spHepNi%G4WES0?L?WO{S6H9Eh=SRdP{R$BG@zT3BN-w*rtg|&+PPh*+o*&A}2 zavIG6rDZui)i!&hHCpxhZu1o*zuCPhL(F(l*4_|o3^tXPT^xHSx}{`POl^T|lj{B5 z=5;@jjco{yNiA2sLtFNJ{pvo9L#?sdYE(PbW4f}kEw(YM^9_uRy&(iG=4QJwG>Q^- zqi$6_&CNlyL!lk}zJ6k#y>U~9ZJ_+N{n}K7l4?s~(=RjiRX;PXE&EwURbHHlW(pb$ zN5{+5o@2g^QUWcEc(F>VN-L9>QOWQqRi#pDkNK_IllnH9>6uY`^7pDe`Wx0|v)AqT zvAqf4Ss6rPgFPm&Gqs?k<@>5D0x0{<>;)~YWv#J>FSqP!wOjrH-1b1s-e5M?R_ZFX z=lH#BKl36@bsG|`W>sOm?i1UrQY*WcB^CyfFCK?+Ql(2vTk6<TRL{Vcb6e}tuT|-?7PV3L{2p{eYiX+k`k&}y+lIV^ zl_*LqNF+7~+G-Q~zJ6if38C1imX>uY+SE|;c*zGXl`|uwBcskOsV}*yW%kTuq93HT z>{ETMEwu?xpWIu_f|kSN&P6nr<@tv2?yGkPV;Sgj>hSEbFW z{Q4JEWg=%xe!8;$I-@kLTVfl{F-GYX>d(7bo@>X|0lfBv_o~{!7S%^>`C+%(^Ygvm zA=t2)FuM!Iaa!{2`J4HjChYBkpE^ZSfZ zYg%njUe}vVx@z6bX$ze6^qK4z%Nk9(a{7XcB!{$yOj%3YNT$_>Yu2}BIQ#c~{rL|$ zzw0TfPksphu9u{C{Sg0MZ%J+c!Msji>#Qql30@PsPPgP;+Xd-@Yjn%iX#1jl7Pukd zMul6nANSaOJ24h*8}@zu_`b-P$hhvUxjPSN-S_pi`)bQnt+TzdwSViSt=(Hxuh15C zz~9iXTlckXOtqFk=IVXl>~3tmV&q4=3xP=quGj`^jOt@-rVUa%lL@W`AftwCu$$~L z6^Wf?t7Czkzf#ASSO*uht{bTjReiqRqW1jyyCEAl15etBwhfV{$XHeVY1w(Pt_c&; zOQv2iQV+bn;TuS<`OY2{8XZYYF1t0Rs?D9hR(qzd^tf#spF{cVMSW_+suDAycb2y4 z0arGBw?%O#^c=WZ<8BnYcTGc|*L8Ju@K+7iYv(i=uZ48E-n;uFm8D0i8EWtDH4Xap z`m(b082hFM<8@Vjv|W|H#7kd~^h;iPJJPDw+*}^gn?s=wcgGU3M=+ALdb3JyN(b*X z8jWAoml#)=z@(I*^xU)A1nv*+i#*bhzObwWbAt0?&xWHi!!yTa#%A{1J6=^Ja?Qd- zS?(Em7p%`o{4BFB^J-M}uH0gz)s|7aCS_>5Kibs{ySw9CGtr|~?bx=cVgaknSNU;6B@P0cX3t!a#s>-^2Tpj z^V(fzqPEIDq-P>tc76Sp`f&P}^$#~q%aoO!R>rX|?(Nopy~%8kKivPAFN~IzO=>eSIdKIX6=hwo6)u zuO6Y^?zT&Z(?Foq$_*=PQ%R*&9S&R(OUz1#!p6@U)BO|k(xcPHb$4fS!dGPO&6Fi( z4R08J#R%i=l{HI^Ylatv*JmCduB;~T6~HTZTV4{K)ipmhN$uaYt!Wrdv3Z`EzMEYk<`?Y$lr0E$IpA$?3B2%98b&`jU~u zugzdKzP++?oN-I3c^zw?K77`Q3x|zsn2@qgu+?39KXnXYLS9);Yy8txc&P|4zksSQKY z2bBcY4J(*?ch<(C8}0!|M|{nkHPiUfq~8aD(-H$Z`jEVb4nwLT{^I} zuF<-7W$Jxp)o(8CJ8Dfs^>%&T+~7a$IYvW3_voAEoa~0#r7A;td4cZfnlbS}pZdb| zY*m*y*4`KFml&E3u0QmVD>Bz)ZqD46*|Twarf)+3%&2{6i@rgl)`HP!Va<-+lQa4k z=DIs}>l)Rg%a~Id@*A0L76MY?4 zRQsmgkJ>-V^KLW1nJ1x=ev zR@c|0mvp^)Sl_g&es{ONmSfOj=pM!OebZL1syYla;m^P&Y95-_>#9xNqdGTOuSWOV zO*{qpkGjvTn7x zJHlf>FWX*Um1u5IJ=K<2qHd!-#xDJC_tW*k#$JhvlH2R6(tCFQ0GunJcK~(c0_JD` z8FdX)xSK?lCK`;Vquc&C+0nIKcFYd$tiDOba|gnbsLGN=ZeG_wqN#s+W?+n6P@hUq zS4Y`@#=Pm7ZriB(7Gdwwbu(?;0ehX=itV{o`DI2TmFUv{#rmu2yCOBvjEt+wtt%TA z7?Zbkx9VeVo*j(mI%8hl9U8;k@rzs|h@ai9v1`1fz9ykkA7QR=K3vH80eljbI#q71 z!<|NjV?)awNjdh=@{puL)==Z-*wOVRygyi`VQBpE7Q(;18?bMC#D3%k+&%VBpBchF zKi9o(M_lb)FCos-Of#SKQ~O=pk>=k=|JZkSdqr-RANmOR2>1y22>1y22>1y22>1y2 z2>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y2 z2>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y2 z2>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y2 z2>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y22>1y6??hnX zc7y-V<2i;>)9`;%9*NlhQ)*ZbpfGdp%vlSRu0S$y(4+&#s+@3eY)HqgLfu6dn8P>Cg&|)k{mX1Y;we+S##&inL8)hykzn0xl5NWUb3`ja$w)V zefuZ-*Y)dPH>6)(vUcwBwz*3dESh`bvY88eCTF1Bfpfib2Mj!J@By=y%sg>+YjVll zQx+^;u=vDezoB*gh8}c``mihhV^tX?ORvR$_Gyja5aNF#Z` zmWSp5jbvy6!phKz2&+O%5vD@R5mtv*AnYDmg|H@c0m2@kOAywE)*|c~dL5wk3cZc6 zcj$eDeL^22JRtNr!oH!uAv`ejHNv{kzYz8dnYL2>Lm`9%LQMzc9aA;^T!h=I6BRnK@2Es!_=O8>R^aR2qoVGzKsO}^M%Ygsgs{IFgm8cwh;X19jBt?3MR<@3BOI*q5DrlhghN%#Y3pC7iV*fw zL4^HPKEeU2AHspEKf*z32*QKZP=te(g>Z-pARMZ?J8c8%R29Mj%0xI&9f)v{Dnxh? z2IH5QOSPe!5%vuI7GbZ@?Ff5^9>#1b2=zu7cgCgF*~;Wx3S9CK!dz=D!f=UE{CjkH zDP;267M!Sz5>7EAr6S!h2aQrrP$OkUF67KF4-3zZ)Nwf^Tq+zHMykT4Vv)mH4*yLz z!c?I${{Zbqw>U`iyDpfMTbDwk`3~q{a3Pc9pxKU%V6qp6((c1#^kEdsnWZTlw(a57 zn1K8*i({5Oau?$KH^HzQ|G;E_mKsH_iflr^?Ge<=E<`Cb`U!B*1r?~H1ZJ14K~tGE zP--{b2ex?usjJ$1PW(y3?h7g&2c=C|EELWOZm@C5lB>Assp>+kwBcC4;lI zoJMMhOWBd5sCTGKg(H`vFQJ27Di)cA5eXgQQiYL^*ziMLsw5HxT%p5UDiPUAork+r zQWfq-^|lU;Jf3ZNnY>0O3Fa+W)1gtM%+yL98Nw=>YS4a=Mx=v?JDjeC)#@*>sk-Xz(%~PSf-a|u-R4lTaom%gf zD~a^uSlv%dj8r00#4bMAhSnOXWaJ|v_wbEERY!(ljf6HnDO7D_HK|8;2-PR=xRYn8 z(Bp0mb)eAZC)_p<0fk0C>DG5>WGvhH%!g90K5{18`RqT0O6MK75L#YvwG5AxmxK4R zTW(Aw!*;&nQq7U)h~bv=fRB-y9J!TRww6jCrbZU9hPSwyjMUMQdsuFpTW*djVuHnr zC1AIUXQTFF<^%nU!74c!Akf=jWBC%c^>|~hsA?|1g{n?4 zj*_xd%kw!>3k|m`t>wp}aiK*X*;YP-Wl!|T<>eQ%-o?hcBFnvNNd-Nl^`~=o_ibp@C z%by|tR8Rj)T9xeytuVeNUR|l_Y-0;rLcDemf|bTDA(yKJ;SMb~Zbt7C$5QDz0<$V# zSPUZLVWrByp!6cSLTI#~o7Mz_Ldg@i4iEmS@B&O^VtjzBNNp)Ptf_~l}hizUqo^a?v#qFE6a+ybIls@-{E zqcS3pYf*F8C{#v5{q$O@Ddqa2V(9l1rD(QBid)HZ+yF^H^JD?tCh!%w6DS z9zS1rC!8hG!k;TxTN0hSSEALWaTY(nPNEBrW)z7 z5}j0CNG(f7NVIg8M9a>V=;S|0bjsrrow{411^X z(X`_wntriFGj5mY=$9or=1&qG8z^P*<7y;oX^?2lxK8Prvz997 zh=s`1oRIE9s@98OY@K?^<^(O~K2BBZ4-h)TZby!0P)y^9$7oAofmZ8HM#S#>Nfps27)IHZKMI`o=>!L#*HSfS; zcgBe>E*7^iHK>%Hv)~lvjOR+!TtU)9x0^NE#$0onHJ4O2>qvCTnV`A6im4FVyEAJd zcR!lTE!%;uT=dhWUtE60OhNiaLOX*?UUNB0c9!=(6go#sJGn-sohXt=O~(k@T(eR^ zme+@s&t_kAPx2&?o09Y|*E$fncz0pLmI7;5aGYr3djGL>js6RfI#tsONcTFRDi*MN z=531xfKMf zT0cgVW{QgC?XqMk6Hi1cQhP3P3ob`Xtf=}W(zVYcO%!mW#M_?n&>g$^D&(2JK#%kL z^X6*y#)Qrv%nd+|ei^#*x9cs`&H(+V<*e58pg;c(shZ}}WmfB#F)aBzB%9_loBaxu z<-aG{G^g3@&ryH=osv!Sn$1QvD*p+|rn${#Kh5mdBzs;qyO=37igvtOZ=k*>WrEW( zcRT`QRcvK1cd;XyHrpK(S^U+yoNfH0sHY*9A|lWen%`x?r-VuK?k+w7q+0)#yr+dn zo9~S@>Oi@3*`k+aGgRP2ud&zENib;pn_5*}PF^YnXvX=6@vFym4l;7b2biv1Ic` zD%mctMt?<3?`qyzv)EK{Tpkc{-f2a$C%V*)qU$wpyY6tX)9BZq*wwp5p7-Jop4$^y z;nn&M;`D(?@mB3lW6n~}#P2zn4+)bu@QxPtR6X=L#NalWNY(lVRGELfz|EVx3wO2F z)c%qv;LW}hhGoS45#ezM;I>bUAMFcjzl`Jgs0eUx;MVT(Zl~f+!sCXaquIrtz}+Yu zFA^int%N(1D4)GY>;i0YX^`e7qvO_?6^NpWc!_A>_QPFHa>MnYi^HhKOGSVilb;G) zi4lvJi2%1OuE73nn9eH71vPGFI(mWL7XY4kh4hd+oDS^4I~d~kQB_vpdg9+*G;k;OQw?8o1Z$;c?$J6lpn8+7>LZ1@aqB1yUVz{nDCM}D z>)>T;{**N*q%ik+u41+nh5yEW)d-K9zfP4tL&ZIW#~op(a<5QlPvKqN&J$yASk`nv ziw)m*=uoejsGz9$YP^@~{Tk>Jv*(qtGkyADE}2L3JvHu@#sQis-=_>QxwuKBY1-veqgKA0KJ%U>0#)Hh2Cl-rbX^6$b8=+H&8ExM8U|p z&<7bqWJ;kTiK|^#Em~SI{`ZjK1_g4a$PI%`V~5;8J(P7GnTPg5#uAyi;GfhkQ_S*e zknYAxr^pHysSDaA`bw`Llxy9E!8=GoLmSUwU<v%sa$DiuJwDQhq9$+3Gg}q*TG+) zJ51<;^Lpq>589qS>-|5 zoZu}`)9_bhB_Ytjn(L8Bv(FTQF;Zqz!&O-U_F4o6djfS7IJhD05V# zF}QT_d(?m-P{`8f;HKtPP14s z4X7Hg?}kY&PU>RLFR^;XcS-4wv3Lx1I1P(F2hYaZL~w<$+@KZpW2GHXLYq1eJIa&H z2O~-?F^7lwQ{cS_&oKF1e5QFJ^3O8uJf+SyPe7>5!;!DeStw-vrxg1>E3?dye-vrk&9hA*A8<8J2pF)^tz7KB1oP;oHo(7qic@gsSO}+?@ zo7W*MFvp@)p?Md$UCcirr^vhwVX@g8`6cGd$S*aIK&djb3F&h4VYD-09*=Z|`3~CC z)%+6aZpyk9n zz@Ov(zz-gO;16aXw;GqtK#I_WN%nQw?4SzWgtS9h;cUoqv`asorA?RKnxzeuyVo@C z(fnyK{5^Va+^eYy1~I%3T{Jd$q!s=%kTCA^NIP6b;rlh)fZwdbYk`gNfX9u6*OPqE z;}(WrAo-BgVx&sKbtE75gp=VZ)clA?R)^mpccVTMO)^ro;ah;Q@uvcGX`d-l&Nco#|xEssA>hU+}@CB6L?9or@@Dxm0V~a;WhgVcA|C;`l zlz&NwFXU*w?(ui(@IcDH;n5%I@b%QU)uTVv;WCzgQ{N`#ztG`1EdQ2_Cx4a=FDAXs zqgNZ@YRbQ@pBDKwM)+v*-|_TqHo|`={jNv9VT6Cp{%qIpi~KetyovlB9)FJ!K9~IW zJo-x`d?oqs%afIv+G~V|lHTd@*O}pKDZk5W&-G^bPSPLfA4LC6X81+Qf9T1tw!#mR z|B<$_mhc0x72Znz#~%MGD?FWZ;S(Jf{yHoCCF$KBf4vp{6X{Pq`d%wMll}jbM?YYN zU#I@hbRQ}Ih!y?~@%`Lu-IVrRLr5UR-Nn%QO#| zL?>cK>Pp@@euuo+NdQn+(xB-H`8e}cH4n*nKMa$uraWZ|S`Zczh+r1w(M08JwMXRJ`#t#1J9dmj14qIr<3MZJa&8H$78-RLew!$Fqh0#hEN!~K&STbAv}(4o$szpGVpbO}%-)W*cDY9h!Rc0goGVXzI-eJ#L{x zQ*S;bwZPOnH1+1go^aBksW%_-$ZChC-rT6C5YAMsLsM@)>T&BFntJmwJyW;?9h!P` zlgF)hXzI@UsW+eYxNQziz4?qsE^}z= z&1XGwxkFQLKBrHXvS&Ip_2%=!rKxvl>dhDQ*5l_2xUCzRiY1Q*XZO(Qg*CQ*VCg$*;B?ntBuc7XBK` zp{X}N_V`y>4o$uJi7piWI?JJ{H+Osd^_D|ZZ+`00_gW53z4<4Pe!y~Q>dnt|Un&2H z<Pwd}f@dS@X?qXY!6;MG z&{C#YM5NhWkzS;N1IX!$AeW}z{6f>_gipo1Gx}(4=INP8>H~GV3H}Ux&7%;JJUr{_ zetJAI9I~VOPn11R>n}m^$DM0%>3bm?!(HHfft|O={Nc#rd%!~SFV!l(f(3huDm>h5 z;{D-EW}U7VLlr9j2#+;}S_zx#S@oHy9CGb{3&Aq9`M>V*#d~HM4>*ioy@03XKE7D) zh$;m9v@#2@g63-1MX*RZe@;8p(_w|Jg#sb zBpjT?t2d9pMj7*`p-!3g*fXLwJd8B-Q|2)2_(&yHup1I&NvUqiVF?NH>dnKAA3#N@ zG}?eSaYn>o6Ig^PuL%x?VtC>lX&i#w@DxZYK&QART;+IYA9~!KEgM{h=xj~LFuHdtBsy@zx&8Q<;Aos$t z#Q|3hD zX_wznAh)qeS$;#o?JPgpc){hT3*B9hDQ z3FsAWrf~jU(B(td5{zDxY6^?gPeFb<-|Lt2j4u%iFZsnzIl)n@1~r1M~C?4VGb5v(v%bL=7~sG znR4RYloRi!oOm}^A-~4F0AUYPPQ06Ik?v{AiFZ>@yqj|3-INpWrkr>;<;1%wC*Dmt z@ovhAcT-Nhn{wjaloRi!oOn0o#Jedc-c332Zpw*wQ%<~_a^l^T6Yr*+crW6K_adHn zFXD;!BA$3J;)(YnIq{AVC*Bd_#5+Qqct?m6?+9_?9U)G%<_*=y)M)`q5CnFl1HMQ zTy*HeM-bM_V6ZFL7@cBcEKI$w^OUaUqZdD0>GlJ1zd(sSxO9)Cg@O;Ff=WFhI-tI( zx@y_U_P#PEdR6LXV;K;r(mdFqr$K}JHx7FAeXNKty!A9DPefkoQIR8#mxHXPG|%gz zBmY2NmA;$&V>BCk5H22g)nB#iIfi;RQ%{x1arJ)>k_Dkf57I+W=q46s+kb~Vw*iA# zkVoF#jt^qTF9qr98ALsI;_AMKYKJdEKWGqZc$||zv>hkiZ#GUw-V)^T3!T#>Z-Q|O zfDsgG&H{&>`I*bn{m4L(B-be!Kv36tnX1RZtgC>i2TWV5Sgr1YoSbf2Q?@6Y*ppn< zOFu+LQfoJp=qa@g4Kx(H=N;_jkRfGZQ58{Y%D_9ScI^#2w`Ip!p0(m zjYS9>ix4&zA#5x{*jQU^EJD~=gs`y)VPg@(#v+7`MF<;<5H=PeY%D_9SX*o?LfBY@ zu(1eXV-do}2F1n(#l{B3#suf!oK0e5gJNTYVq=41 zV}q`ZHECnb8{dGWcT_rLorB_ztRP*bX#qCl;`cZDcm%m(@2WU4E07;9<=U%Sh%$UB zkr%+iZwh$a@nFb7)f$p2C39LxD0g`48OOwpG0v*Taf+Z?)*Q0 zW%zI3Lz$gEE%X*Mo&|8+Nf*cia(^`9b6lDar-A#~^nzoM%*C?LNr1upoL)#g%>?`V zDiSKF^Pt4&sVS^&eJ4s9$7vnZ`;amxy7_ooVDA*V;PviXl%nN|?bpMr*+ci~;(zLB zwlkeRp7g%4^t$GOU|DCPRo;BDtP4Q|n3E%o#{H7;>)>Sw`9;8?xO$?$`VnN<2ZQ=0 zMoWcs4RK0}G-&x7ML9nAIxL<2)0JN%2?OjEl@zzXP%@uNdUaC5Ph#}ZP?CG{f;nLF z6~Tqb>#VbP6C^rxhN=BQ=*;u(#38+tst0sZ&ClBOuYS_LfxqaaOSEor+xKfKIi!=4 zomBG4Pm~wKiVBkfDumXsB{5Y>ib*d;yIht=5h*1Qh z9(mGNqKv+p|Ip2>;t^IczP*Z>EXwfrTz@bchSB)JrVDi^Y8=g$%6mdmJUAcz>oPW z$~yQwp!j3{+BqHkL;ekaMb{4gjDN#l+v;M(_Oxy@iV2@C zJr|(_II1ul_6=4JFV;Lea53PW+CG>Vb+i_X|9|P5n*aEE#%#_2tp5+MXAXh*N?i5= z1bE#+nvW<#<2Pf{H)Uyj{L_ZntR5 z|A8__U(G^h5Mtq1C4+R{%q8=|V{U}Y&Nz^{P?U$9XiUEeNxVN~3$lOQ|LB{*&Ocw6 zkAimx^71c6jatgf$*?^rpzGKdW9^)RH}=z@2VREag?o_2v%OvTenuB%^%s8!GKzWV zo;tzT-5XdLdL z(Ya*}(z2zHDkKu;BhlWt1i`>x$hrabI2`d9e#1t^BRaK_U!3W~a1)m{j$j*~L6+Ob z5x0Tl;W@XBBiKd@OWbYa2(~c=(rshr-?nkIv~f731ihU02FhshCqw+jbQxPVwo}V4 z2Txz0ZP{41>|tbehG3kie>)lU=k z{4q|{=XO?q4Dv-ize>VZgALC9odKSHGpqh+s{idz)E^`2pUJ8ZcUJ$8ton&m-_oh| z`S>+OPs0wvUB@k4$NYuO#cHO9Rp*5}XC&mM#$zEV9g1|Wk*ACP{lcA10OxmV!f)Ax zeQd%iwr@V0@H+DHN41kY=i|1hbtSmQ+Lq2OTJ(0dMM?ZxBrS?|Zc!8R@rc2Iri351 zWX%arwPo!K-wI#`b62cSl2&rNIT6a8spQu~CpE~nL>YmA} zsXcX5pM)Q9<$KXAj1@u*HW4W9#JcUr8>H1mJnsf3}BgKA=dk=3$ugaXm&&0kCowK~pg`y^pLAzcE<>!qLq^ zJO?>6-?hl~4nO~pAVT+kgEN#xi!c!gD1e}?MJQun7s)xR%6d|yBm z=RQARW%Hr*Iou1gfBdA5KONozUJ|PRx1D}8r}P9A|Ly5VtC=r^|C`f~l)D6%%|MF4 zaKae?DCcPN_6q=aC58bXjNi$(e&OL`#whcyE18_!h~KByOLAfZl6Nyn$$S4y_NWoa z+aT=WW5(jROP2j$7<;&ICJpvO!XCvR;vN=u9$!M@C4C+%!|VAxs)D14$QX)mqzoN+ zj3xD`OT{8%CV_g)r3xcsNo{helE@@VKJHS9$S_h*xKuJSiqw-XRUOF;2lbRo)kels z%hN8^Co-9RdB&ycqVfadvvdste+bbFaCIbZvWCiPP_*x(0S7>KiKLG6_Ih{!=rZXvLhT8-yN@r5eF@uF? zM|TsBV~LD7lZso^8Egc1BrZ>Raoi%6FV3W#1*ak%r86n#cqUl|ok=+-cvS#)&V>A% z0AQ>0`?pYi1kR+KKX}p+IFoX2^MoUCCgt4j5_WV2k-USG8TX>-b~f%#mx@H_Ov<@y zoYWYL(wUUA-Yr)Wr3rWLCnj(v6{RyN=fRzLxWs{*D4j_;4@a>HGE&viVORpr#sNar zM(Iq-d33B$eIj%wP(d z{EZ!NGx`a=Mpw|8lyj2QY{HpTg~f&~k>YeFRl(oZouwXqyRM)!DQB5S-wS;-9VdJA zBf8=Q)_00WKcy?^Ov*Xc(+_7-i9OB=<9OmlXHw4D#xOxdRqP-HD~$<4E>~R%x3k=c zL#pesRCp zXHs$NZOmtUq{P>?af`-9mIJ%J-*OPrTMiCb-B>DaeS)yWLX|WC`->whyLx!&Sya+2 zbjYCeP-MtWj!WI!F$%pjOXJ4+bB;>BUV$h%0>FixF8U$xE9CZ8ENLz{I+Jorw7Z6^ z3ObW=O0_#LY*a=B;ubY0qtF#``e_XiDoVM2`b(N>ZX-SeJTj+(&ZL}ynm2w}P!(i? zi#Xd_!obBPbg2rG=He0>2YyL&iVIz=f;4}e<3d-cAk78mUzVo)Nm;r?Ri24-DFd{f zW+-lv>)was7N?tgi>c&*XA!?mvadxLBy5i(A^Ht$O>)JV)Mv3K*qyj#x^wdbu-q~=E@dg}36|;c70Oi6nN&=@f+z7*cphs@ zh38X2D!jnWJf1F_QsEQ+BGJMC9->p>MJb6+JXoT|6C`TmXTGWMNe@c2WUE9=Kb2_N zcM_c($BUa(_>`U!ojO9I(~g$t^yLzr@f(R&JS)*zf0F3ze@e76j@L-3@HyQjS~XIl zb6X`^eW66>-z3omFEPrSNq-ZmyjlE#A(c1hYKi9FCDFWRB$`jJ5vjb^FC|*Qx2&nW zC!JQzfz_kO=nWMGq~h6 zm!o87d2}X~d$hEZYgF2aB6-wwjG)amD-~pUbS9NMn|;yOkSBrMl%#)g>qg|_EfSqc z0c%!poM_^D|FLwfIFrgfRnrPc_d1{|6|j4XGpXF=q5|`PojFY!OjFTOMAeEjsoWKs zwxg8R9M#jARPI?aKZY?|+Q}3Kk@(e!GpXDQ1T>nN4vFl{OA(6;`ADZ}fPN~#pW$*Z zk@nFvi2xMu1VXuU1t+@naksIO@^E?jX0Caohd3lZI>lWS$HB+(OUjYn}0c4 zV#QP*>{u^4lOhVR{aRU*V4Lz6u@lx-tkL}QcyqMqVk-aUZD@x@!DQE0R>FcSGs5bXpZ3%)Ljg zIIW6r*T08kDFfilQZ?eVDt?D_k!IOt!pRj%#dkBMuSxdd+3ZrL&?w$7YQ$+({7G3zyaRMRYGhSxWiNNJBbpGp zgD*y=Mx0i~|0wEt!;m5(&>NcRv?~6TFnJqs7r6jZBTlR0PYaLt7FVgqJC{9tS!NAy zI34rbT^F7domR!~l4kLK)X}VLyXmwley>!)J5}ely@LUdzadQCzg#BAH#_C~W6{R9 ziNLAt0!#t86^OdI=+S9a{2f_3yz^!2rqinUE7Aqt30=ELvQro6v?~6L3qpJ0p5nAB z{;Xuzh|{Y0b22=r(vMe zs`v}S;|)05c{;6%zbM(fA!lo#)2jGKlFb`*Hk(eX;vY*kZ`hLU@@mCtRs3DeJ9rkG z3XaPIBF;OyNcKjT=(H-nUi0?u4hK7pe$i=F{BDuwJ->tJ_Czd6jX14}e;`ua61dZt zvy?NDPOIV%36mRzju!S-J;iBN{5F|LHR7}?e!IZUO@s?~jX14}za$E{spy1Z8F7C^ zc-(2Y?GqzQJBHfnv?~6n2yhSL*6#7>v?{(yc-)wDG`rLjpwp^?A~E*dvbZye^4WV4 zomLeTiw16HI&Q&P0XnTJC=m_Z=D5pAZtNa({8+6(vNbnAKNYwVBUVr*8n`ub1@>

DaYMec1rU{$bu>D*PaS!2f=h>+ok0urL6yAyLJTdkbk5=gd>d)VYsd{K( z=`x%eh|Wj4u)Hs90Pe$4`b{cKln7-+Pr|?zR!kSliXKMEu5*R5qZ!=V3%l{iiji`n zldPmyEtmodaE7b#w};K`yU0O0Q6b2f0+AD9=6>4tA-!=uAouX_NW}sy=kq1yfZC z_emRoqt&JEY@l!+e$MShXI6KE!Tm^Iac0#;oLR}_fio)#>Wv7V!gb)|kkqQLIJ4>^ z&a9qgjuF!$_c3I?=#Z-uXI5R>omq)Y2(`v=wdj{Qbn~#2qO4DCNw3B5+m5lC!yz6>Jmz3AbwFl7{C{G9gJb43jHYr{@N}Ceitf8 z?m;C@RAQsbC@xnC_zwA%`6xe;{95w%=WoJL7NrhFDCHZ$8{fentaqT#Mb#gn{8W~o z)4@|iHX>IKy@}yv$Uj&ghssL(+=V8)BROO@+NBREKxpY+S3#y%9?~5Xf+x)Mp!ZN< zygN9GLi!a1@8de~W!BlTQ^3?Xk8+2ekM?>~NJ|No#9kDaTLN!wHYY?G(i5V=~& z3~iTltv1aGO56gSy7?a+noTJ&9nv$~OF*sw3qv3MFuLkZC`;s4LFUSKIhic3o$ae% zB?@z^QO;{~KuX*T>4)1(Ky#3Nn}0!v<{XjR4w(--P{B1}VG-ly=aX#0A+SwxPH&TGtZ;{U_w-R^gQ$KW$?|52LrX7*h@D z``C`dc$Bx!ozFPaAOij$~*zQ5!}?ebVGU| zd6UUgD)TVfll@EMG5kDg3IX7e?QNTl>_)l}9M!fM=T{bR#$1cMQA_56TuAaskfW&v zr^#N2h94C=S z!x4-ljJmn84ow^X1Jit{bPLhNU-qvHvX5q=n-Mg#&>-YYpl<#(qPUS>yFah7C9CpS zQ8|%vD-U2J-H!|>z3vqzV+mw*Wwlb1_s=y(A4%rbDD^RPvwIEfblTG)+y}w6QL;%- zB3>>6dWa_?)xIm$PB5L7-Lti;qx5@N48}6v$+LeyV=H!b$5%u=o@^|mrF{W;Q)K9u zakvM7(YPF4n<`W6Tu!m$ktYLbT+FGq0_3!H5E%eX(+6>l{+#Q`SUYt_wx+#k@X_;@ zD&tzQ#z&^l!16J!XARORn(kMmQ_U#m=JB5JK}X&()McDPRE*_<>Z!;$mbnpB%xQ3{ zWM|9M+*b)lbP6&w@q`32s=aZGAT+8?8JE+tY(Q^Blur(LMDpbQ z@?Q8idGB@P$$+q|S58e+CQK{Z=XP@wyU8i#P7<1f3C1$i*N!BOYAxiu^+$7#()``n zcy)g)??7q&N*0P&3B}9Ea-n#YKaLc_9J^4w%0A5`DNu->dqFmqpjCuo3pM`*In(Np z^JIHF-)1`vOsuT=!iPW;JGC{pFJWrYzee50r~5Z>Ad2Z|tv6PmvVoJ4)!4{7Ww8H3 z?Uy2tJ&ePe8Q<=&;1McVl~wR96>LY=l#x*2N_N4Np7J1TmV)C!Hny~@-zOj=??;VC zA10v6S^8hlW^|L^x!4B&-3D>}9O|4sZ%&r?BJyT0#eWXiO*jEGREDXFU5{I*pI7sqE=Tj`&BNmDqg|WRI*(@N04;WAvY3ayCj4x}3;069IHZ%9M_RInssBvF7dLkwq(rC>_$f18d%8*u$VJxlIF8Z z_U}kENWLMB^%GBUkMr#5%fdLwfOTTyOpJaf`@iSKVK;mZ-{yE)=~H%FZB z=7{s%9C5yzBhGho#QAQHIN!|?=es%Ld^bm&@8=J2B&&-t!3C2=O4&RTZG`m@AuW3}8!Y%I$+><=iP zj~%R(H*Ikw8_)7h`|qr-Ku>Y`R%leSG79ynE}5g8qtI9$y~$+&QP*uom@O9`8z#K2 zN-{eFVb9O9k8s7QSj2-WOkUn$Y=0NM3^O5eDKf&WP>SB171b{N$1Dw>OB8w{OB?v^ z()!4R9f*ycSf{LysRvMk>ZhzvT*?B~Us=0d$_6z+S)aO87-xj75BN26eC$MJeaKV+ z)vGWY0quX8N$qKB|LYo0dz#w!xReDRwExYeY*5htcb5|FUz|qmI3;iWnW=�u|x^ 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 ajo8e+7!6d>PuI)KaOMvGc+J9Vs{a>20sKAy diff --git a/workspace_tools/debugger/elf_files/lpc1768_l1_gcc_arm.elf b/workspace_tools/debugger/elf_files/lpc1768_l1_gcc_arm.elf deleted file mode 100644 index 54957f67df6e0954330e8f0a5c65596cb7641f60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 154417 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 z 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�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

^W+_iXh>w4)YSTl&>B0T?0nM0mnVqbeoJhSZ! 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 0 or not blocking: - return mbed_boards - - if (first == True): - logging.info("Waiting for a USB device connected") - first = False - - @staticmethod - def chooseBoard(transport = "cmsis_dap", blocking = True, return_first = False): - """ - Allow you to select a board among all boards connected - """ - all_mbeds = MbedBoard.getAllConnectedBoards(transport, False, blocking) - - if all_mbeds == None: - return None - - index = 0 - for mbed in all_mbeds: - print "%d => %s" % (index, mbed.getInfo()) - index += 1 - - if len(all_mbeds) == 1: - all_mbeds[0].init() - return all_mbeds[0] - - try: - ch = 0 - if not return_first: - while True: - ch = sys.stdin.readline() - sys.stdin.flush() - if (int(ch) < 0) or (int(ch) >= len(all_mbeds)): - logging.info("BAD CHOICE: %d", int(ch)) - index = 0 - for mbed in all_mbeds: - print "%d => %s" % ( index, mbed.getInfo()) - index += 1 - else: - break - # close all others mbed connected - for mbed in all_mbeds: - if mbed != all_mbeds[int(ch)]: - mbed.interface.close() - - all_mbeds[int(ch)].init() - return all_mbeds[int(ch)] - except Exception as e: - try: - print e - except: - pass - finally: - for mbed in all_mbeds: - mbed.interface.close() diff --git a/workspace_tools/debugger/pyOCD/flash/__init__.py b/workspace_tools/debugger/pyOCD/flash/__init__.py deleted file mode 100644 index bb29a295ba..0000000000 --- a/workspace_tools/debugger/pyOCD/flash/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from flash_lpc1768 import Flash_lpc1768 -from flash_kl25z import Flash_kl25z -from flash_lpc11u24 import Flash_lpc11u24 -from flash_lpc800 import Flash_lpc800 - -FLASH = {'flash_lpc1768': Flash_lpc1768, - 'flash_kl25z': Flash_kl25z, - 'flash_lpc11u24': Flash_lpc11u24, - 'flash_lpc800': Flash_lpc800 - } \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/flash/flash.py b/workspace_tools/debugger/pyOCD/flash/flash.py deleted file mode 100644 index 761e19e572..0000000000 --- a/workspace_tools/debugger/pyOCD/flash/flash.py +++ /dev/null @@ -1,145 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from pyOCD.target.target import TARGET_RUNNING -import logging -from struct import unpack -from time import time -""" -import os,sys -parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -sys.path.insert(0,parentdir) -""" - -class Flash(): - """ - This class is responsible to flash a new binary in a target - """ - - def __init__(self, target, flash_algo, memoryMapXML): - self.target = target - self.flash_algo = flash_algo - self.end_flash_algo = flash_algo['load_address'] + len(flash_algo)*4 - self.begin_stack = flash_algo['begin_stack'] - self.begin_data = flash_algo['begin_data'] - self.static_base = flash_algo['static_base'] - self.page_size = flash_algo['page_size'] - self.memoryMapXML = memoryMapXML - - def init(self): - """ - Download the flash algorithm in RAM - """ - self.target.halt() - self.target.setTargetState("PROGRAM") - - # download flash algo in RAM - self.target.writeBlockMemoryAligned32(self.flash_algo['load_address'], self.flash_algo['instructions']) - - # update core register to execute the init subroutine - self.updateCoreRegister(0, 0, 0, 0, self.flash_algo['pc_init']) - # resume and wait until the breakpoint is hit - self.target.resume() - while(self.target.getState() == TARGET_RUNNING): - pass - - return - - def eraseAll(self): - """ - Erase all the flash - """ - - # update core register to execute the eraseAll subroutine - self.updateCoreRegister(0, 0, 0, 0, self.flash_algo['pc_eraseAll']) - - # resume and wait until the breakpoint is hit - self.target.resume() - while(self.target.getState() == TARGET_RUNNING): - pass - - return - - def programPage(self, flashPtr, bytes): - """ - Flash one page - """ - # first transfer in RAM - self.target.writeBlockMemoryUnaligned8(self.begin_data, bytes) - - # update core register to execute the program_page subroutine - self.updateCoreRegister(flashPtr, self.page_size, self.begin_data, 0, self.flash_algo['pc_program_page']) - - # resume and wait until the breakpoint is hit - self.target.resume() - while(self.target.getState() == TARGET_RUNNING): - pass - return - - def flashBinary(self, path_file): - """ - Flash a binary - """ - f = open(path_file, "rb") - - start = time() - self.init() - logging.debug("flash init OK: pc: 0x%X", self.target.readCoreRegister('pc')) - self.eraseAll() - logging.debug("eraseAll OK: pc: 0x%X", self.target.readCoreRegister('pc')) - - """ - bin = open(os.path.join(parentdir, 'res', 'good_bin.txt'), "w+") - """ - - flashPtr = 0 - nb_bytes = 0 - try: - bytes_read = f.read(1024) - while bytes_read: - bytes_read = unpack(str(len(bytes_read)) + 'B', bytes_read) - nb_bytes += len(bytes_read) - # page download - self.programPage(flashPtr, bytes_read) - """ - i = 0 - while (i < len(bytes_read)): - bin.write(str(list(bytes_read[i:i+16])) + "\n") - i += 16 - """ - flashPtr += 1024 - - bytes_read = f.read(1024) - finally: - f.close() - """ - bin.close() - """ - end = time() - logging.info("%f kbytes flashed in %f seconds ===> %f kbytes/s" %(nb_bytes/1000, end-start, nb_bytes/(1000*(end - start)))) - - def updateCoreRegister(self, r0, r1, r2, r3, pc): - self.target.writeCoreRegister('pc', pc) - self.target.writeCoreRegister('r0', r0) - self.target.writeCoreRegister('r1', r1) - self.target.writeCoreRegister('r2', r2) - self.target.writeCoreRegister('r3', r3) - self.target.writeCoreRegister('r9', self.static_base) - self.target.writeCoreRegister('sp', self.begin_stack) - self.target.writeCoreRegister('lr', self.flash_algo['load_address'] + 1) - return - \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/flash/flash_kl25z.py b/workspace_tools/debugger/pyOCD/flash/flash_kl25z.py deleted file mode 100644 index 805fa544b3..0000000000 --- a/workspace_tools/debugger/pyOCD/flash/flash_kl25z.py +++ /dev/null @@ -1,92 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from flash import Flash - -flash_algo = { 'load_address' : 0x20000000, - 'instructions' : [ - 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, - 0xb510492f, 0x60084449, 0x2100482e, 0x482f6001, 0x44484a2d, 0x22016002, 0x04926041, 0x02926082, - 0x220560c2, 0x61420692, 0x03122201, 0x46026182, 0x70113220, 0x62411e49, 0xf929f000, 0xd0002800, - 0xbd102001, 0x47702000, 0xb5084a21, 0x0349447a, 0x0c0a9200, 0x481d4601, 0x44482300, 0xf9b7f000, - 0xd0002800, 0xbd082001, 0x4919b510, 0x48174479, 0x44483920, 0xf891f000, 0xd0002800, 0xbd102001, - 0x4b13b510, 0x4601447b, 0x22014810, 0x02923b38, 0xf0004448, 0x2800f8b4, 0x2001d000, 0xb538bd10, - 0x490b460c, 0x39584479, 0x46019100, 0x46134807, 0x44484622, 0xf948f000, 0xd0002800, 0xbd382001, - 0x00000004, 0x40048100, 0x40020000, 0x00000008, 0x00000085, 0x4604b570, 0x25006800, 0x061b7803, - 0x2370d5fc, 0x20007003, 0x0003e03a, 0xfa60f000, 0x0f0b070c, 0x1f1b1713, 0x2f2b2723, 0x68263633, - 0x71f37813, 0x6826e02a, 0x71b37853, 0x6826e026, 0x71737893, 0x6826e022, 0x713378d3, 0x6826e01e, - 0x72f37913, 0x6826e01a, 0x72b37953, 0x6826e016, 0x72737993, 0x6826e012, 0x723379d3, 0x6826e00e, - 0x73f37a13, 0x6826e00a, 0x73b37a53, 0x6826e006, 0x73737a93, 0x6826e002, 0x73337ad3, 0xb2c01c40, - 0xd9c24288, 0x20806821, 0xe0037008, 0x1c416a60, 0x4780d000, 0x78006820, 0xd5f70600, 0x78006820, - 0xd5010681, 0xe0062504, 0xd50106c1, 0xe0022508, 0xd00007c0, 0x46282510, 0xb508bd70, 0x2244460b, - 0x700a4669, 0x2100466a, 0xbd084798, 0x4614b538, 0xd002078a, 0x300120ff, 0x6843bd38, 0xd803428b, - 0x189a6882, 0xd80d428a, 0x428a68c2, 0x6903d803, 0x428b18d3, 0x2002d801, 0x1a89bd38, 0x05d22201, - 0xe0001889, 0x22081ac9, 0x701a466b, 0x705a0c0a, 0x709a0a0a, 0x466a70d9, 0x47a02103, 0xb5ffbd38, - 0x4615b081, 0x27019a01, 0x26006852, 0x02bf1948, 0xd804428a, 0x689b9b01, 0x428318d3, 0x9a01d20f, - 0x428a68d2, 0x9b01d804, 0x18d3691b, 0xd2014283, 0xe0292602, 0x21011a88, 0x184405c9, 0x1a8ce000, - 0x46204639, 0xf907f000, 0xd0022900, 0x360126ff, 0x4639e01a, 0xf0004628, 0x2900f8fe, 0x2601d012, - 0x2009e012, 0x70084669, 0x70480c20, 0x70880a20, 0x9b0470cc, 0x2103466a, 0x47989801, 0xd1030006, - 0x19e41bed, 0xd1ec2d00, 0xb0054630, 0xb5f0bdf0, 0x24006801, 0x0612780a, 0x2270d5fc, 0x6802700a, - 0x71d12103, 0x22806801, 0x6803718a, 0x71592100, 0x23fc6805, 0x6803712b, 0x680373d9, 0x6802701a, - 0x061b7813, 0x7a55d5fc, 0x07177a12, 0x0f3f2201, 0x105603d2, 0xf000003b, 0x0910f96b, 0x09100e0b, - 0x10090909, 0x09090e1f, 0x11090909, 0xe0056102, 0x03522203, 0x6106e7fa, 0x6101e000, 0x0f12072a, - 0xf0000013, 0x0c10f955, 0x120f0c0c, 0x1d1b1815, 0x0c0c0c1f, 0x0d0c0c0c, 0x03522201, 0x61c1e7e6, - 0xbdf04620, 0x02c92101, 0x2101e7f9, 0xe7f60289, 0x02492101, 0x21ffe7f3, 0xe7f03101, 0xe7ee2180, - 0xe7ec2140, 0xe7ea2120, 0x4607b5fe, 0x461d4616, 0x198a2000, 0xd002078b, 0x300120ff, 0x07b3bdfe, - 0x2001d001, 0x687bbdfe, 0xd803428b, 0x191c68bc, 0xd20d4294, 0x428b68fb, 0x693cd803, 0x4294191c, - 0x2002d201, 0x2201bdfe, 0x05d21ac9, 0xe01b188c, 0xe0191acc, 0x46692006, 0x0c207008, 0x0a207048, - 0x70cc7088, 0x710878e8, 0x714878a8, 0x71887868, 0x71c87828, 0x466a9b08, 0x46382107, 0x28004798, - 0x1d24d1e0, 0x1d2d1f36, 0xd1e32e00, 0xb5febdfe, 0x46044615, 0x00a86842, 0x461e1840, 0xd803428a, - 0x18d368a3, 0xd808428b, 0x428b68e3, 0x6927d803, 0x428b19db, 0x2002d801, 0x4282bdfe, 0x68a3d805, - 0x428318d3, 0x1a8fd301, 0x68e2e00a, 0xd9034282, 0x18d36923, 0xd3ee4283, 0x21011a88, 0x184705c9, - 0x46382104, 0xf817f000, 0xd0022900, 0x300120ff, 0x2001bdfe, 0x70084669, 0x70480c38, 0x70880a38, - 0x0a2870cf, 0x714d7108, 0x9b08718e, 0x2106466a, 0x47984620, 0x2200bdfe, 0x428b0903, 0x0a03d32c, - 0xd311428b, 0x469c2300, 0x4603e04e, 0xd43c430b, 0x08432200, 0xd331428b, 0x428b0903, 0x0a03d31c, - 0xd301428b, 0xe03f4694, 0x428b09c3, 0x01cbd301, 0x41521ac0, 0x428b0983, 0x018bd301, 0x41521ac0, - 0x428b0943, 0x014bd301, 0x41521ac0, 0x428b0903, 0x010bd301, 0x41521ac0, 0x428b08c3, 0x00cbd301, - 0x41521ac0, 0x428b0883, 0x008bd301, 0x41521ac0, 0x428b0843, 0x004bd301, 0x41521ac0, 0xd2001a41, - 0x41524601, 0x47704610, 0x0fcae05d, 0x4249d000, 0xd3001003, 0x40534240, 0x469c2200, 0x428b0903, - 0x0a03d32d, 0xd312428b, 0x018922fc, 0x0a03ba12, 0xd30c428b, 0x11920189, 0xd308428b, 0x11920189, - 0xd304428b, 0xd03a0189, 0xe0001192, 0x09c30989, 0xd301428b, 0x1ac001cb, 0x09834152, 0xd301428b, - 0x1ac0018b, 0x09434152, 0xd301428b, 0x1ac0014b, 0x09034152, 0xd301428b, 0x1ac0010b, 0x08c34152, - 0xd301428b, 0x1ac000cb, 0x08834152, 0xd301428b, 0x1ac0008b, 0xd2d94152, 0x428b0843, 0x004bd301, - 0x41521ac0, 0xd2001a41, 0x46634601, 0x105b4152, 0xd3014610, 0x2b004240, 0x4249d500, 0x46634770, - 0xd300105b, 0xb5014240, 0x46c02000, 0xbd0246c0, 0x4674b430, 0x78251e64, 0x42ab1c64, 0x461dd200, - 0x005b5d63, 0xbc3018e3, 0x00004718, 0xfffffffe - ], - 'pc_init' : 0x20000020, - 'pc_eraseAll' : 0x20000088, - 'pc_program_page' : 0x200000be, - 'begin_stack' : 0x20001000, - 'begin_data' : 0x20002000, - 'static_base' : 0x200005ec, - 'page_size' : 1024 - }; - -memoryMapXML = "" \ - "" \ - "" \ - " 0x400" \ - " " \ - "" - - -class Flash_kl25z(Flash): - - def __init__(self, target): - Flash.__init__(self, target, flash_algo, memoryMapXML) - \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/flash/flash_lpc11u24.py b/workspace_tools/debugger/pyOCD/flash/flash_lpc11u24.py deleted file mode 100644 index 5d056c0892..0000000000 --- a/workspace_tools/debugger/pyOCD/flash/flash_lpc11u24.py +++ /dev/null @@ -1,57 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from flash import Flash - -flash_algo = { 'load_address' : 0x10000000, - 'instructions' : [ - 0xe00abe00, 0x062d780d, 0x24084068, 0xd3000040, 0x1e644058, 0x1c49d1fa, 0x2a001e52, 0x4770d1f2, - 0x7803e005, 0x42931c40, 0x2001d001, 0x1e494770, 0x2000d2f7, 0x00004770, 0x47700b00, 0x484e494f, - 0x60084449, 0x2100484e, 0x22016301, 0x63416342, 0x6b416342, 0xd0fc07c9, 0x49496382, 0x39402002, - 0x20007008, 0x20004770, 0xb5f84770, 0x20324c45, 0x2500444c, 0x46222607, 0x4621c261, 0x4f423114, - 0x91004620, 0x696047b8, 0xd10c2800, 0x46212034, 0x483ac161, 0x68004448, 0x462060e0, 0x47b89900, - 0x28006960, 0x2001d000, 0xb5f8bdf8, 0x0b044d35, 0x2032444d, 0x4629606c, 0x311460ac, 0x4e326028, - 0x4628460f, 0x696847b0, 0xd10d2800, 0x2034606c, 0x602860ac, 0x46394829, 0x68004448, 0x462860e8, - 0x696847b0, 0xd0002800, 0xbdf82001, 0x0006b5f8, 0xd11e4614, 0x0180200b, 0x6bc11820, 0x42814823, - 0x4823d038, 0xd0354281, 0x42814822, 0x4822d032, 0xd02f4281, 0x68206861, 0x184068e2, 0x188968a1, - 0x69211840, 0x69611840, 0x69a11840, 0x42401840, 0x4d1461e0, 0x444d0b30, 0x60682132, 0x60a86029, - 0x31144629, 0x46284f10, 0x47b89100, 0x28006968, 0x606ed110, 0x60ac2033, 0x20016028, 0x60e80280, - 0x44484806, 0x61286800, 0x99004628, 0x696847b8, 0xd0002800, 0xbdf82001, 0x00002ee0, 0x00000004, - 0x40048040, 0x00000008, 0x1fff1ff1, 0x4e697370, 0x12345678, 0x87654321, 0x43218765, 0x00000000, - 0x00000000 - ], - 'pc_init' : 0x1000003d, - 'pc_eraseAll' : 0x1000006b, - 'pc_program_page' : 0x100000ed, - 'begin_data' : 0x100001c4, - 'begin_stack' : 0x10001000, - 'static_base' : 0x1000019c, - 'page_size' : 1024 - }; - -memoryMapXML = "" \ - "" \ - "" \ - " 0x400" \ - " " \ - "" - - -class Flash_lpc11u24(Flash): - - def __init__(self, target): - Flash.__init__(self, target, flash_algo, memoryMapXML) \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/flash/flash_lpc1768.py b/workspace_tools/debugger/pyOCD/flash/flash_lpc1768.py deleted file mode 100644 index e48738f3ac..0000000000 --- a/workspace_tools/debugger/pyOCD/flash/flash_lpc1768.py +++ /dev/null @@ -1,61 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from flash import Flash - -flash_algo = { 'load_address' : 0x10000000, - 'instructions' : [ - 0xe00abe00, 0x062d780d, 0x24084068, 0xd3000040, 0x1e644058, 0x1c49d1fa, 0x2a001e52, 0x4770d1f2, - 0x7803e005, 0x42931c40, 0x2001d001, 0x1e494770, 0x2000d2f7, 0x00004770, 0x28100b00, 0x210ed302, - 0x00d0eb01, 0x486c4770, 0x7801b510, 0x0102f021, 0x22aa7001, 0x23557302, 0x78017303, 0x0101f021, - 0x73027001, 0xf8d07303, 0xf0411120, 0xf8c00120, 0xf1a01120, 0xf8d00080, 0x064911a0, 0xf100d5fb, - 0x24010080, 0x408cf880, 0x0113f04f, 0x73026041, 0x78017303, 0x0101f041, 0x73027001, 0xf1a07303, - 0xf8d00080, 0x01491088, 0xf100d5fb, 0x2107006d, 0x1097f880, 0x0109f04f, 0x109bf880, 0xf0417cc1, - 0x74c10102, 0x77c377c2, 0x4c2df800, 0xf64e494b, 0x44492060, 0xf04f6008, 0xbd100000, 0x47702000, - 0x41f0e92d, 0x20324c46, 0x2500444c, 0xe884271d, 0xf10400a1, 0x4e430114, 0x46204688, 0x696047b0, - 0x2034b960, 0x00a1e884, 0x4641483c, 0x68004448, 0x462060e0, 0x696047b0, 0xd0002800, 0xe8bd2001, - 0xe92d81f0, 0xf7ff41f0, 0x4d35ff87, 0x444d4604, 0xe9c52032, 0xf1050400, 0x4e320114, 0x4628460f, - 0x47b060ac, 0xb9686968, 0xe9c52034, 0x482b0400, 0x444860ac, 0x68004639, 0x462860e8, 0x696847b0, - 0xd0dc2800, 0xe7da2001, 0x41f0e92d, 0x46140006, 0x4925d11d, 0x02fcf8d4, 0xd03a4288, 0x42884923, - 0x4923d037, 0xd0344288, 0x4131ea4f, 0xd0304288, 0x0100e9d4, 0xe9d44408, 0x44111202, 0x69214408, - 0x69614408, 0x69a14408, 0x42404408, 0x463061e0, 0xff42f7ff, 0x21324d12, 0x4f12444d, 0x1000e9c5, - 0x0114f105, 0x468860a8, 0x47b84628, 0xb9806968, 0xe9c52033, 0xf44f0600, 0xe9c56080, 0x48074002, - 0x44484641, 0x61286800, 0x47b84628, 0x28006968, 0x2001d095, 0x0000e793, 0x400fc080, 0x00000004, - 0x00000008, 0x1fff1ff1, 0x4e697370, 0x12345678, 0x87654321, 0x00000000, 0x00000000 - ], - 'pc_init' : 0x10000047, - 'pc_eraseAll' : 0x100000e1, - 'pc_program_page' : 0x10000169, - 'begin_data' : 0x1000023c, - 'begin_stack' : 0x10001000, - 'static_base' : 0x10000214, - 'page_size' : 1024 - }; - -memoryMapXML = "" \ - "" \ - "" \ - " 0x400" \ - " " \ - " " \ - "" - - -class Flash_lpc1768(Flash): - - def __init__(self, target): - Flash.__init__(self, target, flash_algo, memoryMapXML) \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/flash/flash_lpc800.py b/workspace_tools/debugger/pyOCD/flash/flash_lpc800.py deleted file mode 100644 index 40da42a7c4..0000000000 --- a/workspace_tools/debugger/pyOCD/flash/flash_lpc800.py +++ /dev/null @@ -1,56 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from flash import Flash - -flash_algo = { 'load_address' : 0x10000000, - 'instructions' : [ - 0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2, - 0x47700a80, 0x484e494f, 0x60084449, 0x2100484e, 0x22016301, 0x63416342, 0x6b416342, 0xd0fc07c9, - 0x49496382, 0x39402002, 0x20007008, 0x20004770, 0xb5f84770, 0x20324c45, 0x2500444c, 0x4622260f, - 0x4621c261, 0x4f423114, 0x91004620, 0x696047b8, 0xd10c2800, 0x46212034, 0x483ac161, 0x68004448, - 0x462060e0, 0x47b89900, 0x28006960, 0x2001d000, 0xb5f8bdf8, 0x0a844d35, 0x2032444d, 0x4629606c, - 0x311460ac, 0x4e326028, 0x4628460f, 0x696847b0, 0xd10d2800, 0x2034606c, 0x602860ac, 0x46394829, - 0x68004448, 0x462860e8, 0x696847b0, 0xd0002800, 0xbdf82001, 0x4614b5f8, 0xd11e0006, 0x0180200b, - 0x6bc11820, 0x42814823, 0x4823d038, 0xd0354281, 0x42814822, 0x4822d032, 0xd02f4281, 0x68206861, - 0x184068e2, 0x188968a1, 0x69211840, 0x69611840, 0x69a11840, 0x42401840, 0x4d1461e0, 0x444d0ab0, - 0x60682132, 0x60a86029, 0x31144629, 0x46284f10, 0x47b89100, 0x28006968, 0x606ed110, 0x60ac2033, - 0x20016028, 0x60e80280, 0x44484806, 0x61286800, 0x99004628, 0x696847b8, 0xd0002800, 0xbdf82001, - 0x00002ee0, 0x00000004, 0x40048040, 0x00000008, 0x1fff1ff1, 0x4e697370, 0x12345678, 0x87654321, - 0x43218765 - ], - 'pc_init' : 0x10000024, - 'pc_eraseAll' : 0x10000052, - 'pc_program_page' : 0x100000d4, - 'begin_data' : 0x10000400, - 'begin_stack' : 0x10001000, - 'static_base' : 0x10000300, - 'page_size' : 1024 - }; - -memoryMapXML = "" \ - "" \ - "" \ - " 0x400" \ - " " \ - "" - - -class Flash_lpc800(Flash): - - def __init__(self, target): - Flash.__init__(self, target, flash_algo, memoryMapXML) \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/gdbserver/__init__.py b/workspace_tools/debugger/pyOCD/gdbserver/__init__.py deleted file mode 100644 index 9c54e524f0..0000000000 --- a/workspace_tools/debugger/pyOCD/gdbserver/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from gdbserver import GDBServer \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/gdbserver/gdb_socket.py b/workspace_tools/debugger/pyOCD/gdbserver/gdb_socket.py deleted file mode 100644 index 1ed4a6d34e..0000000000 --- a/workspace_tools/debugger/pyOCD/gdbserver/gdb_socket.py +++ /dev/null @@ -1,55 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import socket, select - -class GDBSocket(): - def __init__(self, port, packet_size): - self.packet_size = packet_size - self.s = None - self.conn = None - self.port = port - return - - def init(self): - self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - self.s.bind(('', self.port)) - self.s.listen(5) - - def connect(self): - self.conn = None - self.init() - rr,_,_ = select.select([self.s],[],[], 0.5) - if rr: - self.conn, _ = self.s.accept() - - return self.conn - - def read(self): - return self.conn.recv(self.packet_size) - - def write(self, data): - return self.conn.send(data) - - def close(self): - if self.conn != None: - self.conn.close() - return self.s.close() - - def setBlocking(self, blocking): - return self.conn.setblocking(blocking) \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/gdbserver/gdb_websocket.py b/workspace_tools/debugger/pyOCD/gdbserver/gdb_websocket.py deleted file mode 100644 index f6ec479972..0000000000 --- a/workspace_tools/debugger/pyOCD/gdbserver/gdb_websocket.py +++ /dev/null @@ -1,51 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -try: - from websocket import create_connection -except: - pass - -class GDBWebSocket(): - def __init__(self, url): - self.url = url - self.wss = None - return - - def connect(self): - self.wss = None - try: - self.wss = create_connection(self.url) - except: - pass - return self.wss - - def read(self): - return self.wss.recv() - - def write(self, data): - return self.wss.send(data) - - def close(self): - return self.wss.close() - - def setBlocking(self, blocking): - if blocking != 0: - self.wss.settimeout(None) - else: - self.wss.settimeout(0) - \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/gdbserver/gdbserver.py b/workspace_tools/debugger/pyOCD/gdbserver/gdbserver.py deleted file mode 100644 index e17947be9c..0000000000 --- a/workspace_tools/debugger/pyOCD/gdbserver/gdbserver.py +++ /dev/null @@ -1,594 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import logging, threading, socket -from pyOCD.target.cortex_m import CORE_REGISTER -from pyOCD.target.target import TARGET_HALTED -from struct import unpack -from time import sleep -import sys -from gdb_socket import GDBSocket -from gdb_websocket import GDBWebSocket - -""" -import os -parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -sys.path.insert(0,parentdir) -""" - -SIGINT = (2) -SIGSEGV = (11) -SIGILL = (4) -SIGSTOP = (17) -SIGTRAP = (5) -SIGBUS = (10) - -FAULT = {0: "17", #SIGSTOP - 1: "17", - 2: "02", #SIGINT - 3: "11", #SIGSEGV - 4: "11", - 5: "10", #SIGBUS - 6: "04", #SIGILL - 7: "17", - 8: "17", - 9: "17", - 10: "17", - 11: "17", - 12: "17", - 13: "17", - 14: "17", - 15: "17", - } - -class GDBServer(threading.Thread): - """ - This class start a GDB server listening a gdb connection on a specific port. - It implements the RSP (Remote Serial Protocol). - """ - def __init__(self, board, port_urlWSS): - threading.Thread.__init__(self) - self.board = board - self.target = board.target - self.flash = board.flash - self.abstract_socket = None - self.wss_server = None - self.port = 0 - if isinstance(port_urlWSS, str) == True: - self.wss_server = port_urlWSS - else: - self.port = port_urlWSS - self.packet_size = 2048 - self.flashData = "" - self.conn = None - self.lock = threading.Lock() - self.shutdown_event = threading.Event() - self.detach_event = threading.Event() - self.quit = False - if self.wss_server == None: - self.abstract_socket = GDBSocket(self.port, self.packet_size) - else: - self.abstract_socket = GDBWebSocket(self.wss_server) - self.start() - - def restart(self): - if self.isAlive(): - self.detach_event.set() - - def stop(self): - if self.isAlive(): - self.shutdown_event.set() - while self.isAlive(): - pass - logging.info("GDB server thread killed") - self.board.uninit() - - def setBoard(self, board, stop = True): - self.lock.acquire() - if stop: - self.restart() - self.board = board - self.target = board.target - self.flash = board.flash - self.lock.release() - return - - def run(self): - while True: - new_command = False - data = [] - logging.info('GDB server started') - - self.shutdown_event.clear() - self.detach_event.clear() - - while not self.shutdown_event.isSet() and not self.detach_event.isSet(): - connected = self.abstract_socket.connect() - if connected != None: - break - - if self.shutdown_event.isSet(): - return - - if self.detach_event.isSet(): - continue - - logging.info("One client connected!") - - while True: - - if self.shutdown_event.isSet(): - return - - if self.detach_event.isSet(): - continue - - # read command - while True: - if (new_command == True): - new_command = False - break - try: - if self.shutdown_event.isSet() or self.detach_event.isSet(): - break - self.abstract_socket.setBlocking(0) - data = self.abstract_socket.read() - if data.index("$") >= 0 and data.index("#") >= 0: - break - except (ValueError, socket.error): - pass - - if self.shutdown_event.isSet(): - return - - if self.detach_event.isSet(): - continue - - self.abstract_socket.setBlocking(1) - - data = data[data.index("$"):] - - self.lock.acquire() - - if len(data) != 0: - # decode and prepare resp - [resp, ack, detach] = self.handleMsg(data) - - if resp is not None: - # ack - if ack: - resp = "+" + resp - # send resp - self.abstract_socket.write(resp) - # wait a '+' from the client - try: - data = self.abstract_socket.read() - if data[0] != '+': - logging.debug('gdb client has not ack!') - else: - logging.debug('gdb client has ack!') - if data.index("$") >= 0 and data.index("#") >= 0: - new_command = True - except: - pass - - if detach: - self.abstract_socket.close() - self.lock.release() - break - - self.lock.release() - - - def handleMsg(self, msg): - - if msg[0] != '$': - logging.debug('msg ignored: first char != $') - return None, 0, 0 - - #logging.debug('-->>>>>>>>>>>> GDB rsp packet: %s', msg) - - # query command - if msg[1] == 'q': - return self.handleQuery(msg[2:]), 1, 0 - - elif msg[1] == 'H': - return self.createRSPPacket(''), 1, 0 - - elif msg[1] == '?': - return self.lastSignal(), 1, 0 - - elif msg[1] == 'g': - return self.getRegister(), 1, 0 - - elif msg[1] == 'p': - return self.readRegister(msg[2:]), 1, 0 - - elif msg[1] == 'P': - return self.writeRegister(msg[2:]), 1, 0 - - elif msg[1] == 'm': - return self.getMemory(msg[2:]), 1, 0 - - elif msg[1] == 'X': - return self.writeMemory(msg[2:]), 1, 0 - - elif msg[1] == 'v': - return self.flashOp(msg[2:]), 1, 0 - - # we don't send immediately the response for C and S commands - elif msg[1] == 'C' or msg[1] == 'c': - return self.resume() - - elif msg[1] == 'S' or msg[1] == 's': - return self.step() - - elif msg[1] == 'Z' or msg[1] == 'z': - return self.breakpoint(msg[1:]), 1, 0 - - elif msg[1] == 'D': - return self.detach(msg[1:]), 1, 1 - - elif msg[1] == 'k': - return self.kill(), 1, 1 - - else: - logging.error("Unknown RSP packet: %s", msg) - return None - - def detach(self, data): - resp = "OK" - return self.createRSPPacket(resp) - - def kill(self): - return self.createRSPPacket("") - - def breakpoint(self, data): - # handle Z1/z1 commands - addr = int(data.split(',')[1], 16) - if data[1] == '1': - if data[0] == 'Z': - if self.target.setBreakpoint(addr) == False: - resp = "ENN" - return self.createRSPPacket(resp) - else: - self.target.removeBreakpoint(addr) - resp = "OK" - return self.createRSPPacket(resp) - - return None - - def resume(self): - self.ack() - self.target.resume() - self.abstract_socket.setBlocking(0) - - val = '' - - while True: - sleep(0.01) - - try: - data = self.abstract_socket.read() - if (data[0] == '\x03'): - self.target.halt() - val = 'S05' - logging.debug("receive CTRL-C") - break - except: - pass - - if self.target.getState() == TARGET_HALTED: - logging.debug("state halted") - val = 'S05' - break - - self.target.halt() - ipsr = self.target.readCoreRegister('xpsr') - logging.debug("GDB resume xpsr: 0x%X", ipsr) - if (ipsr & 0x1f) == 3: - val = "S" + FAULT[3] - break - self.target.resume() - - self.abstract_socket.setBlocking(1) - return self.createRSPPacket(val), 0, 0 - - def step(self): - self.ack() - self.target.step() - return self.createRSPPacket("S05"), 0, 0 - - def halt(self): - self.ack() - self.target.halt() - return self.createRSPPacket("S05"), 0, 0 - - def flashOp(self, data): - ops = data.split(':')[0] - #logging.debug("flash op: %s", ops) - - if ops == 'FlashErase': - self.flash.init() - self.flash.eraseAll() - return self.createRSPPacket("OK") - - elif ops == 'FlashWrite': - logging.debug("flash write addr: 0x%s", data.split(':')[1]) - # search for second ':' (beginning of data encoded in the message) - second_colon = 0 - idx_begin = 0 - while second_colon != 2: - if data[idx_begin] == ':': - second_colon += 1 - idx_begin += 1 - - self.flashData += data[idx_begin:len(data) - 3] - return self.createRSPPacket("OK") - - # we need to flash everything - elif 'FlashDone' in ops : - flashPtr = 0 - - unescaped_data = self.unescape(self.flashData) - - bytes_to_be_written = len(unescaped_data) - - """ - bin = open(os.path.join(parentdir, 'res', 'bad_bin.txt'), "w+") - - i = 0 - while (i < bytes_to_be_written): - bin.write(str(unescaped_data[i:i+16]) + "\n") - i += 16 - """ - - - logging.info("flashing %d bytes", bytes_to_be_written) - - while len(unescaped_data) > 0: - size_to_write = min(self.flash.page_size, len(unescaped_data)) - self.flash.programPage(flashPtr, unescaped_data[:size_to_write]) - flashPtr += size_to_write - - unescaped_data = unescaped_data[size_to_write:] - - # print progress bar - sys.stdout.write('\r') - i = int((float(flashPtr)/float(bytes_to_be_written))*20.0) - # the exact output you're looking for: - sys.stdout.write("[%-20s] %d%%" % ('='*i, 5*i)) - sys.stdout.flush() - - sys.stdout.write("\n\r") - - self.flashData = "" - - """ - bin.close() - """ - - # reset and stop on reset handler - self.target.resetStopOnReset() - - return self.createRSPPacket("OK") - - elif 'Cont' in ops: - if 'Cont?' in ops: - return self.createRSPPacket("vCont;c;s;t") - - return None - - def unescape(self, data): - data_idx = 0 - - # unpack the data into binary array - str_unpack = str(len(data)) + 'B' - data = unpack(str_unpack, data) - data = list(data) - - # check for escaped characters - while data_idx < len(data): - if data[data_idx] == 0x7d: - data.pop(data_idx) - data[data_idx] = data[data_idx] ^ 0x20 - data_idx += 1 - - return data - - - def getMemory(self, data): - split = data.split(',') - addr = int(split[0], 16) - length = split[1] - length = int(length[:len(length)-3],16) - - val = '' - - mem = self.target.readBlockMemoryUnaligned8(addr, length) - for x in mem: - if x >= 0x10: - val += hex(x)[2:4] - else: - val += '0' + hex(x)[2:3] - - return self.createRSPPacket(val) - - def writeMemory(self, data): - split = data.split(',') - addr = int(split[0], 16) - length = int(split[1].split(':')[0], 16) - - idx_begin = 0 - for i in range(len(data)): - if data[i] == ':': - idx_begin += 1 - break - idx_begin += 1 - - data = data[idx_begin:len(data) - 3] - data = self.unescape(data) - - if length > 0: - self.target.writeBlockMemoryUnaligned8(addr, data) - - return self.createRSPPacket("OK") - - def readRegister(self, data): - num = int(data.split('#')[0], 16) - reg = self.target.readCoreRegister(num) - logging.debug("GDB: read reg %d: 0x%X", num, reg) - val = self.intToHexGDB(reg) - return self.createRSPPacket(val) - - def writeRegister(self, data): - num = int(data.split('=')[0], 16) - val = data.split('=')[1].split('#')[0] - val = val[6:8] + val[4:6] + val[2:4] + val[0:2] - logging.debug("GDB: write reg %d: 0x%X", num, int(val, 16)) - self.target.writeCoreRegister(num, int(val, 16)) - return self.createRSPPacket("OK") - - def intToHexGDB(self, val): - val = hex(int(val))[2:] - size = len(val) - r = '' - for i in range(8-size): - r += '0' - r += str(val) - - resp = '' - for i in range(4): - resp += r[8 - 2*i - 2: 8 - 2*i] - - return resp - - def getRegister(self): - resp = '' - for i in range(len(CORE_REGISTER)): - reg = self.target.readCoreRegister(i) - resp += self.intToHexGDB(reg) - logging.debug("GDB reg: %s = 0x%X", i, reg) - return self.createRSPPacket(resp) - - def lastSignal(self): - fault = self.target.readCoreRegister('xpsr') & 0xff - fault = FAULT[fault] - logging.debug("GDB lastSignal: %s", fault) - return self.createRSPPacket('S' + fault) - - def handleQuery(self, msg): - query = msg.split(':') - logging.debug('GDB received query: %s', query) - - if query is None: - logging.error('GDB received query packet malformed') - return None - - if query[0] == 'Supported': - resp = "qXfer:memory-map:read+;qXfer:features:read+;PacketSize=" - resp += hex(self.packet_size)[2:] - return self.createRSPPacket(resp) - - elif query[0] == 'Xfer': - - if query[1] == 'features' and query[2] == 'read' and \ - query[3] == 'target.xml': - data = query[4].split(',') - resp = self.handleQueryXML('read_feature', int(data[0], 16), int(data[1].split('#')[0], 16)) - return self.createRSPPacket(resp) - - elif query[1] == 'memory-map' and query[2] == 'read': - data = query[4].split(',') - resp = self.handleQueryXML('momery_map', int(data[0], 16), int(data[1].split('#')[0], 16)) - return self.createRSPPacket(resp) - - else: - return None - - elif query[0] == 'C#b4': - return self.createRSPPacket("") - - elif query[0].find('Attached') != -1: - return self.createRSPPacket("1") - - elif query[0].find('TStatus') != -1: - return self.createRSPPacket("") - - elif query[0].find('Tf') != -1: - return self.createRSPPacket("") - - elif 'Offsets' in query[0]: - resp = "Text=0;Data=0;Bss=0" - return self.createRSPPacket(resp) - - elif 'Symbol' in query[0]: - resp = "OK" - return self.createRSPPacket(resp) - - else: - return None - - def handleQueryXML(self, query, offset, size): - logging.debug('GDB query %s: offset: %s, size: %s', query, offset, size) - xml = '' - if query == 'momery_map': - xml = self.flash.memoryMapXML - elif query == 'read_feature': - xml = self.target.targetXML - - size_xml = len(xml) - - prefix = 'm' - - if offset > size_xml: - logging.error('GDB: offset target.xml > size!') - return - - if size > (self.packet_size - 4): - size = self.packet_size - 4 - - nbBytesAvailable = size_xml - offset - - if size > nbBytesAvailable: - prefix = 'l' - size = nbBytesAvailable - - resp = prefix + xml[offset:offset + size] - - return resp - - - def createRSPPacket(self, data): - resp = '$' + data + '#' - - c = 0 - checksum = 0 - for c in data: - checksum += ord(c) - checksum = checksum % 256 - checksum = hex(checksum) - - if int(checksum[2:], 16) < 0x10: - resp += '0' - resp += checksum[2:] - - #logging.debug('--<<<<<<<<<<<< GDB rsp packet: %s', resp) - return resp - - def ack(self): - self.abstract_socket.write("+") \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/interface/__init__.py b/workspace_tools/debugger/pyOCD/interface/__init__.py deleted file mode 100644 index e093ce16a7..0000000000 --- a/workspace_tools/debugger/pyOCD/interface/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from pyusb_backend import PyUSB -from pywinusb_backend import PyWinUSB - -INTERFACE = {'pyusb': PyUSB, - 'pywinusb': PyWinUSB - } \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/interface/interface.py b/workspace_tools/debugger/pyOCD/interface/interface.py deleted file mode 100644 index d051bd31d9..0000000000 --- a/workspace_tools/debugger/pyOCD/interface/interface.py +++ /dev/null @@ -1,45 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -class Interface: - - def __init__(self): - self.vid = 0 - self.pid = 0 - self.vendor_name = "" - self.product_name = "" - return - - def init(self): - return - - def write(self, data): - return - - def read(self, size = -1, timeout = -1): - return - - def getInfo(self): - return self.vendor_name + " " + \ - self.product_name + " (" + \ - str(hex(self.vid)) + ", " + \ - str(hex(self.pid)) + ")" - - def close(self): - return - - \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/interface/pyusb_backend.py b/workspace_tools/debugger/pyOCD/interface/pyusb_backend.py deleted file mode 100644 index de7ca7bbf1..0000000000 --- a/workspace_tools/debugger/pyOCD/interface/pyusb_backend.py +++ /dev/null @@ -1,138 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from interface import Interface -import logging, os - -try: - import usb.core - import usb.util -except: - if os.name == "posix": - logging.error("PyUSB is required on a Linux Machine") - -class PyUSB(Interface): - """ - This class provides basic functions to access - a USB HID device using pyusb: - - write/read an endpoint - """ - - vid = 0 - pid = 0 - - def __init__(self): - self.ep_out = None - self.ep_in = None - self.dev = None - - @staticmethod - def getAllConnectedInterface(vid, pid): - """ - returns all the connected devices which matches PyUSB.vid/PyUSB.pid. - returns an array of PyUSB (Interface) objects - """ - # find all devices matching the vid/pid specified - all_devices = usb.core.find(find_all=True, idVendor=vid, idProduct=pid) - - if all_devices is None: - logging.debug("No device connected") - return None - - boards = [] - - # iterate on all devices found - for board in all_devices: - intf_number = 0 - found = False - - # get active config - config = board.get_active_configuration() - - # iterate on all interfaces: - # - if we found a HID interface -> CMSIS-DAP - for interface in config: - if interface.bInterfaceClass == 0x03: - intf_number = interface.bInterfaceNumber - found = True - break - - if found == False: - continue - - try: - if board.is_kernel_driver_active(intf_number) is True: - board.detach_kernel_driver(intf_number) - except Exception as e: - print e - pass - - intf = usb.util.find_descriptor(config, bInterfaceNumber = intf_number) - ep_out = usb.util.find_descriptor(intf, - # match the first OUT endpoint - custom_match = \ - lambda e: \ - usb.util.endpoint_direction(e.bEndpointAddress) == \ - usb.util.ENDPOINT_OUT - ) - ep_in = usb.util.find_descriptor(intf, - # match the first IN endpoint - custom_match = \ - lambda e: \ - usb.util.endpoint_direction(e.bEndpointAddress) == \ - usb.util.ENDPOINT_IN - ) - product_name = usb.util.get_string(board, 256, 2) - vendor_name = usb.util.get_string(board, 256, 1) - if ep_out is None or ep_in is None: - logging.error('Endpoints not found') - return None - - new_board = PyUSB() - new_board.ep_in = ep_in - new_board.ep_out = ep_out - new_board.dev = board - new_board.vid = vid - new_board.pid = pid - new_board.product_name = product_name - new_board.vendor_name = vendor_name - boards.append(new_board) - - return boards - - def write(self, data): - """ - write data on the OUT endpoint associated to the HID interface - """ - if self.ep_out is None: - raise ValueError('EP_OUT endpoint is NULL') - - self.ep_out.write(data) - #logging.debug('sent: %s', data) - return - - - def read(self, timeout = -1): - """ - read data on the IN endpoint associated to the HID interface - """ - if self.ep_in is None: - raise ValueError('EP_IN endpoint is NULL') - - data = self.ep_in.read(self.ep_in.wMaxPacketSize, timeout) - #logging.debug('received: %s', data) - return data diff --git a/workspace_tools/debugger/pyOCD/interface/pywinusb_backend.py b/workspace_tools/debugger/pyOCD/interface/pywinusb_backend.py deleted file mode 100644 index 90689039dd..0000000000 --- a/workspace_tools/debugger/pyOCD/interface/pywinusb_backend.py +++ /dev/null @@ -1,116 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from interface import Interface -import logging, os - -try: - import pywinusb.hid as hid -except: - if os.name == "nt": - logging.error("PyWinUSB is required on a Windows Machine") - -class PyWinUSB(Interface): - """ - This class provides basic functions to access - a USB HID device using pywinusb: - - write/read an endpoint - """ - vid = 0 - pid = 0 - - def __init__(self): - # Vendor page and usage_id = 2 - self.report = [] - self.rcv_data = [] - self.device = None - return - - # handler called when a report is received - def rx_handler(self, data): - #logging.debug("rcv: %s", data[1:]) - self.rcv_data.append(data[1:]) - - def open(self): - self.device.set_raw_data_handler(self.rx_handler) - self.device.open() - - @staticmethod - def getAllConnectedInterface(vid, pid): - """ - returns all the connected devices which matches PyWinUSB.vid/PyWinUSB.pid. - returns an array of PyWinUSB (Interface) objects - """ - all_devices = hid.find_all_hid_devices() - - # find devices with good vid/pid - all_mbed_devices = [] - for d in all_devices: - if (d.vendor_id == vid) and (d.product_id == pid): - all_mbed_devices.append(d) - - if not all_mbed_devices: - logging.debug("No Mbed device connected") - return - - boards = [] - for dev in all_mbed_devices: - try: - dev.open() - report = dev.find_output_reports() - if (len(report) == 1): - new_board = PyWinUSB() - new_board.report = report[0] - new_board.vendor_name = dev.vendor_name - new_board.product_name = dev.product_name - new_board.vid = dev.vendor_id - new_board.pid = dev.product_id - new_board.device = dev - new_board.device.set_raw_data_handler(new_board.rx_handler) - - boards.append(new_board) - except Exception as e: - logging.error("Receiving Exception: %s", e) - dev.close() - - return boards - - def write(self, data): - """ - write data on the OUT endpoint associated to the HID interface - """ - for _ in range(64 - len(data)): - data.append(0) - #logging.debug("send: %s", data) - self.report.send([0] + data) - return - - - def read(self, timeout = -1): - """ - read data on the IN endpoint associated to the HID interface - """ - while len(self.rcv_data) == 0: - pass - return self.rcv_data.pop(0) - - def close(self): - """ - close the interface - """ - logging.debug("closing interface") - self.device.close() diff --git a/workspace_tools/debugger/pyOCD/target/__init__.py b/workspace_tools/debugger/pyOCD/target/__init__.py deleted file mode 100644 index 9f7fd9ecca..0000000000 --- a/workspace_tools/debugger/pyOCD/target/__init__.py +++ /dev/null @@ -1,29 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import cortex_m -import target_lpc1768 -import target_kl25z -import target_lpc11u24 -import target_lpc800 - -TARGET = {'cortex_m': cortex_m.CortexM, - 'target_lpc1768': target_lpc1768.LPC1768, - 'target_kl25z': target_kl25z.KL25Z, - 'target_lpc11u24': target_lpc11u24.LPC11U24, - 'target_lpc800': target_lpc800.LPC800, - } \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/target/cortex_m.py b/workspace_tools/debugger/pyOCD/target/cortex_m.py deleted file mode 100644 index 24606654b4..0000000000 --- a/workspace_tools/debugger/pyOCD/target/cortex_m.py +++ /dev/null @@ -1,554 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from pyOCD.target.target import Target -from pyOCD.target.target import TARGET_RUNNING, TARGET_HALTED -from pyOCD.transport.cmsis_dap import DP_REG -import logging - -# Debug Halting Control and Status Register -DHCSR = 0xE000EDF0 -# Debug Core Register Selector Register -DCRSR = 0xE000EDF4 -REGWnR = (1 << 16) -# Debug Core Register Data Register -DCRDR = 0xE000EDF8 -# Debug Exception and Monitor Control Register -DEMCR = 0xE000EDFC -TRACE_ENA = (1 << 24) -VC_HARDERR = (1 << 9) -VC_BUSERR = (1 << 8) -VC_CORERESET = (1 << 0) - -NVIC_AIRCR = (0xE000ED0C) -NVIC_AIRCR_VECTKEY = (0x5FA << 16) -NVIC_AIRCR_VECTRESET = (1 << 0) -NVIC_AIRCR_SYSRESETREQ = (1 << 2) - -CSYSPWRUPACK = 0x80000000 -CDBGPWRUPACK = 0x20000000 -CSYSPWRUPREQ = 0x40000000 -CDBGPWRUPREQ = 0x10000000 - -TRNNORMAL = 0x00000000 -MASKLANE = 0x00000f00 - -C_DEBUGEN = (1 << 0) -C_HALT = (1 << 1) -C_STEP = (1 << 2) -C_MASKINTS = (1 << 3) -C_SNAPSTALL = (1 << 4) -DBGKEY = (0xA05F << 16) - -# FPB (breakpoint) -FP_CTRL = (0xE0002000) -FP_CTRL_KEY = (1 << 1) -FP_COMP0 = (0xE0002008) - -CORE_REGISTER = {'r0': 0, - 'r1': 1, - 'r2': 2, - 'r3': 3, - 'r4': 4, - 'r5': 5, - 'r6': 6, - 'r7': 7, - 'r8': 8, - 'r9': 9, - 'r10': 10, - 'r11': 11, - 'r12': 12, - 'sp': 13, - 'lr': 14, - 'pc': 15, - 'xpsr': 16, - } - -targetXML = "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" \ - "\n" - -""" -convert a byte array into a word array -""" -def byte2word(data): - res = [] - for i in range(len(data)/4): - res.append(data[i*4 + 0] << 0 | - data[i*4 + 1] << 8 | - data[i*4 + 2] << 16 | - data[i*4 + 3] << 24) - return res - -""" -convert a word array into a byte array -""" -def word2byte(data): - res = [] - for x in data: - res.append((x >> 0) & 0xff) - res.append((x >> 8) & 0xff) - res.append((x >> 16) & 0xff) - res.append((x >> 24) & 0xff) - return res - - -class Breakpoint(): - def __init__(self, comp_register_addr): - self.comp_register_addr = comp_register_addr - self.enabled = False - self.addr = 0 - - -class CortexM(Target): - - """ - This class has basic functions to access a Cortex M core: - - init - - read/write memory - - read/write core registers - - set/remove hardware breakpoints - """ - - def __init__(self, transport): - self.transport = transport - self.auto_increment_page_size = 0 - self.idcode = 0 - self.breakpoints = [] - self.nb_code = 0 - self.num_breakpoint_used = 0 - self.nb_lit = 0 - self.fpb_enabled = False - self.targetXML = targetXML - return - - def init(self, setup_fpb = True): - """ - Cortex M initialization - """ - self.idcode = self.readIDCode() - # select bank 0 (to access DRW and TAR) - self.transport.writeDP(DP_REG['SELECT'], 0) - self.transport.writeDP(DP_REG['CTRL_STAT'], CSYSPWRUPREQ | CDBGPWRUPREQ) - - while True: - r = self.transport.readDP(DP_REG['CTRL_STAT']) - if (r & (CDBGPWRUPACK | CSYSPWRUPACK)) == (CDBGPWRUPACK | CSYSPWRUPACK): - break - - self.transport.writeDP(DP_REG['CTRL_STAT'], CSYSPWRUPREQ | CDBGPWRUPREQ | TRNNORMAL | MASKLANE) - self.transport.writeDP(DP_REG['SELECT'], 0) - - if setup_fpb: - self.halt() - self.setupFPB() - - return - - def setupFPB(self): - """ - Reads the number of hardware breakpoints available on the core - and disable the FPB (Flash Patch and Breakpoint Unit) - which will be enabled when a first breakpoint will be set - """ - # setup FPB (breakpoint) - fpcr = self.readMemory(FP_CTRL) - self.nb_code = ((fpcr >> 8) & 0x70) | ((fpcr >> 4) & 0xF) - logging.info("%d hardware breakpoints", self.nb_code) - for i in range(self.nb_code): - self.breakpoints.append(Breakpoint(FP_COMP0 + 4*i)) - - # disable FPB (will be enabled on first bp set) - self.disableFPB() - for bp in self.breakpoints: - self.writeMemory(bp.comp_register_addr, 0) - - def info(self, request): - return self.transport.info(request) - - def readIDCode(self): - """ - return the IDCODE of the core - """ - if self.idcode == 0: - self.idcode = self.transport.readDP(DP_REG['IDCODE']) - return self.idcode - - def writeMemory(self, addr, value, transfer_size = 32): - """ - write a memory location. - By default the transfer size is a word - """ - self.transport.writeMem(addr, value, transfer_size) - return - - def readMemory(self, addr, transfer_size = 32): - """ - read a memory location. By default, a word will - be read - """ - return self.transport.readMem(addr, transfer_size) - - def readBlockMemoryUnaligned8(self, addr, size): - """ - read a block of unaligned bytes in memory. Returns - an array of byte values - """ - res = [] - - # try to read 8bits data - if (size > 0) and (addr & 0x01): - mem = self.readMemory(addr, 8) - logging.debug("get 1 byte at %s: 0x%X", hex(addr), mem) - res.append(mem) - size -= 1 - addr += 1 - - # try to read 16bits data - if (size > 1) and (addr & 0x02): - mem = self.readMemory(addr, 16) - logging.debug("get 2 bytes at %s: 0x%X", hex(addr), mem) - res.append(mem & 0xff) - res.append((mem >> 8) & 0xff) - size -= 2 - addr += 2 - - # try to read aligned block of 32bits - if (size >= 4): - logging.debug("read blocks aligned at 0x%X, size: 0x%X", addr, (size/4)*4) - mem = self.readBlockMemoryAligned32(addr, size/4) - res += word2byte(mem) - size -= 4*len(mem) - addr += 4*len(mem) - - if (size > 1): - mem = self.readMemory(addr, 16) - logging.debug("get 2 bytes at %s: 0x%X", hex(addr), mem) - res.append(mem & 0xff) - res.append((mem >> 8) & 0xff) - size -= 2 - addr += 2 - - if (size > 0): - mem = self.readMemory(addr, 8) - logging.debug("get 1 byte remaining at %s: 0x%X", hex(addr), mem) - res.append(mem) - size -= 1 - addr += 1 - - return res - - - def writeBlockMemoryUnaligned8(self, addr, data): - """ - write a block of unaligned bytes in memory. - """ - size = len(data) - idx = 0 - - #try to write 8 bits data - if (size > 0) and (addr & 0x01): - logging.debug("write 1 byte at 0x%X: 0x%X", addr, data[idx]) - self.writeMemory(addr, data[idx], 8) - size -= 1 - addr += 1 - idx += 1 - - # try to write 16 bits data - if (size > 1) and (addr & 0x02): - logging.debug("write 2 bytes at 0x%X: 0x%X", addr, data[idx] | (data[idx+1] << 8)) - self.writeMemory(addr, data[idx] | (data[idx+1] << 8), 16) - size -= 2 - addr += 2 - idx += 2 - - # write aligned block of 32 bits - if (size >= 4): - logging.debug("write blocks aligned at 0x%X, size: 0x%X", addr, (size/4)*4) - data32 = byte2word(data[idx:idx + (size & ~0x03)]) - self.writeBlockMemoryAligned32(addr, data32) - addr += size & ~0x03 - idx += size & ~0x03 - size -= size & ~0x03 - - # try to write 16 bits data - if (size > 1): - logging.debug("write 2 bytes at 0x%X: 0x%X", addr, data[idx] | (data[idx+1] << 8)) - self.writeMemory(addr, data[idx] | (data[idx+1] << 8), 16) - size -= 2 - addr += 2 - idx += 2 - - #try to write 8 bits data - if (size > 0): - logging.debug("write 1 byte at 0x%X: 0x%X", addr, data[idx]) - self.writeMemory(addr, data[idx], 8) - size -= 1 - addr += 1 - idx += 1 - - return - - def writeBlockMemoryAligned32(self, addr, data): - """ - write a block of aligned words in memory. - """ - size = len(data) - while size > 0: - n = self.auto_increment_page_size - (addr & (self.auto_increment_page_size - 1)) - if size*4 < n: - n = (size*4) & 0xfffffffc - self.transport.writeBlock32(addr, data[:n/4]) - data = data[n/4:] - size -= n/4 - addr += n - return - - def readBlockMemoryAligned32(self, addr, size): - """ - read a block of aligned words in memory. Returns - an array of word values - """ - resp = [] - while size > 0: - n = self.auto_increment_page_size - (addr & (self.auto_increment_page_size - 1)) - if size*4 < n: - n = (size*4) & 0xfffffffc - resp += self.transport.readBlock32(addr, n/4) - size -= n/4 - addr += n - return resp - - def halt(self): - """ - halt the core - """ - self.writeMemory(DHCSR, DBGKEY | C_DEBUGEN | C_HALT) - return - - def step(self): - """ - perform an instruction level step - """ - if self.getState() != TARGET_HALTED: - logging.debug('cannot step: target not halted') - return - if self.maybeSkipBreakpoint() is None: - self.writeMemory(DHCSR, DBGKEY | C_DEBUGEN | C_STEP) - return - - def reset(self): - """ - reset a core. After a call to this function, the core - is running - """ - self.transport.reset() - - def resetStopOnReset(self): - """ - perform a reset and stop the core on the reset handler - """ - logging.debug("reset stop on Reset") - # read address of reset handler - reset_handler = self.readMemory(4) - - # reset and halt the target - self.transport.reset() - self.halt() - - # set a breakpoint to the reset handler and reset the target - self.setBreakpoint(reset_handler) - self.transport.reset() - - # wait until the bp is reached - while (self.getState() == TARGET_RUNNING): - pass - - # remove the breakpoint - self.removeBreakpoint(reset_handler) - - logging.debug("stopped on reset handler: 0x%X", reset_handler) - - def setTargetState(self, state): - if state == "PROGRAM": - self.reset() - self.writeMemory(DHCSR, DBGKEY | C_DEBUGEN) - self.writeMemory(DEMCR, VC_CORERESET) - self.writeMemory(NVIC_AIRCR, NVIC_AIRCR_VECTKEY | NVIC_AIRCR_SYSRESETREQ) - while self.getState() == TARGET_RUNNING: - pass - self.writeMemory(DEMCR, 0) - - - def getState(self): - dhcsr = self.readMemory(DHCSR) - if dhcsr & (C_STEP | C_HALT): - return TARGET_HALTED - return TARGET_RUNNING - - def resume(self): - """ - resume the execution - """ - if self.getState() != TARGET_HALTED: - logging.debug('cannot resume: target not halted') - return - self.maybeSkipBreakpoint() - self.writeMemory(DHCSR, DBGKEY | C_DEBUGEN) - return - - def maybeSkipBreakpoint(self): - pc = self.readCoreRegister('pc') - bp = self.findBreakpoint(pc) - if bp is not None: - logging.debug('skip/resume breakpoint: pc 0x%X', pc) - self.removeBreakpoint(pc) - self.writeMemory(DHCSR, DBGKEY | C_DEBUGEN | C_STEP) - self.setBreakpoint(pc) - logging.debug('step over breakpoint: now pc0x%X', self.readCoreRegister('pc')) - return bp - return None - - def findBreakpoint(self, addr): - for bp in self.breakpoints: - if bp.enabled and bp.addr == addr: - return bp - return None - - def readCoreRegister(self, reg): - """ - read a core register (r0 .. r16). - If reg is a string, find the number associated to this register - in the lookup table CORE_REGISTER - """ - if isinstance(reg, str): - try: - reg = CORE_REGISTER[reg] - except KeyError: - logging.error('cannot find %s core register', id) - return - - if (reg < 0) or (reg > len(CORE_REGISTER)): - logging.error("unknown reg: %d", reg) - return - - # write id in DCRSR - self.writeMemory(DCRSR, reg) - # read DCRDR - return self.readMemory(DCRDR) - - - def writeCoreRegister(self, reg, data): - """ - write a core register (r0 .. r16) - If reg is a string, find the number associated to this register - in the lookup table CORE_REGISTER - """ - if isinstance(reg, str): - try: - reg = CORE_REGISTER[reg] - except KeyError: - logging.error('cannot find %s core register', id) - return - - if (reg < 0) or (reg > len(CORE_REGISTER)): - logging.error("unknown reg: %d", reg) - return - - # write id in DCRSR - self.writeMemory(DCRDR, data) - # read DCRDR - self.writeMemory(DCRSR, reg | REGWnR) - return - - - def setBreakpoint(self, addr): - """ - set a hardware breakpoint at a specific location in flash - """ - if self.fpb_enabled is False: - self.enableFPB() - - if self.availableBreakpoint() == 0: - logging.error('No more available breakpoint!!, dropped bp at 0x%X', addr) - return False - - for bp in self.breakpoints: - if not bp.enabled: - bp.enabled = True - bp_match = (1 << 30) - if addr & 0x2: - bp_match = (2 << 30) - self.writeMemory(bp.comp_register_addr, addr & 0x1ffffffc | bp_match | 1) - bp.addr = addr - self.num_breakpoint_used += 1 - return True - return False - - - def availableBreakpoint(self): - return len(self.breakpoints) - self.num_breakpoint_used - - def enableFPB(self): - self.writeMemory(FP_CTRL, FP_CTRL_KEY | 1) - self.fpb_enabled = True - logging.debug('fpb has been enabled') - return - - def disableFPB(self): - self.writeMemory(FP_CTRL, FP_CTRL_KEY | 0) - self.fpb_enabled = False - logging.debug('fpb has been disabled') - return - - def removeBreakpoint(self, addr): - """ - remove a hardware breakpoint at a specific location in flash - """ - for bp in self.breakpoints: - if bp.enabled and bp.addr == addr: - bp.enabled = False - self.writeMemory(bp.comp_register_addr, 0) - bp.addr = addr - self.num_breakpoint_used -= 1 - return - return - - # GDB functions - def getTargetXML(self): - return self.targetXML, len(self.targetXML) - \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/target/target.py b/workspace_tools/debugger/pyOCD/target/target.py deleted file mode 100644 index 9c09892d32..0000000000 --- a/workspace_tools/debugger/pyOCD/target/target.py +++ /dev/null @@ -1,82 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -TARGET_RUNNING = (1 << 0) -TARGET_HALTED = (1 << 1) - -class Target(): - - def __init__(self, transport): - return - - def init(self): - return - - def info(self, request): - return - - def readIDCode(self): - return - - def halt(self): - return - - def step(self): - return - - def resume(self): - return - - def writeMemory(self, addr, value, transfer_size = 32): - return - - def readMemory(self, addr, transfer_size = 32): - return - - def writeBlockMemoryUnaligned8(self, addr, value): - return - - def writeBlockMemoryAligned32(self, addr, data): - return - - def readBlockMemoryUnaligned8(self, addr, size): - return - - def readBlockMemoryAligned32(self, addr, size): - return - - def readCoreRegister(self, id): - return - - def writeCoreRegister(self, id): - return - - def setBreakpoint(self, addr): - return - - def removeBreakpoint(self, addr): - return - - def reset(self): - return - - def getState(self): - return - - # GDB functions - def getTargetXML(self): - return \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/target/target_kl25z.py b/workspace_tools/debugger/pyOCD/target/target_kl25z.py deleted file mode 100644 index f2f98f69c9..0000000000 --- a/workspace_tools/debugger/pyOCD/target/target_kl25z.py +++ /dev/null @@ -1,57 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from cortex_m import CortexM -import logging - - -MDM_STATUS = 0x01000000 -MDM_CTRL = 0x01000004 -MDM_IDR = 0x010000fc - -class KL25Z(CortexM): - - def __init__(self, transport): - CortexM.__init__(self, transport) - self.auto_increment_page_size = 0x400 - - def init(self): - CortexM.init(self, False) - - # check for flash security - val = self.transport.readAP(MDM_IDR) - if val != 0x001c0020: - logging.error("KL25Z: bad flash ID") - val = self.transport.readAP(MDM_STATUS) - if (val & (1 << 2)): - logging.warning("KL25Z secure state: will try to unlock") - self.transport.assertReset(True) - while True: - self.transport.writeAP(MDM_CTRL, 1) - val = self.transport.readAP(MDM_STATUS) - logging.info(val) - if (val & 1): - break - while True: - self.transport.writeAP(MDM_CTRL, 0) - val = self.transport.readAP(MDM_CTRL) - if (val == 0): - break - - logging.info("KL25Z not in secure state") - self.halt() - self.setupFPB() diff --git a/workspace_tools/debugger/pyOCD/target/target_lpc11u24.py b/workspace_tools/debugger/pyOCD/target/target_lpc11u24.py deleted file mode 100644 index 5bd3e06d15..0000000000 --- a/workspace_tools/debugger/pyOCD/target/target_lpc11u24.py +++ /dev/null @@ -1,24 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from cortex_m import CortexM - -class LPC11U24(CortexM): - - def __init__(self, transport): - CortexM.__init__(self, transport) - self.auto_increment_page_size = 0x400 \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/target/target_lpc1768.py b/workspace_tools/debugger/pyOCD/target/target_lpc1768.py deleted file mode 100644 index 8d0d1deb21..0000000000 --- a/workspace_tools/debugger/pyOCD/target/target_lpc1768.py +++ /dev/null @@ -1,40 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from cortex_m import CortexM - -class LPC1768(CortexM): - - def __init__(self, transport): - CortexM.__init__(self, transport) - self.auto_increment_page_size = 0x1000 - - - def reset(self): - # halt processor - self.halt() - # not remap 0x0000-0x0020 to anything but the flash - self.writeMemory(0x400FC040, 1) - CortexM.reset(self) - - def resetStopOnReset(self): - # halt processor - self.halt() - # not remap 0x0000-0x0020 to anything but the flash - self.writeMemory(0x400FC040, 1) - CortexM.resetStopOnReset(self) - \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/target/target_lpc800.py b/workspace_tools/debugger/pyOCD/target/target_lpc800.py deleted file mode 100644 index 4ef73db9b9..0000000000 --- a/workspace_tools/debugger/pyOCD/target/target_lpc800.py +++ /dev/null @@ -1,24 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from cortex_m import CortexM - -class LPC800(CortexM): - - def __init__(self, transport): - CortexM.__init__(self, transport) - self.auto_increment_page_size = 0x400 diff --git a/workspace_tools/debugger/pyOCD/transport/__init__.py b/workspace_tools/debugger/pyOCD/transport/__init__.py deleted file mode 100644 index c657d37349..0000000000 --- a/workspace_tools/debugger/pyOCD/transport/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from cmsis_dap import CMSIS_DAP - -TRANSPORT = {'cmsis_dap': CMSIS_DAP - } \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/transport/cmsis_dap.py b/workspace_tools/debugger/pyOCD/transport/cmsis_dap.py deleted file mode 100644 index 9c50d542da..0000000000 --- a/workspace_tools/debugger/pyOCD/transport/cmsis_dap.py +++ /dev/null @@ -1,229 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from cmsis_dap_core import dapTransferBlock, dapWriteAbort, dapSWJPins, dapConnect, dapDisconnect, dapTransfer, dapSWJSequence, dapSWDConfigure, dapSWJClock, dapTransferConfigure, dapInfo -from transport import Transport -import logging -from time import sleep - -# !! This value are A[2:3] and not A[3:2] -DP_REG = {'IDCODE' : 0x00, - 'ABORT' : 0x00, - 'CTRL_STAT': 0x04, - 'SELECT': 0x08 - } -AP_REG = {'CSW' : 0x00, - 'TAR' : 0x04, - 'DRW' : 0x0C - } - -IDCODE = 0 << 2 -AP_ACC = 1 << 0 -DP_ACC = 0 << 0 -READ = 1 << 1 -WRITE = 0 << 1 -VALUE_MATCH = 1 << 4 -MATCH_MASK = 1 << 5 - -APBANKSEL = 0x000000f0 - -# AP Control and Status Word definitions -CSW_SIZE = 0x00000007 -CSW_SIZE8 = 0x00000000 -CSW_SIZE16 = 0x00000001 -CSW_SIZE32 = 0x00000002 -CSW_ADDRINC = 0x00000030 -CSW_NADDRINC = 0x00000000 -CSW_SADDRINC = 0x00000010 -CSW_PADDRINC = 0x00000020 -CSW_DBGSTAT = 0x00000040 -CSW_TINPROG = 0x00000080 -CSW_HPROT = 0x02000000 -CSW_MSTRTYPE = 0x20000000 -CSW_MSTRCORE = 0x00000000 -CSW_MSTRDBG = 0x20000000 -CSW_RESERVED = 0x01000000 - -CSW_VALUE = (CSW_RESERVED | CSW_MSTRDBG | CSW_HPROT | CSW_DBGSTAT | CSW_SADDRINC) - -TRANSFER_SIZE = {8: CSW_SIZE8, - 16: CSW_SIZE16, - 32: CSW_SIZE32 - } - - -def JTAG2SWD(interface): - data = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] - dapSWJSequence(interface, data) - - data = [0x9e, 0xe7] - dapSWJSequence(interface, data) - - data = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] - dapSWJSequence(interface, data) - - data = [0x00] - dapSWJSequence(interface, data) - -class CMSIS_DAP(Transport): - """ - This class implements the CMSIS-DAP protocol - """ - def __init__(self, interface): - self.interface = interface - self.packet_max_count = 0 - self.packet_max_size = 0 - self.csw = -1 - self.dp_select = -1 - return - - def init(self): - # init dap IO - dapConnect(self.interface) - # set clock freq at 1000000Hz - dapSWJClock(self.interface) - # configure transfer - dapTransferConfigure(self.interface) - # configure swd protocol - dapSWDConfigure(self.interface) - # switch from jtag to swd - JTAG2SWD(self.interface) - # read ID code - logging.info('IDCODE: 0x%X', self.readDP(DP_REG['IDCODE'])) - # clear abort err - dapWriteAbort(self.interface, 0x1e); - return - - def uninit(self): - dapDisconnect(self.interface) - return - - def info(self, request): - resp = None - try: - resp = dapInfo(self.interface, request) - except KeyError: - logging.error('request %s not supported', request) - return resp - - def writeMem(self, addr, data, transfer_size = 32): - self.writeAP(AP_REG['CSW'], CSW_VALUE | TRANSFER_SIZE[transfer_size]) - - if transfer_size == 8: - data = data << ((addr & 0x03) << 3) - elif transfer_size == 16: - data = data << ((addr & 0x02) << 3) - - dapTransfer(self.interface, 2, [WRITE | AP_ACC | AP_REG['TAR'], - WRITE | AP_ACC | AP_REG['DRW']], - [addr, data]) - - def readMem(self, addr, transfer_size = 32): - self.writeAP(AP_REG['CSW'], CSW_VALUE | TRANSFER_SIZE[transfer_size]) - - resp = dapTransfer(self.interface, 2, [WRITE | AP_ACC | AP_REG['TAR'], - READ | AP_ACC | AP_REG['DRW']], - [addr]) - - res = (resp[0] << 0) | \ - (resp[1] << 8) | \ - (resp[2] << 16) | \ - (resp[3] << 24) - - if transfer_size == 8: - res = (res >> ((addr & 0x03) << 3) & 0xff) - elif transfer_size == 16: - res = (res >> ((addr & 0x02) << 3) & 0xffff) - - return res - - # write aligned word ("data" are words) - def writeBlock32(self, addr, data): - # put address in TAR - self.writeAP(AP_REG['CSW'], CSW_VALUE | CSW_SIZE32) - self.writeAP(AP_REG['TAR'], addr) - dapTransferBlock(self.interface, len(data), WRITE | AP_ACC | AP_REG['DRW'], data) - return - - # read aligned word (the size is in words) - def readBlock32(self, addr, size): - # put address in TAR - self.writeAP(AP_REG['CSW'], CSW_VALUE | CSW_SIZE32) - self.writeAP(AP_REG['TAR'], addr) - data = [] - resp = dapTransferBlock(self.interface, size, READ | AP_ACC | AP_REG['DRW']) - for i in range(len(resp)/4): - data.append( (resp[i*4 + 0] << 0) | \ - (resp[i*4 + 1] << 8) | \ - (resp[i*4 + 2] << 16) | \ - (resp[i*4 + 3] << 24)) - return data - - - def readDP(self, addr): - resp = dapTransfer(self.interface, 1, [READ | DP_ACC | (addr & 0x0c)]) - return (resp[0] << 0) | \ - (resp[1] << 8) | \ - (resp[2] << 16) | \ - (resp[3] << 24) - - def writeDP(self, addr, data): - if addr == DP_REG['SELECT']: - if data == self.dp_select: - return - self.dp_select = data - - dapTransfer(self.interface, 1, [WRITE | DP_ACC | (addr & 0x0c)], [data]) - return True - - def writeAP(self, addr, data): - if addr == AP_REG['CSW']: - if data == self.csw: - return - self.csw = data - - ap_sel = addr & 0xff000000 - bank_sel = addr & APBANKSEL - - self.writeDP(DP_REG['SELECT'], ap_sel | bank_sel) - dapTransfer(self.interface, 1, [WRITE | AP_ACC | (addr & 0x0c)], [data]) - return True - - def readAP(self, addr): - ap_sel = addr & 0xff000000 - bank_sel = addr & APBANKSEL - - self.writeDP(DP_REG['SELECT'], ap_sel | bank_sel) - resp = dapTransfer(self.interface, 1, [READ | AP_ACC | (addr & 0x0c)]) - return (resp[0] << 0) | \ - (resp[1] << 8) | \ - (resp[2] << 16) | \ - (resp[3] << 24) - - def reset(self): - dapSWJPins(self.interface, 0, 'nRESET') - sleep(0.1) - dapSWJPins(self.interface, 0x80, 'nRESET') - sleep(0.1) - - def assertReset(self, asserted): - if asserted: - dapSWJPins(self.interface, 0, 'nRESET') - else: - dapSWJPins(self.interface, 0x80, 'nRESET') - - \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/transport/cmsis_dap_core.py b/workspace_tools/debugger/pyOCD/transport/cmsis_dap_core.py deleted file mode 100644 index 49e281213d..0000000000 --- a/workspace_tools/debugger/pyOCD/transport/cmsis_dap_core.py +++ /dev/null @@ -1,315 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import logging -import array - -COMMAND_ID = {'DAP_INFO': 0x00, - 'DAP_LED': 0x01, - 'DAP_CONNECT': 0x02, - 'DAP_DISCONNECT': 0x03, - 'DAP_TRANSFER_CONFIGURE': 0x04, - 'DAP_TRANSFER': 0x05, - 'DAP_TRANSFER_BLOCK': 0x06, - 'DAP_TRANSFER_ABORT': 0x07, - 'DAP_WRITE_ABORT': 0x08, - 'DAP_DELAY': 0x09, - 'DAP_RESET_TARGET': 0x0a, - 'DAP_SWJ_PINS': 0x10, - 'DAP_SWJ_CLOCK': 0x11, - 'DAP_SWJ_SEQUENCE': 0x12, - 'DAP_SWD_CONFIGURE': 0x13, - } - -ID_INFO = {'VENDOR_ID': 0x01, - 'PRODUCT_ID': 0x02, - 'SERIAL_NUMBER': 0x03, - 'CMSIS_DAP_FW_VERSION': 0x04, - 'TARGET_DEVICE_VENDOR': 0x05, - 'TARGET_DEVICE_NAME': 0x06, - 'CAPABILITIES': 0xf0, - 'PACKET_COUNT': 0xfe, - 'PACKET_SIZE': 0xff - } - -PINS = {'None': 0x00, - 'SWCLK_TCK': (1 << 0), - 'SWDIO_TMS': (1 << 1), - 'TDI': (1 << 2), - 'TDO': (1 << 3), - 'nTRST': (1 << 5), - 'nRESET': (1 << 7), - } - -DAP_DEFAULT_PORT = 0 -DAP_SWD_PORT = 1 -DAP_JTAG_POR = 2 - -DAP_OK = 0 -DAP_ERROR = 0xff - -MAX_PACKET_SIZE = 0x0E - -def dapInfo(interface, id_): - cmd = [] - cmd.append(COMMAND_ID['DAP_INFO']) - cmd.append(ID_INFO[id_]) - interface.write(cmd) - - resp = interface.read() - if resp[0] != COMMAND_ID['DAP_INFO']: - raise ValueError('DAP_INFO response error') - - if resp[1] == 0: - return - - if resp[1] == 1: - return resp[2] - - if resp[1] == 2: - return (resp[3] << 8) | resp[2] - - x = array.array('B', [i for i in resp[2:2+resp[1]]]) - - return x.tostring() - - -def dapLed(interface): - #not yet implemented - return - -def dapConnect(interface, mode = DAP_DEFAULT_PORT): - cmd = [] - cmd.append(COMMAND_ID['DAP_CONNECT']) - cmd.append(mode) - interface.write(cmd) - - resp = interface.read() - if resp[0] != COMMAND_ID['DAP_CONNECT']: - raise ValueError('DAP_CONNECT response error') - - if resp[1] == 0: - raise ValueError('DAP Connect failed') - - if resp[1] == 1: - logging.info('DAP SWD MODE initialised') - - if resp[1] == 2: - logging.info('DAP JTAG MODE initialised') - - return resp[1] - -def dapDisconnect(interface): - cmd = [] - cmd.append(COMMAND_ID['DAP_DISCONNECT']) - interface.write(cmd) - - resp = interface.read() - if resp[0] != COMMAND_ID['DAP_DISCONNECT']: - raise ValueError('DAP_DISCONNECT response error') - - if resp[1] != DAP_OK: - raise ValueError('DAP Disconnect failed') - - return resp[1] - - -def dapWriteAbort(interface, data, dap_index = 0): - cmd = [] - cmd.append(COMMAND_ID['DAP_WRITE_ABORT']) - cmd.append(dap_index) - cmd.append((data >> 0) & 0xff) - cmd.append((data >> 8) & 0xff) - cmd.append((data >> 16) & 0xff) - cmd.append((data >> 24) & 0xff) - interface.write(cmd) - - resp = interface.read() - if resp[0] != COMMAND_ID['DAP_WRITE_ABORT']: - raise ValueError('DAP_WRITE_ABORT response error') - - if resp[1] != DAP_OK: - raise ValueError('DAP Write Abort failed') - - return True - -def dapResetTarget(interface): - cmd = [] - cmd.append(COMMAND_ID['DAP_RESET_TARGET']) - interface.write(cmd) - - resp = interface.read() - if resp[0] != COMMAND_ID['DAP_RESET_TARGET']: - raise ValueError('DAP_RESET_TARGET response error') - - if resp[1] != DAP_OK: - raise ValueError('DAP Reset target failed') - - return resp[1] - -def dapTransferConfigure(interface, idle_cycles = 0x00, wait_retry = 0x0050, match_retry = 0x0000): - cmd = [] - cmd.append(COMMAND_ID['DAP_TRANSFER_CONFIGURE']) - cmd.append(idle_cycles) - cmd.append(wait_retry & 0xff) - cmd.append(wait_retry >> 8) - cmd.append(match_retry & 0xff) - cmd.append(match_retry >> 8) - interface.write(cmd) - - resp = interface.read() - if resp[0] != COMMAND_ID['DAP_TRANSFER_CONFIGURE']: - raise ValueError('DAP_TRANSFER_CONFIGURE response error') - - if resp[1] != DAP_OK: - raise ValueError('DAP Transfer Configure failed') - - return resp[1] - -def dapTransfer(interface, count, request, data = [0], dap_index = 0): - cmd = [] - cmd.append(COMMAND_ID['DAP_TRANSFER']) - cmd.append(dap_index) - cmd.append(count) - count_write = count - for i in range(count): - cmd.append(request[i]) - if not ( request[i] & ((1 << 1) | (1 << 4))): - cmd.append(data[i] & 0xff) - cmd.append((data[i] >> 8) & 0xff) - cmd.append((data[i] >> 16) & 0xff) - cmd.append((data[i] >> 24) & 0xff) - count_write -= 1 - interface.write(cmd) - - resp = interface.read() - if resp[0] != COMMAND_ID['DAP_TRANSFER']: - raise ValueError('DAP_TRANSFER response error') - - if resp[1] != count: - raise ValueError('Transfer not completed') - - if resp[2] != 0x01: - raise ValueError('SWD Fault') - - return resp[3:3+count_write*4] - -def dapTransferBlock(interface, count, request, data = [0], dap_index = 0): - packet_count = count - nb = 0 - resp = [] - # we send successfully several packets if the size is bigger than MAX_PACKET_COUNT - while packet_count > 0: - cmd = [] - cmd.append(COMMAND_ID['DAP_TRANSFER_BLOCK']) - cmd.append(dap_index) - packet_written = min(packet_count, MAX_PACKET_SIZE) - cmd.append(packet_written & 0xff) - cmd.append((packet_written >> 8) & 0xff) - cmd.append(request) - if not (request & ((1 << 1))): - for i in range(packet_written): - cmd.append(data[i + nb*MAX_PACKET_SIZE] & 0xff) - cmd.append((data[i + nb*MAX_PACKET_SIZE] >> 8) & 0xff) - cmd.append((data[i + nb*MAX_PACKET_SIZE] >> 16) & 0xff) - cmd.append((data[i + nb*MAX_PACKET_SIZE] >> 24) & 0xff) - interface.write(cmd) - packet_count = packet_count - MAX_PACKET_SIZE - nb = nb + 1 - - # we then read - tmp = interface.read() - if tmp[0] != COMMAND_ID['DAP_TRANSFER_BLOCK'] or tmp[3] != 0x01: - raise ValueError('DAP_TRANSFER_BLOCK response error') - size_transfer = tmp[1] | (tmp[2] << 8) - resp.extend(tmp[4:4+size_transfer*4]) - - return resp - -def dapSWJClock(interface, clock = 1000000): - cmd = [] - cmd.append(COMMAND_ID['DAP_SWJ_CLOCK']) - cmd.append(clock & 0xff) - cmd.append((clock >> 8) & 0xff) - cmd.append((clock >> 16) & 0xff) - cmd.append((clock >> 24) & 0xff) - interface.write(cmd) - - resp = interface.read() - if resp[0] != COMMAND_ID['DAP_SWJ_CLOCK']: - raise ValueError('DAP_SWJ_CLOCK response error') - - if resp[1] != DAP_OK: - raise ValueError('DAP SWJ Clock failed') - - return resp[1] - -def dapSWJPins(interface, output, pin, wait = 0): - cmd = [] - cmd.append(COMMAND_ID['DAP_SWJ_PINS']) - try: - p = PINS[pin] - except KeyError: - logging.error('cannot find %s pin', pin) - return - cmd.append(output & 0xff) - cmd.append(p) - cmd.append(wait & 0xff) - cmd.append((wait >> 8) & 0xff) - cmd.append((wait >> 16) & 0xff) - cmd.append((wait >> 24) & 0xff) - interface.write(cmd) - - resp = interface.read() - if resp[0] != COMMAND_ID['DAP_SWJ_PINS']: - raise ValueError('DAP_SWJ_PINS response error') - - return resp[1] - - -def dapSWDConfigure(interface, conf = 0): - cmd = [] - cmd.append(COMMAND_ID['DAP_SWD_CONFIGURE']) - cmd.append(conf) - interface.write(cmd) - - resp = interface.read() - if resp[0] != COMMAND_ID['DAP_SWD_CONFIGURE']: - raise ValueError('DAP_SWD_CONFIGURE response error') - - if resp[1] != DAP_OK: - raise ValueError('DAP SWD Configure failed') - - return resp[1] - -def dapSWJSequence(interface, data): - cmd = [] - cmd.append(COMMAND_ID['DAP_SWJ_SEQUENCE']) - cmd.append(len(data)*8) - for i in range(len(data)): - cmd.append(data[i]) - interface.write(cmd) - - resp = interface.read() - if resp[0] != COMMAND_ID['DAP_SWJ_SEQUENCE']: - raise ValueError('DAP_SWJ_SEQUENCE response error') - - if resp[1] != DAP_OK: - raise ValueError('DAP SWJ Sequence failed') - - return resp[1] - \ No newline at end of file diff --git a/workspace_tools/debugger/pyOCD/transport/transport.py b/workspace_tools/debugger/pyOCD/transport/transport.py deleted file mode 100644 index b0dae47f07..0000000000 --- a/workspace_tools/debugger/pyOCD/transport/transport.py +++ /dev/null @@ -1,64 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -class Transport(): - - def __init__(self, interface): - self.interface = interface - return - - def init(self): - return - - def uninit(self): - return - - def info(self, request): - return - - def readDP(self, addr): - return - - def writeDP(self, addr, data): - return - - def writeAP(self, addr, data): - return - - def readAP(self, addr): - return - - def writeMem(self, addr, data, transfer_size = 32): - return - - def readMem(self, addr, transfer_size = 32): - return - - def writeBlock32(self, addr, data): - return - - def readBlock32(self, addr, data): - return - - def assertReset(self, asserted): - return - - def getUniqueID(self): - return - - def reset(self): - return \ No newline at end of file diff --git a/workspace_tools/debugger/setup.py b/workspace_tools/debugger/setup.py deleted file mode 100644 index f61df3abaf..0000000000 --- a/workspace_tools/debugger/setup.py +++ /dev/null @@ -1,33 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -from distutils.core import setup - -setup( - name="pyOCD", - version="0.1", - description="CMSIS-DAP debugger for python", - author="samux", - author_email="samuel.mokrani@gmail.com", - license="Apache 2.0", - classifiers = [ - "Development Status :: 4 - Beta", - "License :: Apache 2.0", - "Programming Language :: Python", - ], - packages=["pyOCD", "pyOCD.flash", "pyOCD.gdbserver", "pyOCD.interface", "pyOCD.target", "pyOCD.transport", "pyOCD.board"] -) diff --git a/workspace_tools/debugger/test/basic_test.py b/workspace_tools/debugger/test/basic_test.py deleted file mode 100644 index 69ab407bf8..0000000000 --- a/workspace_tools/debugger/test/basic_test.py +++ /dev/null @@ -1,165 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import argparse, os -from time import sleep -from random import randrange - -parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - -from pyOCD.board import MbedBoard - -addr = 0 -size = 0 -f = None -binary_file = "l1_" - -interface = None - -import logging - -logging.basicConfig(level=logging.INFO) - -parser = argparse.ArgumentParser(description='A CMSIS-DAP python debugger') -parser.add_argument('-f', help='binary file', dest = "file") -args = parser.parse_args() - -try: - - board = MbedBoard.chooseBoard() - target_type = board.getTargetType() - - if args.file is None: - binary_file += target_type + ".bin" - binary_file = os.path.join(parentdir, 'binaries', binary_file) - else: - binary_file = args.file - - print "binary file: %s" % binary_file - - if target_type == "lpc1768": - addr = 0x10000001 - size = 0x1102 - elif target_type == "lpc11u24": - addr = 0x10000001 - size = 0x502 - elif target_type == "kl25z": - addr = 0x20000001 - size = 0x502 - elif target_type == "lpc800": - addr = 0x10000001 - size = 0x502 - - target = board.target - transport = board.transport - flash = board.flash - interface = board.interface - - - print "\r\n\r\n------ GET Unique ID ------" - print "Unique ID: %s" % board.getUniqueID() - - print "\r\n\r\n------ TEST READ / WRITE CORE REGISTER ------" - pc = target.readCoreRegister('pc') - print "initial pc: 0x%X" % target.readCoreRegister('pc') - # write in pc dummy value - target.writeCoreRegister('pc', 0x3D82) - print "now pc: 0x%X" % target.readCoreRegister('pc') - # write initial pc value - target.writeCoreRegister('pc', pc) - print "initial pc value rewritten: 0x%X" % target.readCoreRegister('pc') - - - print "\r\n\r\n------ TEST HALT / RESUME ------" - - print "resume" - target.resume() - sleep(0.2) - - print "halt" - target.halt() - print "HALT: pc: 0x%X" % target.readCoreRegister('pc') - sleep(0.2) - - - - print "\r\n\r\n------ TEST READ / WRITE MEMORY ------" - target.halt() - print "READ32/WRITE32" - val = randrange(0, 0xffffffff) - print "write32 0x%X at 0x%X" % (val, addr) - target.writeMemory(addr, val) - res = target.readMemory(addr) - print "read32 at 0x%X: 0x%X" % (addr, res) - if res != val: - print "ERROR in READ/WRITE 32" - - print "\r\nREAD16/WRITE316" - val = randrange(0, 0xffff) - print "write16 0x%X at 0x%X" % (val, addr + 2) - target.writeMemory(addr + 2, val, 16) - res = target.readMemory(addr + 2, 16) - print "read16 at 0x%X: 0x%X" % (addr + 2, res) - if res != val: - print "ERROR in READ/WRITE 16" - - print "\r\nREAD8/WRITE8" - val = randrange(0, 0xff) - print "write8 0x%X at 0x%X" % (val, addr + 1) - target.writeMemory(addr + 1, val, 8) - res = target.readMemory(addr + 1, 8) - print "read8 at 0x%X: 0x%X" % (addr + 1, res) - if res != val: - print "ERROR in READ/WRITE 8" - - - print "\r\n\r\n------ TEST READ / WRITE MEMORY BLOCK ------" - data = [randrange(1, 50) for x in range(size)] - target.writeBlockMemoryUnaligned8(addr, data) - block = target.readBlockMemoryUnaligned8(addr, size) - error = False - for i in range(len(block)): - if (block[i] != data[i]): - error = True - print "ERROR: 0x%X, 0x%X, 0x%X!!!" % ((addr + i), block[i], data[i]) - if error: - print "TEST FAILED" - else: - print "TEST PASSED" - - - print "\r\n\r\n------ TEST RESET ------" - target.reset() - sleep(0.1) - target.halt() - - for i in range(5): - target.step() - print "pc: 0x%X" % target.readCoreRegister('pc') - - - print "\r\n\r\n----- FLASH NEW BINARY -----" - flash.flashBinary(binary_file) - - target.reset() - -except Exception as e: - print "Unknown exception: %s" % e - -finally: - if board != None: - board.uninit() \ No newline at end of file diff --git a/workspace_tools/debugger/test/gdb_test.py b/workspace_tools/debugger/test/gdb_test.py deleted file mode 100644 index dd04436fed..0000000000 --- a/workspace_tools/debugger/test/gdb_test.py +++ /dev/null @@ -1,36 +0,0 @@ -""" - mbed CMSIS-DAP debugger - Copyright (c) 2006-2013 ARM Limited - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -""" - -import logging - -from pyOCD.gdbserver import GDBServer -from pyOCD.board import MbedBoard - -logging.basicConfig(level=logging.INFO) - -try: - board_selected = MbedBoard.chooseBoard() - if board_selected != None: - gdb = GDBServer(board_selected, 3333) - while gdb.isAlive(): - gdb.join(timeout = 0.5) - -except KeyboardInterrupt: - gdb.stop() -except Exception as e: - print "uncaught exception: %s" % e - gdb.stop() \ No newline at end of file