def set_app_mode(handler, verbose=False): from piksi_tools.bootload import Bootloader """ Set Piksi into the application firmware, regardless of whether it is currently in the application firmware or the bootloader. Will raise a piksi_tools.timeout.TimeoutError if Piksi responses appear to have hung. Parameters ========== handler : sbp.client.handler.Handler handler to send/receive messages from/to Piksi. verbose : bool Print more verbose output. """ if verbose: print("Setting device into application mode") # Wait until we receive a heartbeat or bootloader handshake so we # know what state Piksi is in. with Bootloader(handler) as piksi_bootloader: heartbeat = Heartbeat() handler.add_callback(heartbeat, SBP_MSG_HEARTBEAT) if verbose: print("Waiting for bootloader handshake or heartbeat from device") with Timeout(TIMEOUT_BOOT) as timeout: while not heartbeat.received and not piksi_bootloader.handshake_received: time.sleep(0.1) handler.remove_callback(heartbeat, SBP_MSG_HEARTBEAT) # If Piksi is in the application, simply return. if heartbeat.received: if verbose: print("Received heartbeat") return # Piksi is in the bootloader, tell Piksi to jump into the application. with Timeout(TIMEOUT_BOOT) as timeout: if verbose: print("Waiting for bootloader handshake from device") piksi_bootloader.handshake() piksi_bootloader.jump_to_app() if verbose: print("Received handshake") if verbose: print("Telling device to jump to application") # Wait for Heartbeat to ensure we're in the application firmware. heartbeat = Heartbeat() handler.add_callback(heartbeat, SBP_MSG_HEARTBEAT) if verbose: print("Waiting for heartbeat") with Timeout(TIMEOUT_BOOT) as timeout: while not heartbeat.received: time.sleep(0.1) if verbose: print("Received heartbeat") handler.remove_callback(heartbeat, SBP_MSG_HEARTBEAT)
def test_jump_to_app(self): """ Test that we can jump to the application after programming. """ unittest.skipIf(self.skip_single, 'Skipping single Piksi tests') if self.verbose: print "--- test_jump_to_app ---" with serial_link.get_driver(use_ftdi=False, port=self.port1) as driver: with Handler(driver.read, driver.write) as handler: with Bootloader(handler) as piksi_bootloader: if self.verbose: print "Handshaking with bootloader" piksi_bootloader.handshake() if self.verbose: print "Jumping to application" piksi_bootloader.jump_to_app() # If we succesfully jump to the application, we should receive # Heartbeat messages. with Timeout(TIMEOUT_BOOT) as timeout: heartbeat = Heartbeat() handler.add_callback(heartbeat, SBP_MSG_HEARTBEAT) if self.verbose: print "Waiting to receive heartbeat" while not heartbeat.received: time.sleep(0.1) if self.verbose: print "Received hearbeat" handler.remove_callback(heartbeat, SBP_MSG_HEARTBEAT)
def __init__(self, link): """ Parameters ========== link : sbp.client.handler.Handler link to register Heartbeat message callback with sbp_version : tuple (int, int) SBP version to use for STM Unique ID messages. """ self.unique_id_returned = False self.unique_id = None self.link = link self.heartbeat = Heartbeat()
def test_btldr_handshake_wrong_sender_id(self): """ Test setting Piksi into bootloader mode with an incorrect sender ID (should fail). """ unittest.skipIf(self.skip_single, 'Skipping single Piksi tests') if self.verbose: print("--- test_btldr_handshake_wrong_sender_id ---") with serial_link.get_driver(use_ftdi=False, port=self.port1) as driver: with Handler(driver.read, driver.write) as handler: # Make sure device is in the application firmware. set_app_mode(handler, self.verbose) # Reset Piksi, and attempt to handshake into bootloader mode with an # incorrect sender ID. if self.verbose: print("Sending reset") handler.send(SBP_MSG_RESET, "") with Bootloader(handler) as piksi_bootloader: with Timeout(TIMEOUT_BOOT) as timeout: if self.verbose: print( "Waiting for bootloader handshake from device") while not piksi_bootloader.handshake_received: time.sleep(0.1) if self.verbose: print("Received handshake") if self.verbose: print("Sending handshake with incorrect sender ID") handler.send(SBP_MSG_BOOTLOADER_HANDSHAKE_REQ, '\x00', sender=0x41) # We should receive a heartbeat if the handshake was unsuccessful. with Timeout(TIMEOUT_BOOT) as timeout: heartbeat = Heartbeat() handler.add_callback(heartbeat, SBP_MSG_HEARTBEAT) if self.verbose: print("Waiting to receive heartbeat") while not heartbeat.received: time.sleep(0.1) if self.verbose: print("Received hearbeat") handler.remove_callback(heartbeat, SBP_MSG_HEARTBEAT)
def test_get_versions(self): """ Get Piksi bootloader/firmware/NAP version from device. """ unittest.skipIf(self.skip_single, 'Skipping single Piksi tests') if self.verbose: print("--- test_get_versions ---") with serial_link.get_driver(use_ftdi=False, port=self.port1) as driver: with Handler(driver.read, driver.write) as handler: with Bootloader(handler) as piksi_bootloader: # Get bootloader version, print, and jump to application firmware. with Timeout(TIMEOUT_BOOT) as timeout: if self.verbose: print("Waiting for bootloader handshake") piksi_bootloader.handshake() piksi_bootloader.jump_to_app() print("Piksi Bootloader Version:", piksi_bootloader.version) # Wait for heartbeat, get settings, print firmware/NAP versions. heartbeat = Heartbeat() handler.add_callback(heartbeat, SBP_MSG_HEARTBEAT) if self.verbose: print("Waiting to receive heartbeat") while not heartbeat.received: time.sleep(0.1) if self.verbose: print("Received hearbeat") handler.remove_callback(heartbeat, SBP_MSG_HEARTBEAT) if self.verbose: print("Getting Piksi settings") settings = self.get_piksi_settings(handler) if self.verbose: print("Piksi Firmware Version:", \ settings['system_info']['firmware_version']) if self.verbose: print("Piksi NAP Version:", \ settings['system_info']['nap_version'])
def setup_piksi(handler, stm_fw, nap_fw, verbose=False): """ Set Piksi into a known state (STM / NAP firmware). Erases entire STM flash (except for bootloader sector). Requires Piksi have a valid STM firmware sending heartbeat messages and with the reset callback registered. Will raise a timeout.TimeoutError if Piksi responses appear to have hung. Parameters ========== handler : sbp.client.handler.Handler handler to send/receive SBP messages to/from Piksi through. stm_fw : intelhex.IntelHex firmware to program Piksi STM with. nap_fw : intelhex.IntelHex firmware to program Piksi NAP with. verbose : bool Print more verbose output. """ # Wait until we receive a heartbeat or bootloader handshake so we # know what state Piksi is in. with Bootloader(handler) as piksi_bootloader: heartbeat = Heartbeat() handler.add_callback(heartbeat, SBP_MSG_HEARTBEAT) # Throw an exception if a heartbeat or handshake # is not received for 5 seconds. with Timeout(TIMEOUT_BOOT) as timeout: if verbose: print "Waiting for Heartbeat or Bootloader Handshake" while not heartbeat.received and not piksi_bootloader.handshake_received: time.sleep(0.1) # If Piksi is in the application, reset it into the bootloader. if heartbeat.received: if verbose: print "Received Heartbeat, resetting Piksi" handler.send(SBP_MSG_RESET, "") handler.remove_callback(heartbeat, SBP_MSG_HEARTBEAT) with Timeout(TIMEOUT_BOOT) as timeout: piksi_bootloader.handshake() bootloader_version = piksi_bootloader.version if verbose: print "Received bootloader handshake" with Flash(handler, flash_type="STM", sbp_version=piksi_bootloader.sbp_version) as piksi_flash: # Erase entire STM flash (except bootloader). if verbose: print "Erasing STM" with Timeout(TIMEOUT_ERASE_STM) as timeout: for s in range(1, 12): piksi_flash.erase_sector(s) # Write STM firmware. with Timeout(TIMEOUT_PROGRAM_STM) as timeout: if verbose: if verbose: print "Programming STM" piksi_flash.write_ihx(stm_fw, sys.stdout, 0x10, erase=False) else: piksi_flash.write_ihx(stm_fw, erase=False) with Flash(handler, flash_type="M25", sbp_version=piksi_bootloader.sbp_version) as piksi_flash: # Write NAP hexfile. with Timeout(TIMEOUT_WRITE_NAP) as timeout: if verbose: if verbose: print "Programming NAP" piksi_flash.write_ihx(nap_fw, sys.stdout, 0x10) else: piksi_flash.write_ihx(nap_fw) # Jump to the application firmware. if verbose: print "Jumping to application" piksi_bootloader.jump_to_app()