Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flashing of file does not work without GUI progress bar #93

Closed
qwasko1212 opened this issue Apr 9, 2021 · 23 comments
Closed

Flashing of file does not work without GUI progress bar #93

qwasko1212 opened this issue Apr 9, 2021 · 23 comments

Comments

@qwasko1212
Copy link

qwasko1212 commented Apr 9, 2021

I have to develop an application that should operate without any GUI interface. When I am flashing target with a file using jlink.flash_file() it invokes GUI window with progress bar. I am running my application using ssh and I am getting the following exception

JLinkGUIServerExe: cannot connect to X server 
Traceback (most recent call last):
 File "_ctypes/callbacks.c", line 232, in 'calling callback function'
 File "/home/pi/Documents/host/.venv/lib/python3.7/site-packages/pylink/jlink.py", line 323, in <lambda>
   self.detailed_log_handler = lambda s: (detailed_log or logger.debug)(s.decode())
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 25: invalid start byte

This issue also present when I am running an App without a system launcher using raspberry py. Enabling ssh X forwarding is not an option.

I have also tried to supply on_progress callback to jlink.flash_file(), but it still does not prevent for invoking GUI progress bar.

@hkpeprah
Copy link
Contributor

hkpeprah commented Apr 9, 2021

You might want to try the disable_dialog_boxes() method.

@qwasko1212
Copy link
Author

qwasko1212 commented Apr 9, 2021

This is exactly what I need, but unfortunately, this does not work. I am calling methods as following:

self.jlink.disable_dialog_boxes()  # Disable GUI when flashing
self.jlink.flash_file(file, station.JLINK_FLASH_ADDR, self.on_progress)

However it still creates flashing window. I am using Raspberry OS (Debian).

@kettenbach-it
Copy link
Contributor

Same here

@kettenbach-it
Copy link
Contributor

kettenbach-it commented Apr 9, 2021

In jlink.py is says:

Dialog boxes only appear on Windows platforms.

That's not the case. Dialogboxes appear on MacOS and Linux as well (unfortunately)

@hkpeprah
Copy link
Contributor

hkpeprah commented Apr 9, 2021

Hey folks, sorry about the above, could you try the following and let me know if any of these work for you. You may need to combine them:

jl = pylink.JLink()

# Hide Device Selection
jl.exec_command('HideDeviceSelection = 1')
jl.exec_command('SuppressControlPanel')

# Hide Flash Windows
jl.exec_command('DisableInfoWinFlashDL')
jl.exec_command('DisableInfoWinFlashBPs')

I think it's fairly new that they appear on *nix platforms.

@kettenbach-it
Copy link
Contributor

Works on MacOS as well as on Linux!
Thanks for the quick fix! (This should make it into the source code as well)

@hkpeprah
Copy link
Contributor

hkpeprah commented Apr 9, 2021

Thanks @kettenbach-it for the quick look into this, and @qwasko1212 for raising it. I've marked this issue as a bug. I can submit a patch for this later today / over the weekend when I have time, but if y'all want to go ahead and submit a patch, I'd be happy to review later today and accept the change. The change would be to the disable_dialog_boxes() method to ensure it disables the flash windows too.

Probably update its docstring too to indicate it's not just Window.

@kettenbach-it
Copy link
Contributor

I'll submit a PR.

Can you have a look at #94 !? That's even more severe that this issue

hkpeprah pushed a commit that referenced this issue Apr 12, 2021
* #93 Fix disable_dialog_boxes
* #93 Re-enable the info windows: EnableInfoWinFlashBPs and EnableInfoWinFlashD
@hkpeprah
Copy link
Contributor

Fix should be present in v0.10.0 thanks to @kettenbach-it. @qwasko1212, please confirm if this resolves the issue for you.

@kettenbach-it
Copy link
Contributor

Mmm, there still a problem left:

I use "ssh -x" to login to the machine that runs the flash-code. "-x" disables the X-Server, which won't be available in my final production enviroment (docker). Docker ist the reason, why I need this whole thing to be a real shell application not depending on a running x-server.

Using pylink-0.10, flashing with this code works:

    # SuppressControlPanel
    jlink.exec_command("HideDeviceSelection = 1")
    jlink.exec_command("SuppressControlPanel")
    # Hide Flash Windows
    jlink.exec_command("DisableInfoWinFlashDL")
    jlink.exec_command("DisableInfoWinFlashBPs")

    jlink.erase()
    jlink.flash_file(FILE, 0)
    jlink.reset()

But flashing without the "exec_command" statements (lines 1-6), leads to this:

JLinkGUIServerExe: cannot connect to X server
Exception ignored on calling ctypes callback function: <function JLink.__init__.<locals>.<lambda> at 0xb619d070>
Traceback (most recent call last):
  File "/root/duravit-integration-api/venv/lib/python3.9/site-packages/pylink/jlink.py", line 323, in <lambda>
    self.detailed_log_handler = lambda s: (detailed_log or logger.debug)(s.decode())
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 25: invalid start byte

@kettenbach-it
Copy link
Contributor

I narrowed it down to

jlink.exec_command("DisableInfoWinFlashDL")

If this is not present in my program, I get the above error

@qwasko1212
Copy link
Author

@kettenbach-it I am using ssh without GUI and jlink.disable_dialog_boxes() disables all GUI windows.
"JLinkGUIServerExe: cannot connect to X server" means that windows were actually created, but it was not possible to show them. Just call jlink.disable_dialog_boxes() before flashing and the problem should be resolved.

P.s I tried to connect using ssh -x and for me everything is fine.

@kettenbach-it
Copy link
Contributor

🤦

@kettenbach-it
Copy link
Contributor

I can confirm: everything is fine now.
This ticket can be clsed

@NazarKostetskiy
Copy link

NazarKostetskiy commented Apr 14, 2021

If device is unplugged, using this code:

jlink = JLink()
jlink.exec_command('HideDeviceSelection = 1')
jlink.exec_command('SuppressControlPanel')
jlink.exec_command('DisableInfoWinFlashDL')
jlink.exec_command('DisableInfoWinFlashBPs')
jlink.disable_dialog_boxes()
jlink.open()

I'm getting this error:

JLinkGUIServerExe: cannot connect to X server Traceback (most recent call last): File "_ctypes/callbacks.c", line 232, in 'calling callback function' File "/home/pi/raspberry_web_service/venv/lib/python3.7/site-packages/pylink/jlink.py", line 323, in <lambda> self.detailed_log_handler = lambda s: (detailed_log or logger.debug)(s.decode())

pylink-square==0.10.0

@kettenbach-it
Copy link
Contributor

You didn't do a jlink.open()
Maybe the JLink-Tools want to raise a dialogue-box telling you that no device is open....
Try it with jlink.open() after JLink() and we'll see...

@NazarKostetskiy
Copy link

Did with jlink.open() after JLink() . Yep, seems like JLink is trying to raise dialog on open and cannot do that(tried with JLinkExe with Xorg and without Xorg). But I don't need any GUI and I want to disable it. With plugged device everything works fine.

DLL version V6.99c

@hkpeprah
Copy link
Contributor

The documentation seems to be a bit outdated on this, but the situation is as follows:

  • .open() takes a serial_no or ip_addr as arguments.
  • If ip_addr is specified, it tries to connect over IP.
  • If serial_no is specified, it tries to connect to the specific device with the given serial number.
  • If serial_no is not specified and ip_addr is not specified, it tries to connect to the first USB emulator device found.

In your case, you have no device plugged in at all, and it is probably raising some error dialog which is why you're running into the issue. Is there a use case for your flow of calling open() with no plugged in device? It should fail, so it's not unexpected that there is some weird issue going on. My suggestion would be to do something like this:

num_emulators = jl.num_connected_emulators()
if num_emulators == 1:
    # There is at least one device we can connect to.
    jl.open()
elif num_emulators > 1:
    raise RuntimeError('Multiple devices found.')
else:
    raise RuntimeError('No devices found.')

@NazarKostetskiy
Copy link

The documentation seems to be a bit outdated on this, but the situation is as follows:

  • .open() takes a serial_no or ip_addr as arguments.
  • If ip_addr is specified, it tries to connect over IP.
  • If serial_no is specified, it tries to connect to the specific device with the given serial number.
  • If serial_no is not specified and ip_addr is not specified, it tries to connect to the first USB emulator device found.

In your case, you have no device plugged in at all, and it is probably raising some error dialog which is why you're running into the issue. Is there a use case for your flow of calling open() with no plugged in device? It should fail, so it's not unexpected that there is some weird issue going on. My suggestion would be to do something like this:

num_emulators = jl.num_connected_emulators()
if num_emulators == 1:
    # There is at least one device we can connect to.
    jl.open()
elif num_emulators > 1:
    raise RuntimeError('Multiple devices found.')
else:
    raise RuntimeError('No devices found.')

Thanks. Good idea.

@cohen5790
Copy link

I am using an Educational (EDU) J-link. I have the disable_dialog_boxes() method and the exec_command() methods in my code, BUT I'm still getting a 'J-Link terms of use' Pop-Up window every time I run a J-link flash or erase method.

image

I want to disable all J-link GUI and windows to run my code on a headless Raspberry Pi 4. How can I disable this terms-of-service Pop-up?

`def erase_SensorHub():

device = "nRF52840_xxAA"
jlink = pylink.JLink()
jlink.open(serial_no=jlink_serial_no)

jlink.power_on()    
jlink.set_tif(pylink.JLinkInterfaces.SWD)    
jlink.connect(device, verbose=True)

jlink.disable_dialog_boxes()    
# Hide Device Selection
jlink.exec_command('HideDeviceSelection = 1')
jlink.exec_command('SuppressControlPanel')

# Hide Flash Windows
jlink.exec_command('DisableInfoWinFlashDL')
jlink.exec_command('DisableInfoWinFlashBPs')

jlink.erase() 

jlink.reset()
jlink.power_off()
jlink.close()`

@hkpeprah
Copy link
Contributor

hkpeprah commented Nov 7, 2022

@cohen5790, I don't think there is a way to remove that dialog as it's an EDU model.

@cohen5790
Copy link

cohen5790 commented Nov 7, 2022

@cohen5790, I don't think there is a way to remove that dialog as it's an EDU model.

Yes, I agree That would make sense for an EDU version.

There is also a method in pylink-square jlink.exec_command('SuppressGUI') that could be helpful for others.

@HelloMrWan
Copy link

@cohen5790 thanks,老哥牛逼,This command needs to be executed before each 'open'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants