Jump to content
  • 0

DD via Waveforms and AD2 via SDK on the same PC


sintech

Question

Hello,

I'm trying to use DD in WF as logic analyzer connected to the outputs of my DUT.

And at the same time I send test signals to the DUT inputs using AD2 DIO via Python SDK.

In python I'm getting an error "b'The device is being used by another application SERC: 0x3E9\nDevice programming failed.\n'"

If I select "DDiscovery DEMO" in WF, python script works fine.

 

Is this kind of setup supported?

It would be nice to have power of WF visualization and flexibility of SDK at the same time.

 

Link to comment
Share on other sites

5 answers to this question

Recommended Posts

It seem that this issue was caused by not closing device via SDK properly.

If I stop my python script prematurely without calling "dwf.FDwfDeviceClose(AD2)", it can't connect to AD2 next time.

If I reselect DD in WF Device manager, AD2 works via SDK again. Strange but true...

Link to comment
Share on other sites

Hi @sintech

In case the application/script is killed it remains marked being busy in the shared memory device list .
This list is kept by Adept Runtime.

@malexander

Could we solve this ?
To reproduce it under Windows:
- connect any two devices (AD1, 2, ADS or DD) and open two instances of WF app to connect to both
- kill one instance of the app (win device manager, end task)
- open new WF(2) instance, this will fail to connect to the device(2), the Djtg/DptiEnable JtscInitScanChain will fail
- reconnect with the other WF(1) app to the device(1) (WF device manager Select)
- now the WF(2) will allow to connect to the device(2)
I have tried this with Adept Runtime 2.19.2 and 2.21.2

With ADP all app instances need to be closed. I guess the SysReset command is sent only when there is no active connection to any device.

Link to comment
Share on other sites

@attila

I was able to reproduce this using Waveforms and the Adept test application.

1. Open Waveforms 1 and connect to device A
2. Open Waveforms 2 and connect to device B
3. Used task manager to kill Waveforms 2
4. Run "test DjtgPortEn -d Discovery2 -n 1 -enpriv -c 1" and get "failed to enable jtag for device: Discovery2"
5. Run "test DptiPortEn -d Discovery2 -n 1 -enpriv -c 2" and get "failed to enable PTI port 0 for device Discovery2"
6 .If I start a new instance of Waveforms and connect to device B the behavior is as you described, Waveforms says "No device detected" and if I go to device manager I see device A and B both listed as in use.

I modified the FTDIFW_60 DLL (used by AD, AD2, DD) to skip the steps involving writing and checking fsDptEnabled (checking for port conflicts). You'd expect this to allow two or more handles to enable the same JTG or DPTI port, but it doesn't because the enable command locks a named mutex to gain exclusive access to the FTDI interface utilized by the port. The mutex is held until the port is disabled or until the process/thread crashes or is killed. If one process owns the lock then the next process (or handle from the same process) to call the enable function will receive the same dcap conflict that it would have received had the fsDptEnabled check been used. I perform the following steps with this modified DLL.

1. Open Waveforms 1 and connect to device A
2. Open Waveforms 2 and connect to device B
3. Used task manager to kill Waveforms 2
4. Run "test DjtgPortEn -d Discovery2 -n 1 -enpriv -c 2" and get "Pass"
5. Run "test DptiPortEn -d Discovery2 -n 1 -enpriv -c 2" and get "Pass"
6. Run new instance of waveforms and receive No Device error. This is surprising since the Adept test suite was able to enable both the DJTG and DPTI port of device B. Yet the Waveforms device manager still shows "Used by other application" as the Status in the device manager. Oddly enough it will open device B if I highlight it and click "select". I'm not sure which Adept API calls Waveforms makes before concluding that the device is used by another application, but I assumed it was DjtgEnable or DptiEnable. Perhaps there's another API being called and that API is still failing. Can you tell me which API function(s) you call to determine that the device is in use?

So the next question that someone is going to ask is why even perform the fsDptEnabled checks and not rely entirely on the interface mutex that can be recovered from a dead process/thread? One reason I can think of is because some devices (Nexys Video and Genesys 2) support DJTG on one interface of the USB controller and DPTI (async and sync) on the other interface of the same controller. There's no issue with allowing the DJTG and async DPTI to be enabled at the same time because they are on separate interfaces and no resources are shared. However, the USB controller uses some of the resources from both channels when the sync DPTI interface is enabled. In this case we don't want to allow both DJTG and sync DPTI to be enabled and have been relying on fsDptEnabled for that.

Another thing is that the fsDptEnabled checks existed before the interface locks. Those were added later to support cooperative locking with the Xilinx tools.

I could probably modify all of the FDTIFW DLLs to rely on interface locks and remove the fsDptEnabled checks to work around this issue. Most of the effort would be spent testing this with all of the existing the devices across all of the platforms. However, I'm not sure this is the correct solution and haven't taken the time to investigate which other resources are left in a bad state when an application is killed (or exits) without disabling the active ports and closing the interface handles.

It's tempting to install a signal handler to try to perform cleanup when the process is killed, but we can't really do that at the DLL level. If a signal handler were used it'd need to be installed at the application level.

You mentioned SysReset. The SysReset command may be sent when the application opens an HIF if it's the only HIF on the system referencing a particular device. If there are any other handles referenced against the same device then SysReset doesn't get sent. In the scenario that was described here the 2nd device will remain in DVTOPN with a non-zero reference count because the process was killed before DmgrClose() was executed and the shared memory doesn't get free'd up or re-initialized until all processes that are referencing it exit. So we can't really rely on SysReset to save the day, even if the device does execute that command.

I don't remember how the bare metal implementation processes SysReset on the ADP but the Linux implementation will only clear fsDptEnabled when SysReset is received over the USB interface, and only if the number of connected TCPIP clients is equal to zero. It doesn't clear fsDptEnabled when the SysReset comes from a TCPIP client because there presently isn't any mechanism for detecting if the USB interface is in use by a PC application.

Link to comment
Share on other sites

@attila

Ok now the behavior makes sense. dinfoOpenCount comes from the reference count for the device that's stored in shared memory and isn't decremented until DmgrClose is called with an HIF referencing the device. I would also expect the reference count to remain non-zero if there are two processes running and one of them does not call DmgrClose before exiting, even if exits normally. I remember Tommy running into this when he created one of the USB104 demos because he wasn't consistently calling DmgrClose before exiting.

One other thing that occurred to me - dinfoOpenCount may be 0 for a device with Ethernet, but that device may be in use by Waveforms on another PC on the local network. In this case the port enable call would fail when Waveforms tries to open it on the 2nd PC.

Off the top of my head I don't have a good solution to any of the issues that we've discussed here. These will get put on a list of open issues and we can discuss them offline.

Thanks,
Michael

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...