<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Pynrfjprog create dummy thread, how to avoid/delete them ?</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/94079/pynrfjprog-create-dummy-thread-how-to-avoid-delete-them</link><description>Hi, 
 
 I&amp;#39;m devlopping python (v3.9.6) software to flash nRF52832 using pynrfjprog (v10.17.3) package. 
 The soft is a loop trying to erase and flash. But while debugging with VSCode, I see that pynrfjprog package create &amp;quot;Dummy-X&amp;quot; threads and never release</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 28 Nov 2022 09:50:49 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/94079/pynrfjprog-create-dummy-thread-how-to-avoid-delete-them" /><item><title>RE: Pynrfjprog create dummy thread, how to avoid/delete them ?</title><link>https://devzone.nordicsemi.com/thread/397811?ContentTypeID=1</link><pubDate>Mon, 28 Nov 2022 09:50:49 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e5edf9f3-446b-42d9-af27-47f4bcba48ec</guid><dc:creator>AntoineB</dc:creator><description>&lt;p&gt;Hi Einarh,&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Thank for your reply. I will try to perform others tests then. &lt;br /&gt;For now I call .exe with pynrfjprog HighLevel in order to avoid created and never release threads.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Antoine&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Pynrfjprog create dummy thread, how to avoid/delete them ?</title><link>https://devzone.nordicsemi.com/thread/397809?ContentTypeID=1</link><pubDate>Mon, 28 Nov 2022 09:43:57 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e01384f8-82ae-47aa-96d4-d7a2bc9f8e92</guid><dc:creator>Einarh</dc:creator><description>&lt;p&gt;Hi again&lt;/p&gt;
&lt;p&gt;We are not able to reproduce your issue with the low level API on our end.&lt;/p&gt;
&lt;p&gt;Your &amp;quot;dummy threads&amp;quot; are probably C++ threads that aren&amp;#39;t terminated properly, and are likely caused by how you use your class.&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Einar&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Pynrfjprog create dummy thread, how to avoid/delete them ?</title><link>https://devzone.nordicsemi.com/thread/397493?ContentTypeID=1</link><pubDate>Thu, 24 Nov 2022 15:44:17 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a85b0d91-6532-455e-a45a-c0648fd70d95</guid><dc:creator>AntoineB</dc:creator><description>&lt;p&gt;Hi again Einarh,&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Do you have any clue on why this threads are created and never deleted ?&lt;/p&gt;
&lt;p&gt;Thanks in advance for your help.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Best regard,&lt;/p&gt;
&lt;p&gt;Antoine&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Pynrfjprog create dummy thread, how to avoid/delete them ?</title><link>https://devzone.nordicsemi.com/thread/396999?ContentTypeID=1</link><pubDate>Tue, 22 Nov 2022 16:54:53 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:fa72019f-c59c-4327-8e5c-bd08f9dd6a20</guid><dc:creator>AntoineB</dc:creator><description>&lt;p&gt;Hi Einarh,&lt;/p&gt;
&lt;p&gt;Thanks for the quick reply. I&amp;#39;ve just tested the code you sent but with LowLevel api, Dummy threads are created when calling LowLevel.API to be used as api (line 57) but they are not deleted even with adding api.close()&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Antoine&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Pynrfjprog create dummy thread, how to avoid/delete them ?</title><link>https://devzone.nordicsemi.com/thread/396837?ContentTypeID=1</link><pubDate>Tue, 22 Nov 2022 09:35:59 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:170e167a-71fe-4dc3-b278-05d734175a7a</guid><dc:creator>Einarh</dc:creator><description>&lt;p&gt;You can try to use LowLevel instead:&lt;/p&gt;
&lt;p&gt;(you might have to set up your logfilter again)&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="python"&gt;import logging
from pynrfjprog import LowLevel
import threading

class nRF528XXFlasher:
    flashers = dict()
    semaphore = threading.BoundedSemaphore(value=1)
    
    def __init__(self, snr=None, config={}, logger=None):
        self.config = config
        
        if logger is None:
            self.logger = logging.getLogger(__name__)
        else:
            self.logger = logger.getChild(__name__)
        self.logger.setLevel(self.config.get(&amp;quot;log_level&amp;quot;, &amp;quot;INFO&amp;quot;))
        
        try:
            nRF528XXFlasher.semaphore.acquire(timeout=3)
            if snr is None:
                snr = self._get_random_snr()
            self.snr = snr
            nRF528XXFlasher.flashers[snr] = self
        finally:
            nRF528XXFlasher.semaphore.release()
            
        # Catch and redirect logs from the probe
        class ProbeLogFilter(logging.Filter):
            def __init__(self, flasher, name=&amp;quot;&amp;quot;):
                super().__init__(name)
                self.flasher = flasher
                
            def filter(self, record):
                if self.flasher.config.get(&amp;quot;nRF528XX_flasher_enable_log&amp;quot;, False):
                    if str(self.flasher.snr) in record.name:
                        self.flasher.logger.handle(record)
                return False
                
        logging.getLogger(f&amp;quot;HighLevel.Probes.{self.snr}&amp;quot;).addFilter(ProbeLogFilter(flasher=self))
        
    def _get_random_snr(self):
        with LowLevel.API(LowLevel.DeviceFamily.UNKNOWN) as api:
            probes_snrs = set(api.enum_emu_snr())
            self.logger.debug(f&amp;quot;nRF528XXFlasher possible serials : {probes_snrs}&amp;quot;)
            available_snrs = probes_snrs.difference(nRF528XXFlasher.flashers.keys())
            if not available_snrs:
                raise AssertionError(&amp;quot;No available snrs&amp;quot;)
            return available_snrs.pop()
            
    def __del__(self):
        for snr in nRF528XXFlasher.flashers:
            if nRF528XXFlasher.flashers[snr] == self:
                nRF528XXFlasher.flashers.pop(snr)
                break
                
    def erase_app(self):
        with LowLevel.API(LowLevel.DeviceFamily.NRF52, log=self.config.get(&amp;quot;nRF528XX_flasher_enable_log&amp;quot;)) as api:
            api.connect_to_emu_with_snr(self.snr)
            api.erase_all()
        return True
        
    def flash_app(self, hex_file):
        with LowLevel.API(LowLevel.DeviceFamily.NRF52, log=self.config.get(&amp;quot;nRF528XX_flasher_enable_log&amp;quot;)) as api:
            api.connect_to_emu_with_snr(self.snr)
            api.program_file(hex_file)
            api.verify_file(hex_file)
            api.sys_reset()
        return True&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;-Einar&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Pynrfjprog create dummy thread, how to avoid/delete them ?</title><link>https://devzone.nordicsemi.com/thread/396716?ContentTypeID=1</link><pubDate>Mon, 21 Nov 2022 15:01:18 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:68998007-3558-4b3b-b93a-30279a36728f</guid><dc:creator>AntoineB</dc:creator><description>&lt;p&gt;Hi Einar,&lt;br /&gt;&lt;br /&gt;It is in fact my own code. Please find bellow the script I&amp;#39;m using:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;import logging
import pynrfjprog.HighLevel
import threading

class nRF528XXFlasher():
    api = None
    flashers = {}
    semaphore = threading.BoundedSemaphore(value=1)

    def __init__(self, snr=None, config={}, logger=None):
        self.config = config

        if logger is None:
            self.logger = logging.getLogger(__name__)
        else:
            self.logger = logger.getChild(__name__)

        self.logger.setLevel(self.config.get(&amp;quot;log_level&amp;quot;, &amp;quot;INFO&amp;quot;))

        try:
            nRF528XXFlasher.semaphore.acquire(timeout=3)

            if nRF528XXFlasher.api is None:
                nRF528XXFlasher.api = pynrfjprog.HighLevel.API(self.config.get(&amp;quot;nRF528XX_flasher_enable_log&amp;quot;, False))

            if not nRF528XXFlasher.api.is_open():
                nRF528XXFlasher.api.open()

            if snr is None:
                probes_snrs = nRF528XXFlasher.api.get_connected_probes()
                if len(probes_snrs) &amp;gt; 0:
                    self.logger.debug(f&amp;quot;nRF528XXFlasher possible serials : {probes_snrs}&amp;quot;)
                    for probe_snr in probes_snrs:
                        logger.debug(probe_snr)
                        if probe_snr not in nRF528XXFlasher.flashers:
                            snr = probe_snr
                            break
        finally:
            nRF528XXFlasher.semaphore.release()

        self.snr = snr
        if self.snr is None:
            raise Exception(f&amp;quot;nRF528XX Flasher probe not found ({self.snr})&amp;quot;)

        nRF528XXFlasher.flashers[snr] = self

        # Catch and redirect logs from the probe
        class ProbeLogFilter(logging.Filter):
            def __init__(self, flasher, name=&amp;quot;&amp;quot;):
                super().__init__(name)
                self.flasher = flasher

            def filter(self, record):
                if self.flasher.config.get(&amp;quot;nRF528XX_flasher_enable_log&amp;quot;, False):
                    if str(self.flasher.snr) in record.name:
                        self.flasher.logger.handle(record)
                return False

        logging.getLogger(f&amp;quot;pynrfjprog.HighLevel.Probes.{self.snr}&amp;quot;).addFilter(
            ProbeLogFilter(flasher=self))

    def __del__(self):
        for snr in nRF528XXFlasher.flashers:
            if nRF528XXFlasher.flashers[snr] == self:
                nRF528XXFlasher.flashers.pop(snr)
                break
        if len(nRF528XXFlasher.flashers) &amp;lt;= 0:
            if nRF528XXFlasher.api.is_open():
                nRF528XXFlasher.api.close()

    def erase_app(self):
        with pynrfjprog.HighLevel.DebugProbe(nRF528XXFlasher.api, self.snr, log=self.config.get(&amp;quot;nRF528XX_flasher_enable_log&amp;quot;, True)) as probe:
            probe.erase(erase_action=pynrfjprog.HighLevel.EraseAction.ERASE_ALL)
        return True

    def flash_app(self, hex_file):
        with pynrfjprog.HighLevel.DebugProbe(nRF528XXFlasher.api, self.snr, pynrfjprog.HighLevel.CoProcessor.CP_APPLICATION, log=self.config.get(&amp;quot;nRF528XX_flasher_enable_log&amp;quot;, True)) as probe:
            probe.program(hex_file, program_options=pynrfjprog.HighLevel.ProgramOptions(verify=pynrfjprog.HighLevel.VerifyAction.VERIFY_READ, erase_action=pynrfjprog.HighLevel.EraseAction.ERASE_ALL, reset=pynrfjprog.HighLevel.ResetAction.RESET_SYSTEM))
        return True&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Antoine&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Pynrfjprog create dummy thread, how to avoid/delete them ?</title><link>https://devzone.nordicsemi.com/thread/396705?ContentTypeID=1</link><pubDate>Mon, 21 Nov 2022 14:41:18 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6be102d7-4c14-4913-bb5e-5aa92c2b79e0</guid><dc:creator>Einarh</dc:creator><description>&lt;p&gt;Hello&lt;/p&gt;
&lt;p&gt;What software are you using to flash exactly? Is it a script you wrote yourself?&lt;/p&gt;
&lt;p&gt;If so, please share your script.&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Einar&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>