code: async def _upload_to_module(hw, serialnum, fw_filename, loop):
      
  
      # ensure there is a reference to the port
      if not hw.is_connected():
          hw.connect()
  
      hw.discover_modules()
      hw_mods = hw.attached_modules.values()
  
      res = {}
      for module in hw_mods:
          if module.device_info.get('serial') == serialnum:
              log.info("Module with serial {} found".format(serialnum))
              bootloader_port = await modules.enter_bootloader(module)
              if bootloader_port:
                  module._port = bootloader_port
              # else assume old bootloader connection on existing module port
              log.info("Uploading file to port: {}".format(
                  module.port))
              log.info("Flashing firmware. This will take a few seconds")
              try:
                  res = await asyncio.wait_for(
                      modules.update_firmware(
                          module, fw_filename, loop),
                      UPDATE_TIMEOUT)
              except asyncio.TimeoutError:
                  return {'message': 'AVRDUDE not responding'}
              break
      if not res:
          res = {'message': 'Module {} not found'.format(serialnum)}
      return res
docs: This method remains in the API currently because of its use of the robot
      singleton's copy of the api object & driver. This should move to the server
      lib project eventually and use its own driver object (preferably involving
      moving the drivers themselves to the serverlib)