@@ -212,18 +212,20 @@ <h1 class="mb-4 mt-0">Python API examples</h1>
212212 < div class ="sidebar docs-sidebar-2 p-4 ">
213213 < h5 class ="sidebar-header "> On this page</ h5 >
214214 < ul id ="toc " class ="section-nav ">
215- < li class ="toc-entry toc-h3 "> < a href ="#hello-world-example-code "> Hello World example code</ a > </ li >
216- < li class ="toc-entry toc-h3 "> < a href ="#elf-files-and-breakpoints "> ELF files and breakpoints</ a > </ li >
215+ < li class ="toc-entry toc-h2 "> < a href ="#hello-world-example-code "> Hello World example code</ a > </ li >
216+ < li class ="toc-entry toc-h2 "> < a href ="#elf-files-and-breakpoints "> ELF files and breakpoints</ a > </ li >
217217< li class ="toc-entry toc-h2 "> < a href ="#alternative-ways-to-create-a-session "> Alternative ways to create a session</ a > </ li >
218+ < li class ="toc-entry toc-h2 "> < a href ="#semihosting "> Semihosting</ a > </ li >
218219</ ul >
219220 </ div >
220221 </ div >
221222
222- < h3 id ="hello-world-example-code "> Hello World example code</ h3 >
223+ < h2 id ="hello-world-example-code "> Hello World example code</ h2 >
223224
224225< p > This example shows basic connection, loading a firmware binary, and some simple target control.</ p >
225226
226- < div class ="language-python highlighter-rouge "> < div class ="highlight "> < pre class ="highlight "> < code > < span class ="kn "> from</ span > < span class ="nn "> pyocd.core.helpers</ span > < span class ="kn "> import</ span > < span class ="n "> ConnectHelper</ span >
227+ < div class ="language-python highlighter-rouge "> < div class ="highlight "> < pre class ="highlight "> < code > < span class ="c1 "> #!/usr/bin/env python3
228+ </ span > < span class ="kn "> from</ span > < span class ="nn "> pyocd.core.helpers</ span > < span class ="kn "> import</ span > < span class ="n "> ConnectHelper</ span >
227229< span class ="kn "> from</ span > < span class ="nn "> pyocd.flash.file_programmer</ span > < span class ="kn "> import</ span > < span class ="n "> FileProgrammer</ span >
228230
229231< span class ="kn "> import</ span > < span class ="nn "> logging</ span >
@@ -238,32 +240,32 @@ <h3 id="hello-world-example-code">Hello World example code</h3>
238240 < span class ="c1 "> # Load firmware into device.
239241</ span > < span class ="n "> FileProgrammer</ span > < span class ="p "> (</ span > < span class ="n "> session</ span > < span class ="p "> ).</ span > < span class ="n "> program</ span > < span class ="p "> (</ span > < span class ="s "> "my_firmware.bin"</ span > < span class ="p "> )</ span >
240242
241- < span class ="c1 "> # Reset, run.
243+ < span class ="c1 "> # Reset
242244</ span > < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> reset_and_halt</ span > < span class ="p "> ()</ span >
243- < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> resume</ span > < span class ="p "> ()</ span >
244-
245+
245246 < span class ="c1 "> # Read some registers.
246247</ span > < span class ="k "> print</ span > < span class ="p "> (</ span > < span class ="s "> "pc: 0x%X"</ span > < span class ="o "> %</ span > < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> read_core_register</ span > < span class ="p "> (</ span > < span class ="s "> "pc"</ span > < span class ="p "> ))</ span >
247248
248249 < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> step</ span > < span class ="p "> ()</ span >
249250 < span class ="k "> print</ span > < span class ="p "> (</ span > < span class ="s "> "pc: 0x%X"</ span > < span class ="o "> %</ span > < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> read_core_register</ span > < span class ="p "> (</ span > < span class ="s "> "pc"</ span > < span class ="p "> ))</ span >
250251
251252 < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> resume</ span > < span class ="p "> ()</ span >
253+ < span class ="n "> time</ span > < span class ="p "> .</ span > < span class ="n "> sleep</ span > < span class ="p "> (</ span > < span class ="mf "> 0.2</ span > < span class ="p "> )</ span >
252254 < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> halt</ span > < span class ="p "> ()</ span >
253255 < span class ="k "> print</ span > < span class ="p "> (</ span > < span class ="s "> "pc: 0x%X"</ span > < span class ="o "> %</ span > < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> read_core_register</ span > < span class ="p "> (</ span > < span class ="s "> "pc"</ span > < span class ="p "> ))</ span >
254256
255257 < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> reset_and_halt</ span > < span class ="p "> ()</ span >
256258
257259 < span class ="k "> print</ span > < span class ="p "> (</ span > < span class ="s "> "pc: 0x%X"</ span > < span class ="o "> %</ span > < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> read_core_register</ span > < span class ="p "> (</ span > < span class ="s "> "pc"</ span > < span class ="p "> ))</ span >
258-
259260</ code > </ pre > </ div > </ div >
260261
261- < h3 id ="elf-files-and-breakpoints "> ELF files and breakpoints</ h3 >
262+ < h2 id ="elf-files-and-breakpoints "> ELF files and breakpoints</ h2 >
262263
263264< p > Expanding on the above example, this code demonstrates reading a symbol address from an ELF file
264265and setting a breakpoint. Then the target is reset and run until the breakpoint is hit.</ p >
265266
266- < div class ="language-python highlighter-rouge "> < div class ="highlight "> < pre class ="highlight "> < code > < span class ="kn "> from</ span > < span class ="nn "> pyocd.core.helpers</ span > < span class ="kn "> import</ span > < span class ="n "> ConnectHelper</ span >
267+ < div class ="language-python highlighter-rouge "> < div class ="highlight "> < pre class ="highlight "> < code > < span class ="c1 "> #!/usr/bin/env python3
268+ </ span > < span class ="kn "> from</ span > < span class ="nn "> pyocd.core.helpers</ span > < span class ="kn "> import</ span > < span class ="n "> ConnectHelper</ span >
267269< span class ="kn "> from</ span > < span class ="nn "> pyocd.core.target</ span > < span class ="kn "> import</ span > < span class ="n "> Target</ span >
268270< span class ="kn "> from</ span > < span class ="nn "> pyocd.debug.elf.symbols</ span > < span class ="kn "> import</ span > < span class ="n "> ELFSymbolProvider</ span >
269271
@@ -293,8 +295,8 @@ <h3 id="elf-files-and-breakpoints">ELF files and breakpoints</h3>
293295</ span > < span class ="n "> pc</ span > < span class ="o "> =</ span > < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> read_core_register</ span > < span class ="p "> (</ span > < span class ="s "> "pc"</ span > < span class ="p "> )</ span >
294296 < span class ="k "> print</ span > < span class ="p "> (</ span > < span class ="s "> "pc: 0x%X"</ span > < span class ="o "> %</ span > < span class ="n "> pc</ span > < span class ="p "> )</ span >
295297
296- < span class ="k "> assert</ span > < span class ="n "> pc</ span > < span class ="o "> ==</ span > < span class ="n "> addr</ span >
297-
298+ < span class ="k "> assert</ span > < span class ="n "> pc</ span > < span class ="o "> ==</ span > < span class ="n "> addr</ span > < span class =" o " > & </ span > < span class =" o " > ~ </ span > < span class =" mh " > 0x01 </ span > < span class =" c1 " > # mask off LSB
299+ </ span >
298300 < span class ="c1 "> # Remove breakpoint.
299301</ span > < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> remove_breakpoint</ span > < span class ="p "> ()</ span >
300302</ code > </ pre > </ div > </ div >
@@ -351,6 +353,112 @@ <h2 id="alternative-ways-to-create-a-session">Alternative ways to create a sessi
351353 < span class ="c1 "> # ... control the target
352354</ span > </ code > </ pre > </ div > </ div >
353355
356+ < p > Selecting a probe and configuring the target connection is done as follows:</ p >
357+
358+ < div class ="language-python highlighter-rouge "> < div class ="highlight "> < pre class ="highlight "> < code > < span class ="c1 "> # Connect to the target with some options.
359+ </ span > < span class ="n "> session</ span > < span class ="o "> =</ span > < span class ="n "> ConnectHelper</ span > < span class ="p "> .</ span > < span class ="n "> session_with_chosen_probe</ span > < span class ="p "> (</ span > < span class ="n "> unique_id</ span > < span class ="o "> =</ span > < span class ="s "> "E6616407E3646B29"</ span > < span class ="p "> ,</ span > < span class ="n "> options</ span > < span class ="o "> =</ span > < span class ="p "> {</ span > < span class ="s "> "frequency"</ span > < span class ="p "> :</ span > < span class ="mi "> 4000000</ span > < span class ="p "> ,</ span > < span class ="s "> "target_override"</ span > < span class ="p "> :</ span > < span class ="s "> "nrf52840"</ span > < span class ="p "> })</ span >
360+
361+ < span class ="k "> with</ span > < span class ="n "> session</ span > < span class ="p "> :</ span >
362+ < span class ="c1 "> # ...
363+ </ span > </ code > </ pre > </ div > </ div >
364+
365+ < p > More options can be found < a href ="options.md "> here</ a > .</ p >
366+
367+ < h2 id ="semihosting "> Semihosting</ h2 >
368+
369+ < p > For in-target tests it is sometimes convenient to use semihosting, e.g. write coverage data into the hosts file system.
370+ To execute semihosting requests a < code class ="highlighter-rouge "> wait_for_halt()</ code > function must be implemented. If writing the profile data is
371+ explicitly done at end of < code class ="highlighter-rouge "> main()</ code > , a breakpoint on return is also helpful. Implementation could be like this:</ p >
372+
373+ < div class ="language-python highlighter-rouge "> < div class ="highlight "> < pre class ="highlight "> < code > < span class ="c1 "> #!/usr/bin/env python3
374+ </ span > < span class ="kn "> from</ span > < span class ="nn "> pyocd.core.helpers</ span > < span class ="kn "> import</ span > < span class ="n "> ConnectHelper</ span >
375+ < span class ="kn "> from</ span > < span class ="nn "> pyocd.core.target</ span > < span class ="kn "> import</ span > < span class ="n "> Target</ span >
376+ < span class ="kn "> from</ span > < span class ="nn "> pyocd.debug.elf.symbols</ span > < span class ="kn "> import</ span > < span class ="n "> ELFSymbolProvider</ span >
377+ < span class ="kn "> from</ span > < span class ="nn "> pyocd.flash.file_programmer</ span > < span class ="kn "> import</ span > < span class ="n "> FileProgrammer</ span >
378+ < span class ="kn "> from</ span > < span class ="nn "> pyocd.debug</ span > < span class ="kn "> import</ span > < span class ="n "> semihost</ span >
379+ < span class ="kn "> import</ span > < span class ="nn "> time</ span >
380+
381+ < span class ="kn "> import</ span > < span class ="nn "> traceback</ span >
382+ < span class ="kn "> import</ span > < span class ="nn "> logging</ span >
383+ < span class ="n "> logging</ span > < span class ="p "> .</ span > < span class ="n "> basicConfig</ span > < span class ="p "> (</ span > < span class ="n "> level</ span > < span class ="o "> =</ span > < span class ="n "> logging</ span > < span class ="p "> .</ span > < span class ="n "> INFO</ span > < span class ="p "> )</ span >
384+
385+
386+ < span class ="n "> image_name</ span > < span class ="o "> =</ span > < span class ="s "> "profiling.elf"</ span >
387+
388+
389+ < span class ="k "> def</ span > < span class ="nf "> wait_for_halt</ span > < span class ="p "> (</ span > < span class ="n "> target</ span > < span class ="p "> ,</ span > < span class ="n "> semihost</ span > < span class ="p "> ):</ span >
390+ < span class ="n "> go_on</ span > < span class ="o "> =</ span > < span class ="bp "> True</ span >
391+ < span class ="k "> while</ span > < span class ="n "> go_on</ span > < span class ="p "> :</ span >
392+ < span class ="n "> state</ span > < span class ="o "> =</ span > < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> get_state</ span > < span class ="p "> ()</ span >
393+ < span class ="k "> if</ span > < span class ="n "> state</ span > < span class ="o "> ==</ span > < span class ="n "> Target</ span > < span class ="p "> .</ span > < span class ="n "> State</ span > < span class ="p "> .</ span > < span class ="n "> HALTED</ span > < span class ="p "> :</ span >
394+ < span class ="k "> try</ span > < span class ="p "> :</ span >
395+ < span class ="c1 "> # Handle semihosting
396+ </ span > < span class ="n "> go_on</ span > < span class ="o "> =</ span > < span class ="n "> semihost</ span > < span class ="p "> .</ span > < span class ="n "> check_and_handle_semihost_request</ span > < span class ="p "> ()</ span >
397+ < span class ="k "> if</ span > < span class ="n "> go_on</ span > < span class ="p "> :</ span >
398+ < span class ="c1 "> # target was halted due to semihosting request
399+ </ span > < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> resume</ span > < span class ="p "> ()</ span >
400+ < span class ="k "> except</ span > < span class ="nb "> Exception</ span > < span class ="k "> as</ span > < span class ="n "> e</ span > < span class ="p "> :</ span >
401+ < span class ="k "> print</ span > < span class ="p "> (</ span > < span class ="s "> "semihost exception/resume------"</ span > < span class ="p "> ,</ span > < span class ="n "> e</ span > < span class ="p "> )</ span >
402+ < span class ="k "> print</ span > < span class ="p "> (</ span > < span class ="n "> traceback</ span > < span class ="p "> .</ span > < span class ="n "> format_exc</ span > < span class ="p "> ())</ span >
403+ < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> resume</ span > < span class ="p "> ()</ span >
404+ < span class ="n "> go_on</ span > < span class ="o "> =</ span > < span class ="bp "> True</ span >
405+ < span class ="k "> else</ span > < span class ="p "> :</ span >
406+ < span class ="n "> time</ span > < span class ="p "> .</ span > < span class ="n "> sleep</ span > < span class ="p "> (</ span > < span class ="mf "> 0.01</ span > < span class ="p "> )</ span >
407+
408+
409+ < span class ="n "> session</ span > < span class ="o "> =</ span > < span class ="n "> ConnectHelper</ span > < span class ="p "> .</ span > < span class ="n "> session_with_chosen_probe</ span > < span class ="p "> (</ span > < span class ="n "> unique_id</ span > < span class ="o "> =</ span > < span class ="s "> "E6616407E3646B29"</ span > < span class ="p "> ,</ span > < span class ="n "> options</ span > < span class ="o "> =</ span > < span class ="p "> {</ span > < span class ="s "> "frequency"</ span > < span class ="p "> :</ span > < span class ="mi "> 4000000</ span > < span class ="p "> ,</ span >
410+ < span class ="s "> "target_override"</ span > < span class ="p "> :</ span > < span class ="s "> "nrf52840"</ span > < span class ="p "> ,</ span >
411+ < span class ="s "> "enable_semihosting"</ span > < span class ="p "> :</ span > < span class ="bp "> True</ span > < span class ="p "> ,</ span >
412+ < span class ="s "> "semihost_use_syscalls"</ span > < span class ="p "> :</ span > < span class ="bp "> False</ span > < span class ="p "> })</ span >
413+
414+ < span class ="k "> with</ span > < span class ="n "> session</ span > < span class ="p "> :</ span >
415+ < span class ="n "> target</ span > < span class ="o "> =</ span > < span class ="n "> session</ span > < span class ="p "> .</ span > < span class ="n "> target</ span >
416+ < span class ="n "> target_context</ span > < span class ="o "> =</ span > < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> get_target_context</ span > < span class ="p "> ()</ span >
417+ < span class ="n "> semihost_io_handler</ span > < span class ="o "> =</ span > < span class ="n "> semihost</ span > < span class ="p "> .</ span > < span class ="n "> InternalSemihostIOHandler</ span > < span class ="p "> ()</ span >
418+ < span class ="n "> semihost</ span > < span class ="o "> =</ span > < span class ="n "> semihost</ span > < span class ="p "> .</ span > < span class ="n "> SemihostAgent</ span > < span class ="p "> (</ span > < span class ="n "> target_context</ span > < span class ="p "> ,</ span > < span class ="n "> io_handler</ span > < span class ="o "> =</ span > < span class ="n "> semihost_io_handler</ span > < span class ="p "> ,</ span > < span class ="n "> console</ span > < span class ="o "> =</ span > < span class ="n "> semihost_io_handler</ span > < span class ="p "> )</ span >
419+
420+ < span class ="c1 "> # Load firmware into device.
421+ </ span > < span class ="n "> FileProgrammer</ span > < span class ="p "> (</ span > < span class ="n "> session</ span > < span class ="p "> ).</ span > < span class ="n "> program</ span > < span class ="p "> (</ span > < span class ="n "> image_name</ span > < span class ="p "> )</ span >
422+
423+ < span class ="c1 "> # Set ELF file on target.
424+ </ span > < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> elf</ span > < span class ="o "> =</ span > < span class ="n "> image_name</ span >
425+ < span class ="n "> provider</ span > < span class ="o "> =</ span > < span class ="n "> ELFSymbolProvider</ span > < span class ="p "> (</ span > < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> elf</ span > < span class ="p "> )</ span >
426+
427+ < span class ="c1 "> # Look up address of main().
428+ </ span > < span class ="n "> addr</ span > < span class ="o "> =</ span > < span class ="n "> provider</ span > < span class ="p "> .</ span > < span class ="n "> get_symbol_value</ span > < span class ="p "> (</ span > < span class ="s "> "main"</ span > < span class ="p "> )</ span >
429+ < span class ="k "> print</ span > < span class ="p "> (</ span > < span class ="s "> "main() address: 0x%X"</ span > < span class ="o "> %</ span > < span class ="n "> addr</ span > < span class ="p "> )</ span >
430+
431+ < span class ="c1 "> # Set breakpoint.
432+ </ span > < span class ="k "> print</ span > < span class ="p "> (</ span > < span class ="s "> "set breakpoint to entry of main()"</ span > < span class ="p "> )</ span >
433+ < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> set_breakpoint</ span > < span class ="p "> (</ span > < span class ="n "> addr</ span > < span class ="p "> )</ span >
434+
435+ < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> reset_and_halt</ span > < span class ="p "> ()</ span >
436+ < span class ="k "> print</ span > < span class ="p "> (</ span > < span class ="s "> "execute"</ span > < span class ="p "> )</ span >
437+ < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> resume</ span > < span class ="p "> ()</ span >
438+
439+ < span class ="c1 "> # Wait until breakpoint is hit.
440+ </ span > < span class ="n "> wait_for_halt</ span > < span class ="p "> (</ span > < span class ="n "> target</ span > < span class ="p "> ,</ span > < span class ="n "> semihost</ span > < span class ="p "> )</ span >
441+
442+ < span class ="c1 "> # Print PC.
443+ </ span > < span class ="n "> pc</ span > < span class ="o "> =</ span > < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> read_core_register</ span > < span class ="p "> (</ span > < span class ="s "> "pc"</ span > < span class ="p "> )</ span >
444+ < span class ="k "> print</ span > < span class ="p "> (</ span > < span class ="s "> " pc: 0x%X"</ span > < span class ="o "> %</ span > < span class ="n "> pc</ span > < span class ="p "> )</ span >
445+ < span class ="k "> assert</ span > < span class ="n "> pc</ span > < span class ="o "> ==</ span > < span class ="n "> addr</ span > < span class ="o "> &</ span > < span class ="o "> ~</ span > < span class ="mh "> 0x01</ span > < span class ="c1 "> # mask off LSB
446+ </ span > < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> remove_breakpoint</ span > < span class ="p "> (</ span > < span class ="n "> addr</ span > < span class ="p "> )</ span >
447+
448+ < span class ="c1 "> # set breakpoint to return address and execute til there
449+ </ span > < span class ="n "> lr</ span > < span class ="o "> =</ span > < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> read_core_register</ span > < span class ="p "> (</ span > < span class ="s "> "lr"</ span > < span class ="p "> )</ span >
450+ < span class ="k "> print</ span > < span class ="p "> (</ span > < span class ="s "> " lr: 0x%X (return address)"</ span > < span class ="o "> %</ span > < span class ="n "> lr</ span > < span class ="p "> )</ span >
451+ < span class ="k "> print</ span > < span class ="p "> (</ span > < span class ="s "> "set breakpoint to return of main()"</ span > < span class ="p "> )</ span >
452+ < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> set_breakpoint</ span > < span class ="p "> (</ span > < span class ="n "> lr</ span > < span class ="p "> )</ span >
453+ < span class ="k "> print</ span > < span class ="p "> (</ span > < span class ="s "> "execute"</ span > < span class ="p "> )</ span >
454+ < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> resume</ span > < span class ="p "> ()</ span >
455+ < span class ="n "> wait_for_halt</ span > < span class ="p "> (</ span > < span class ="n "> target</ span > < span class ="p "> ,</ span > < span class ="n "> semihost</ span > < span class ="p "> )</ span >
456+
457+ < span class ="n "> pc</ span > < span class ="o "> =</ span > < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> read_core_register</ span > < span class ="p "> (</ span > < span class ="s "> "pc"</ span > < span class ="p "> )</ span >
458+ < span class ="k "> print</ span > < span class ="p "> (</ span > < span class ="s "> " pc: 0x%X"</ span > < span class ="o "> %</ span > < span class ="n "> pc</ span > < span class ="p "> )</ span >
459+ < span class ="k "> assert</ span > < span class ="n "> pc</ span > < span class ="o "> ==</ span > < span class ="n "> lr</ span > < span class ="o "> &</ span > < span class ="o "> ~</ span > < span class ="mh "> 0x01</ span > < span class ="c1 "> # mask off LSB
460+ </ span > < span class ="n "> target</ span > < span class ="p "> .</ span > < span class ="n "> remove_breakpoint</ span > < span class ="p "> (</ span > < span class ="n "> lr</ span > < span class ="p "> )</ span >
461+ </ code > </ pre > </ div > </ div >
354462
355463
356464 </ div >
0 commit comments