Hello Everyone,
I've created GUIs for S32K boards with FreeMaster several times, but until now I only used the ActiveX interface and methods.
This time I tried to create GUI that uses JSON-RPC methods, by modifying an existing ActiveX GUI.
Help me to see what I miss.
First problem,
I started with simple variable reading. I use the following fields for feedback.
Here we can see, that I received a positive feedback from the pcm.OnBoardDetected and from the pcm.IsCommPortOpen() methods. Only after that I tried to read a variable, but I received the following error message: "ReadVariable: Could not read the variable 'FMSTR_u32FwVversion[0]'. Error 0x8000fffb (Communication port is not opened.)."
Interesting is, that when I call the same ReadVariable method manually with a button, it works.
code sniplet:
pcm.ReadVariable(name)
.then((response) => {
$("#mcu_ic_text").val("Variable value: " + response.data);
})
.catch((err) => {
on_error(err.msg);
});
But I need to read variables automatically when the board connects.
Second,
When I click refresh (F5), it seems like nothing works that worked until that point. I have in the main() function, which is called after the refresh, a pcm.IsCommPortOpen() and a pcm.IsBoardDetected() methods, but they don't deliver any response after the refresh.
function main() {
pcm = new PCM("localhost:41000", on_connected, on_error, on_error);
pcm.OnServerError = on_error;
pcm.OnSocketError = on_error;
pcm.IsCommPortOpen().then(response => {
$("#pcb_version_text").val("Port status: " + response.data);
});
pcm.IsBoardDetected()
.then((response) => {
$("#nfc_ic_text").val("board:");
})
.catch((err) => {
on_error(err.msg);
});
}
PS:
I'm looking forward to an answer and thanks for any suggestions.
Best regards,
Kornel Lengl
Hi @iulian_stan,
Thanks for your suggestions, I moved the pcm.IsCommPortOpen() and the pcm.IsBoardDetected() methods to the on_connected method. Now they work after the refresh.
But moving the pcm.ReadVariable didn't solve the problem.
I include the JS and the HTML files so you can see that in the on_connected method I check if the board is connected and if the comm port is open. And after that I call the pcm.ReadVariable, but it returns an error, that says: "ReadVariable: Could not read the variable 'FMSTR_u32FwVversion[0]'.
Error 0x8000fffb (Communication port is not opened.).".
I can read variables, with an additional button like in the example.htm, but I need to read variables after the board is connected automatically.
Best regards,
Kornel Lengl
Hi @nxf63246,
I did not see any issues in your example nor I was able to reproduce your issue. The only "abnormal" case when I was able to get the error was when I disconnected the board before the JS code executed. My steps :
Actually, I could say IsCommPortOpen call is redundant because OnBoardDetected implies the communication port is already open. To add an extra check could you move read_variable into .then method of the pcm.IsCommPortOpen promise to make sure that the port is open before the variable is read:
function boardDetected()
{
//These feedbacks get printed succesfully
$("#board_detected_text").val("Board connected +");
pcm.IsCommPortOpen().then(response => {
$("#port_status_text").val("Port status: " + response.data);
read_variable("FMSTR_u32FwVversion[0]");
});
}
Thank you @iulian_stan for you time and suggestions, but I still get the same error message for the immediate variable reading, even if I move the read_variable() function into .then method of the pcm.IsCommPortOpen, just like this:
pcm.IsCommPortOpen().then(response => {
$("#port_status_text").val("Port status: " + response.data);
//response.data = true
read_variable("FMSTR_u32FwVversion[0]");// the same error message as before
});
I can make the FMSTR to wait for the variable like this, but this is very poor:
setInterval(function(){ pcm.ReadVariable("FMSTR_PcbVersionLength")
.then((response) => {
pcb_version_length = response.data; //this works
}) }, 100);
PS: also an interesting thing that the variable watch sees all the variable values immediately, the problem is only with the displaying
Hi @nxf63246,
Apologies for the delayed reply.
Could you please attach your communication log. You can access the logger on the top menu bar:
Tools → Communication Debug Log...
Just make sure you open it before you connect to the board (press the "Go!" button) so it can catches all the messages from the start.
Hi @iulian_stan,
On this communication log you can see the error for the pcm.ReadVariable() function. And after that the successful variable reads for the variable watch.
On this one, you can see the same failed variable read and the successful one with the button, mentioned earlier.
Best regards
Hi @nxf63246,
I was able to reproduce your issue - it happens only when the variable info is loaded from an ELF file (I was using TSA in my tests, but from your logs I noticed that in your case TSA call fails meaning it is not used).
Unfortunately I don't have a solution, we will further investigate this issue. As a workaround I could suggest:
var retry = 3;
function read_variable(name)
{
/* ReadVariable uses FreeMASTER variable object from current project. Use
* ReadUIntVariable to access the memory directly using a symbol name. */
pcm.ReadVariable(name)
.then((response) => {
$("#var_read_text").val("Variable value: " + response.data);
})
.catch((err) => {
if (retry--) {
setTimeout(() => read_variable(name), 100);
} else {
retry = 3;
on_error(err.msg);
}
});
}
I will post updates on this thread once we find the root cause of this issue.
Hello nxf63246,
I confirm the issue in the FreeMASTER desktop application. The OnCommPortStateChanged(true) and OnBoardDetected() events are triggered prematurely. Variables which are accessed within approximately 100ms after these events may return the 'port not open' error.
The reason why the issue appears only when using an ELF file but not with TSA is just a question of processing speed. The ELF file is read much faster than TSA.
The simplest fix is to delay the event handler execution:
pcm.OnBoardDetected = ()=>setTimeout(MyOnBoardDetectedHandler, 100);
pcm.OnCommPortStateChanged = (x)=>setTimeout(()=>MyOnCommPortStateChangedHandler(x), 100);
As the FreeMASTER 3.1.3 version is just being published, this issue will be fixed later, in a next version planned for Q1/2022. I can provide a hotfix version if you need it.
Thank you for your report & to Iulian for support,
Michal
Hi @nxf63246,
My guess is that it may be related to the JS reactive pattern - the Variable read function should be called inside a successful connection or board detected callback function ex:
pcm.OnBoardDetected = function() {
pcm.ReadVariable(name)
.then((response) => {
$("#mcu_ic_text").val("Variable value: " + response.data);
})
.catch((err) => {
on_error(err.msg);
});
}
Regarding the second part - there's a similar issue in your code snippet - you do not wait for the connection to be established:
function main() {
pcm = new PCM("localhost:41000", on_connected, on_error, on_error);
pcm.OnServerError = on_error;
pcm.OnSocketError = on_error;
pcm.IsCommPortOpen().then(response => { // there is no guarantee that pcm is connected to localhost at this point
$("#pcb_version_text").val("Port status: " + response.data);
});
pcm.IsBoardDetected() // there is no guarantee that pcm is connected to localhost at this point
.then((response) => {
$("#nfc_ic_text").val("board:");
})
.catch((err) => {
on_error(err.msg);
});
}
All pcm functions calls (ex: IsCommPortOpen, IsBoardDetected ...) should be made inside or after "on_connected" function is executed - that's when pcm is actually connected to FreeMASTER server.
If moving those calls does not solve your issues please share your HTML/JS code with us.