While studying the k8055n-5.0.pas code to figure out the “new” protocol I spotted this:
function OpenDevice(CardNumber: integer): integer ; stdcall;
begin
CloseDevice;
givepath;
CloseDevice;
givepath;
CardAddress:=CardNumber;
if open[CardNumber] then
begin
result:=CardNumber;
Buf_tx[1]:=6; //check if New version
OutIn(CardAddress,1,1);
if Buf_rx[2]>10 then
begin
modeNew:=true;
if Buf_rx[2]<20 then // was in old mode
begin
OutIn(CardAddress,1,1);
givepath; // restart to clean the USB buffer
end;
end
else
modeNew:=false;
end
else
result:=-1;
end;
It seems to me that after successfully switching to the “new” protocol, the call to givepath commented “// restart to clean the USB buffer” is done while the cards are open, without a call to CloseDevice. Unless something was changed in the findpath module, this would leak two file handles per OpenDevice call for a K8055N that was in “old” mode.
Thank you for the feedback.
I think this will avoid the leak:function OpenDevice(CardNumber: integer): integer ; stdcall;
begin
CloseDevice;
givepath;
CloseDevice;
givepath;
CardAddress:=CardNumber;
if open[CardNumber] then
begin
result:=CardNumber;
Buf_tx[1]:=6; //check if New version
OutIn(CardAddress,1,1);
if Buf_rx[2]>10 then
begin
modeNew:=true;
if Buf_rx[2]<20 then // was in old mode
begin
OutIn(CardAddress,1,1);
CloseDevice; // avoid leak two file handles
givepath; // restart to clean the USB buffer
end;
end
else
modeNew:=false;
end
else
result:=-1;
end;
Note that this leak isn’t a serious problem. Once switched to “new” mode the K8055N stays in it until the controller is rebooted (disconnect/reconnect). So in order to leak a significant amount of handles one has to repeatedly reconnect the card while the application is constantly reopening it and is never restarted itself. I don’t think there are many cases like that out there. Including the fix whenever you actually need to publish a new version should be sufficient.
Yes, and this problem occurs only when the card switches from old (K8055) mode to new (K8055N) mode.
The card goes to old mode if used with an application using the old K8055 version of the DLL.
If then, without disconnecting the card, an application is run using the new K8055N DLL, the card switches to the new (K8055N) mode.
In this case the leakage occurs.
Now also same problem fixed in the function SetCurrentDevice.[code]function OpenDevice(CardNumber: integer): integer ; stdcall;
begin
CloseDevice; // make sure to close the file handle
givepath;
CloseDevice; // close the file handle
givepath;
CardAddress:=CardNumber;
if open[CardNumber] then
begin
result:=CardNumber;
Buf_tx[1]:=6; // check if New version
OutIn(CardAddress,1,1);
if Buf_rx[2]>10 then
begin
modeNew:=true;
if Buf_rx[2]<20 then // was in old mode
begin
OutIn(CardAddress,1,1);
CloseDevice; // close the file handle
givepath; // restart to clean the USB buffer
end;
end
else
modeNew:=false;
end
else
result:=-1;
end;
function SetCurrentDevice(CardNumber: integer): integer; stdcall;
var i:integer;
begin
if open[CardNumber] then
begin
CardAddress:=CardNumber;
for i:=0 to 8 do
Buf_tx[i]:=Buf_cards[i, CardAddress];
result:=CardNumber;
Buf_tx[1]:=6; // check if New version
OutIn(CardAddress,1,1);
if Buf_rx[2]>10 then
begin
modeNew:=true;
if Buf_rx[2]<20 then // was in old mode
begin
OutIn(CardAddress,1,1);
CloseDevice; // make sure to close the file handle
givepath; // restart to clean the USB buffer
end;
end
else
modeNew:=false;
end
else
result:=-1;
end;[/code]
I had a program that used three cards using both counters on each card. It was running in a VB2010 program for a form that was displaying counter values. the counter values were read in intervals set by a timer coded to the form.
It would have been nice if there were 5 hardware counters on the board so i didn’t have to go and buy 3 cards however the following code…
private sub getcounts()
opendevice(3)
label1.text = readcounter(1)
label2.text = readcounter(1)
opendevice(2)
label3.text =readcounter(1)
label4.text =readcounter(2)
opendevice(1)
label5.text =readcounter(1)
label6.text =readcounter(2)
end sub
The code was set to run every second so the counters on the form were updated every second. After 5 mins or less the cards crashed unitl having to unplug them and plug them back in.
I noticed that if I only used one card and used the opendevice() command on the form open then it would not happen. completely supports what you have explained here. this was with the driver 5.0.0 its all good now with 5.0.2.
can the pic be updated so I can have 5 hardware counters on the one board ?
should i be using setcurrentdevice ? whats the benefit ?
The card could be modified to Open8055. Currently the Open8055 firmware maintains 5 16-bit counters for the input ports. This could be enhanced to 32-bit ones.
You should do the three OpenDevice() calls, one for each card, on form open. Then use SetCurrentDevice() in the timer subroutine.
OpenDevice() is actually closing all currently open devices, then reopens them (through the givepath() function). SetCurrentDevice() switches to the requested one without the close/open.