This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Test development using CLI/python/RTT

Hi,

I'd like to start developing automated tests for my custom NRF52840 board.

Currently I use the CLI library (with RTT backend) for communicating with the board.

Any ideas for how I could communicate with my board via a python script?

Thanks

Tim

Parents Reply Children
  • Hi Jørgen,

    I would like to avoid the middleman (CLI) and just use pynrfjprog directly.

    1. I plan to use the pynrfjprog read and write functions directly as you suggested. However, on the firmware side, I'm considering one potential issue: my logger uses the RTT backend. Would I have to disable  the logger?
    2. As for implmentation, would it make sense to use a repeating timer to call SEGGER_RTTRead() and have a task (I'm using FreeRTOS) decode the command, since there is no interrupt to tell when data is received in the RTT buffer?


    Tim

    1. RTT supports mulitple channels. If you want to keep logging, use another channel than 0 for the test communications.
    2. Yes, this makes sense to me.
  • Okay, so I tried using Channel 1 (both in my python script and firmware), Everytime I run the script, I hit a breakpoint in the code. Specifically, this breakpoint (in cmsis_gcc.h) is hit everytime I send a string from the script:

    __attribute__((always_inline)) __STATIC_INLINE void __SEV(void)
    {
      __ASM volatile ("sev");
    }

    And the program halts. Is this expected?

  • I have not experienced this. I did a test with a modified peripheral example, and a custom pynrfjprog sample. This seems to work as expected.

    rtt_writer_sdk_16.0.0.zip

    from __future__ import print_function
    
    # Import pynrfjprog API module
    from pynrfjprog import LowLevel
    from time import sleep
    
    
    def run(snr=None):
        """
        Run example script.
    
        @param (optional) int snr: Specify serial number of DK to run example on.
        """
        print('# RTT read example using pynrfjprog started...')
        
        # Detect the device family of your device. Initialize an API object with UNKNOWN family and read the device's family. This step is performed so this example can be run in all devices without customer input.
        print('# Opening API with device family UNKNOWN, reading the device family.')
        with LowLevel.API(LowLevel.DeviceFamily.UNKNOWN) as api:            # Using with construction so there is no need to open or close the API class.
            if snr is not None:
                api.connect_to_emu_with_snr(snr)
            else:
                api.connect_to_emu_without_snr()
            device_family = api.read_device_family()
        
        # Initialize an API object with the target family. This will load nrfjprog.dll with the proper target family.
        api = LowLevel.API(device_family)
        
        # Open the loaded DLL and connect to an emulator probe. If several are connected a pop up will appear.
        api.open()
        try:
    
            if snr is not None:
                api.connect_to_emu_with_snr(snr)
            else:
                api.connect_to_emu_without_snr()
    
            # Erase all the flash of the device.
            print('Starting RTT.')
            api.rtt_start()
    		
    		# rtt_start() API is non-blocking, need to wait for the control block to be found
            while(api.rtt_is_control_block_found() != True): 
    			print("waiting for control block")
    			sleep(0.1)
    
            channel_count_down, channel_count_up = api.rtt_read_channel_count()
            print("Found {} down channels and {} up channels".format(channel_count_down, channel_count_up))
    		
            rtt_string = {}
            for i in range(channel_count_down):
    			rtt_string[str(i)] = b''
    		
            while(True):
    			for i in range(channel_count_down):
    				r = api.rtt_read(i, 1)
    				if(len(r) != 0):
    					if(r == b'\n'):
    						print(rtt_string[str(i)])
    						rtt_string[str(i)] = b''
    					else:
    						rtt_string[str(i)] = rtt_string[str(i)] + r
            
            api.close()
    
            print('# Example done...')
    
        except LowLevel.APIError:
            api.close()
            raise
        
     
    if __name__ == '__main__':
        run()
    
    
    

    Did you SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS/SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS in your sdk_config.h file?

Related