I am programming a C# application which will be used to program and test STM32 microcontrollers during production. I would like to program and verify the chip, then write some configuration to the flash memory and finally set the read-out protection. As a backend I decided to use OpenOCD and its Tcl interface running at port 6666.
The problem: I am able to execute commands and get their results, but I don't know how to check if the command was successfully executed or not. E.g. the reset command returns empty string no matters the target is connected or not... Some other commands like mdw return data or error string, but I am looking for some generic way how to check if the command succeeded or not.
Thank you for your ideas.
Assuming your Tcl code has a bit in its heart doing sendBack [eval $script], you'd change it to do this:
set code [catch {eval $script} result]
sendBack [list $code $result]
or even this:
set code [catch {eval $script} result options]
sendBack [list $code $result $options]
You'll need to unpack that list on the other side. The first element is the result code (0 for success, 1 for error, a few others theoretically but you probably won't see them), the second is the result value or the error message, and the third (if you use the second code snippet) is an options dictionary that can contain various things useful for debugging (including structured error codes, a stack trace, etc.)
Passing back the full result tuple is how you transfer the entire result from one context to another. A number of remote debugging tools for Tcl use pretty much exactly the same trick.
Related
I did not find a way to get the memory available using IServer, so instead I am trying to do so using IDatabase.ExecuteAsync("MEMORY STATS") and then processing the result
In the Redis Console one can write MEMORY STATS and get an array output - https://redis.io/commands/memory-stats.
This post says I can use ExecuteAsync to pass raw commands - Executing Redis Console commands in c#
Yet when I do IDatabase.ExecuteAsync("MEMORY STATS") I get the following error:
"RedisServerException: ERR unknown command `MEMORY STATS`, with args beginning with:".
You should do IDatabase.ExecuteAsync("MEMORY", "STATS").
This is because in reality, there is a MEMORY command, and STATS, USAGE, etc are treated as a first argument. This is so even when it is documented as a single MEMORY STATS command.
So, translated to RESP2, the server is expecting two separate strings, not a single string with a space in the middle.
I want to know if there is any way to set the property id values of the ENUM_MQL_INFO_INTEGER using external program or dll or anything.
I tried this:
int OnInit()
{
//---
MQL_DLLS_ALLOWED = 1;
Print(MQLInfoInteger(MQL_DLLS_ALLOWED));
//---
return(INIT_SUCCEEDED);
}
It gave error:
'MQL_DLLS_ALLOWED' - l-value required TestingEnum.mq5 15 4
'1' - cannot convert enum TestingEnum.mq5 15 22
'=' - l-value required TestingEnum.mq5 15 21
Kindly, let me know what I can do.
I cannot help you with your question directly, mainly because of the reasons discussed in the comments. I believe you can check the value whether DLL is allowed, but you cannot enable/disable it easily. Maybe there is a way with running MT terminal from the command line, with some keys allowing or blocking dll, so you may check. But that means restarting your platform, I am not sure that is convenient.
If I were you, and tired of enabling/disabling dll dozen times, I would introduce a global variable of client terminal, with values 0 or 1 (doubles of course). Then, if it is zero, dlls are not called, and ea does not start (if you check that in OnInit()), if it is non-zero value, dll works. A simple script changing this GV can be written and hot keys assigned. In that case, hotkey blocks everything, and allows dll again when needed.
In case you need any help with that - I will edit my code and provide some basic examples.
I'm currently running a small loop in g-code that has to wait for a common variable to change values. With Program Buffering ON, my g-code program does not see changes to the variables!
What is the best way to turn Program Buffering OFF while I am in this g-code loop?
If I manually set Program Buffering (NC Optional Parameter Bit No.2 Bit 7 to "DOES NOT". Then my loop behaves appropriately and the controller properly checks the value of the common variable each loop.
NLOOP G04 F1
IF[VC890 EQ 0] GOTO NRTS
GOTO NLOOP
NRTS RTS
Very straight forward loop. Maybe it needs to be more complex.
Perhaps if it was longer the buffer wouldn't matter?
I expect my customer's will want Program Buffering turned on.
Can I turn it off temporarily with the THINC API?
Because if it works, this would be great:
public void SetNCOptionalParameterBit(
int intBitIndex,
int intBitNo,
OnOffStateEnum enValue);
If this function will let me set param bit no 2 bit 7 on and off then this would probably be a valid work around.
Okuma.CMDATAPI.DataAPI.COptionalParameter myCOPtionalParameter;
myCOptionalParameter = new Okuma.CMDATAPI.DataAPI.COptionalParameter();
myCOPtionalParameter.SetNCOptionalParameterBit(2, 7,
Okuma.CMDATAPI.Enumerations.OnOffStateEnum.On);
What about M331 to prevent read ahead? (I won’t be at a control for a few days to verify usage, I’m holding my newborn and it’s 4am right now but I think it can go either on the line where you read variable on or the line before.)
NLOOP G04 F1 M331 (buffering prohibit)
IF[VC890 EQ 0] GOTO NRTS
GOTO NLOOP
NRTS RTS
The SetNCOptionalParameterBit() function is capable of setting NO. 2, BIT 7.
However, depending on what version of API you have, the THINC API test application might fail to do so. I confirmed there is a bug in the test app for API 1.17.2.0. And it was fixed by the time 1.18.0.0 was released.
So just be aware of that. Even if your machine has an older API such as 1.17.2.0, you should still be able to write code that uses this function successfully. Just ignore the test app results.
The best solution for my scenario was saving the current value of NC Optional Parameter 2 into a common variable, then changing it to Does Not buffer then running my code, then putting it back to whatever it was before.
in Gcode:
VC892 = VOPRB[2] (save current NC Optional Parameter bit 2 value)
VOPRB[2] = [VOPRB[2] OR 128] (bit magic to flip bit 7 to a 1 if its not)
(insert code to be run without buffering)
VOPRB[2] = VC892 (put back saved NC Optional Parameter bit 2 value)
How do you call this method on Nvidia GPU:
NVAPI_INTERFACE NvAPI_GPU_SetEDID (
NvPhysicalGpuHandle hPhysicalGpu,
NvU32 displayOutputId,
NV_EDID * pEDID
)
Src: http://docs.nvidia.com/gameworks/content/gameworkslibrary/coresdk/nvapi/group__gpu.html#ga6a41b31dd9743120213435d985f8fbcf
I need to execute the above command to remove all EDID set on all DisplayOutputs on our new Quadro Graphics Cards. Based on the API documentation, I tried searching for NvPhysicalGpuHandle and came across this project/library:
https://github.com/openhardwaremonitor/openhardwaremonitor/blob/master/Hardware/Nvidia/NVAPI.cs
This does not have the method I need NvAPI_GPU_SetEDID
I am not hardware programmer, I just need to be able to call this one command. any ideas? Can this be achieved using nvapi.dll/nvapi64.dll via pinvoke or something?
I personally didn't test this, but you can try the library and see if it can set EDID information without any problem, if it fails, please open an issue.
https://github.com/falahati/NvAPIWrapper
Here is how you should do it,
First, you need to find the right DisplayDevice or GPUOutput that you want to write EDID information to. There are multiple ways to do so.
Get a list of all PhysicalGPUs in the system using the NvAPIWrapper.GPU.PhysicalGPU.GetPhysicalGPUs() static method, then select the PhysicalGPU you desire based on your logic. After finding the right PhysicalGPU, use the NvAPIWrapper.GPU.PhysicalGPU.GetDisplayDevices() method to get a list of all connected DisplayDevices to that GPU and store the right one in a variable.
Instead of searching for connected DisplayDevices, you can also go for the GPUOutputs. Just like before, you first need to find the right PhysicalGPU and then you can get a list of all GPUOutputs using the NvAPIWrapper.GPU.PhysicalGPU.ActiveOutputs property and store the right GPUOutput in a variable.
Another way to find the right DisplayDevice is to go for a list of all Displays. To do so, you need to use the NvAPIWrapper.Display.Display.GetDisplays() static method. This returns an array of Displays. Then using the NvAPIWrapper.Display.Display.DisplayDevice property, you can get the corresponding DisplayDevice of a Display.
After finding the right DisplayDevice or GPUOutput, you should use the NvAPIWrapper.GPU.PhysicalGPU.WriteEDIDData() method. This method allows you to write EDID data stored in a byte array to the DisplayDevice or the GPUOutput you selected before.
Note: Make sure to capture NVIDIAApiException and check for the NVIDIAApiException.Status property in case something went wrong.
So, I am developing a game with Unity3D, and I'm using Prolog for IA planning.
My problem is very similar to the monkey and banana problem, but I'm having problems on asserting a new initial state.
By changing the initial state, my character would be able to plan again his actions whenever something important on the environment changed.
But let's get back to my problem:
I'm passing a string to prolog, via socket, and I want to build a list of facts. Then, I'd like to use these facts as the initial state for my planning procedure.
I'm able to write the socket's input stream on the SWI terminal by transforming the byte array into a list of chars. I am also able to get a string back from the prolog server, by writing something on the output stream.
But I don't know how I am supposed to turn those characters/string into a list of facts.
Also, I'd like to use that list of facts as an initial state, by passing it to the planning procedure like I would pass an argument to a function in an imperative programming language (if that were the case).
What I'd like to do is something like this (pseudocode):
% on the prolog server, we have a main function
% we get a bytestream (In),
% turn it into a list of facts
% use it as the initial state
% and write Plan to the output stream (Out).
loopback(In, Out) :-
\+at_end_of_stream(In),
read_pending_input(In, Codes, []),
atom_codes(AtomList, Codes), %bytes into a list of atoms
toFacts(Init, AtomList), %??? Init = AtomList to list of facts
test(Init, Plan), %pass Init as the initial state
format(Out, '~s', Plan), %Get the plan back and write to the output
flush_output(Out),
loopback(In, Out).
% Init should look like this - a mere list of facts:
Init = [on(monkey, floor),
on(box, floor),
at(monkey, a),
at(box, b),
at(bananas, c),
status(bananas, hanging)].
% The planning predicate - Init as an argument, Plan is the result
test(Init, Plan):-
write('Initial state:'),nl,
write_sol(Init),
Goal = [status(bananas, grabbed)],
nl,write('Goal state:'),nl,
write(Goal),nl,
solve(Init,Goal,Plan).
I am really stuck right now, I hope someone can help me. Thank you!
References:
Full monkey banana problem code.
SWI socket server code example.
You have many choices: the simplest seems to be read_from_codes
test :-
S = "[on(monkey, floor),
on(box, floor),
at(monkey, a),
at(box, b),
at(bananas, c),
status(bananas, hanging)].",
read_from_codes(S, T),
writeln(T).
results in
?- test.
[on(monkey,floor),on(box,floor),at(monkey,a),at(box,b),at(bananas,c),status(bananas,hanging)]
true.
But the exchange of structured data could be easier using a devoted protocol like JSON. I used it just via AJAX/jQuery. Maybe overkill for your use case...
In http://tinycog.sourceforge.net/ we are using the SWI-Prolog HTTP server and Unity3D HTTP calls to build an interface using JSON libraries on both end for encoding of complex terms etc. Actually a small C# script on the Unity3D side just sends the position of all GameObjects to an SWI-Server and receives a list of commands that to be executed on the Unity3D level including "goto", "grab" and "fire".
The SWI-Prolog code is in the GIT repository, the Unity3D code in C# is part of the client ZIP in the project files.