Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Get Address of Global (P-var) Easily?
#1
We are trying to implement our own gather program that logs data and can handle global variable tagnames instead of P-var numbers.

If I define a global variable, how can I easily get the address of that variable without knowing which P-var it is mapped to?

For example, I want to do this:

Code:
Gather.Addr[0] = MyGlobalVar1.a

Obviously this fails. If I know the specific P-var, I can do this:

Code:
Gather.Addr[0] = Sys.P[xxxx].a

Is there a simpler way to get the address of the global var without worrying about which P-var it is pointing to internally?
Reply
#2
There might be an easier way but one way to do this is go to the file /var/ftp/usrflash/Database/pp_global.sym then you can search the table and find the corresponding variable number.

Another way is to send a query using getresponse() with the echo on and the answer will be in the form Pxxx=number then parse the string and get xxxx
Reply
#3
Brad,

I figured it out. I needed to have a way to define a global variable with the following characteristics:

1) Accessible in C code by tagname
2) Accessible in Script code by tagname
3) Accessible through GetResponse by tagname
4) Address accessible through GetResponse by tagname

Global vars currently can do the first 3, but it is hard to get the address symbolically (have to do GetResponse, then parse the string = much uglier).

To fix this, I have to use #define's and also use a duplicate definition for each global variable:

Code:
In global definitions.pmh:
#define MyVar1 Sys.DData[0] // instead of ptr MyVar1->Sys.DData[0]
#define MyVar2 Sys.P[0] // instead of global MyVar2

In C code header file:
#define MyVar1 *((double *)pushm + 0)
#define MyVar2 pshm->P[0]

Then, I can do this:

Code:
Command: Gather.Addr[0] = MyVar1.a
Command: Gather.Addr[1] = MyVar2.a

Command: MyVar1
Response: Sys.DData[0]=0

Command: MyVar2
Response: Sys.P[0]=0

This works, but it is too bad that we have to hard code Pvars/Mvars and that the definitions for each global var have to be duplicated in the pmh and header files.

Question: Could you change the preprocessor to define globals as Sys.P[8192] instead of P8192? This is what I'm thinking:

Code:
In global definitions.pmh:
global MyVar1;
// this should still auto generate pshm->P[8192] in pp_proj.h

In C code header:
#define _PPScriptMode_

In GetResponse:
Command: Gather.Addr[0] = MyVar1.a
Response: Gather.Addr[0] = Sys.P[8192].a

That would fix the issue I'm having with Pvars, however, I don't think there is a syntax for accessing the address of Mvars in one call:

Code:
In global definitions.pmh:
ptr MyVar1->Sys.DData[0];

I can get the address of the Mvar by doing this:
Command: MyVar1->
Response: Sys.DData[0]

What I want to do:
Command: Gather.Addr[0] = &MyVar1
or something similar to get the address of MyVar1

Another question: Is it possible to access ptr vars in C code without using GetPtrVar()?

Sorry, there is a lot here. Here are the questions summarized:

1) Is it possible for DT to change global var definitions to Sys.P[8192] instead of P8192 so we can access the addresses easily?
2) Is there an easy way to access the address of a Ptr var without doing 2 GetResponses (i.e. one to get the address, one to use the address)?
3) For globally defined Ptr vars, is there an easy way to access them by tagname in C code (similar to how _PPScriptMode_ generates the #define's for global vars)?
Reply
#4
Wow --- funny that you should asking last week the very question that I have today.
It appears that you are looking for addresses in a background C program where you have access to the pp_proj.h file.

I am trying to do get the address of a P variable in a MONO vb program. GetResponse doesn't seem to return "PXXX=YY" for me.

For instance, I have a variable called "AxesEnabled" which is at P249.
If I pass "AxesEnabled" into GetResponse, I am getting the following:
error #20: ILLEGAL CMD: AxesEnabled

This same "AxesEnabled" returns P249=XX just fine in the Terminal Window and in GPASCII from the command line in Linux.
Reply
#5
BoneSkier,

How are you defining AxesEnabled? If I do:

Code:
global AxesEnabled;

or

#define AxesEnabled P249


then I can use BOTH the terminal in the IDE and a GetResponse from an outside program.

Unfortunately, I don't know if this works with the GetResponse in the PPmacComLib because my company is using our own custom driver instead.

Suffice it to say that in our "GetResponse" equivalent method, on the Power PMAC side of the driver we call Delta Tau's ConvertSymbolicToPMACExp() function. This converts all tagnames (e.g. AxesEnabled) to a Pmac var (e.g. P249) before doing a GetResponse and returning the result.

I don't know if Delta Tau's PPmacComLib driver does the same thing.

As far as the address goes, if you know what Pvar you want (e.g. P249) you can use Sys.P[249].a to get the address. I am hoping that in the future, Delta Tau can redo their global definitions:

Code:
Current way it is done:
global AxesEnabled; // defines AxesEnabled = P249
GetResponse("AxesEnabled.a"); // returns "P249.a" which is invalid


Better way to do it:
global AxesEnabled; // defined AxesEnabled = Sys.P[249]
GetResponse("AxesEnabled.a"); // returns "Sys.P[249].a" which is valid
Reply
#6
I am doing the following for my definition --- it has to be at this location for compatibility reasons:

#define AxesEnabled P249

The code (in a VB.NET program running on MONO) I have is this:

<DllImport(DllLocation, EntryPoint:="GetResponse", CharSet:=CharSet.Ansi)> _
Private Shared Function GetResponse(<[In](), MarshalAs(UnmanagedType.LPStr)> ByVal q As String, <Out(), MarshalAs(UnmanagedType.LPStr)> ByVal a As StringBuilder, ByVal maxlen As Int32, ByVal echomode As Byte) As Integer
End Function


Public Function GetPVarAddress(ByVal sVariableName As String) As Integer
Try
Dim sResponse As New StringBuilder("A", 4096)
Dim sResponse2 As String
Dim sResult() As String
Dim sAddress As String

Dim iResult As Integer
iResult = GetResponse(sVariableName, sResponse, 512, 0)
sResponse2 = sResponse.ToString()
sResult = sResponse2.Split(New Char() {"="c})
sAddress = Mid(sResult(1), 1)
Return Integer.Parse(sAddress)
Catch ex As Exception
Console.Write("GetPVarAddress Error: " & ex.Message & vbCrLf)
End Try
End Function

Reply
#7
Is your program running on the Power PMAC? If so, check out the ConvertSymbolicToPMACExp() function. It converts tagnames (AxesEnabled) to a GetResponse compatible string (P249).

Example:
Code:
<DllImport(DllLocation, EntryPoint:="GetResponse", CharSet:=CharSet.Ansi)> _
Private Shared Function GetResponse(<[In](), MarshalAs(UnmanagedType.LPStr)> ByVal q As String, <Out(), MarshalAs(UnmanagedType.LPStr)> ByVal a As StringBuilder, ByVal maxlen As Int32, ByVal echomode As Byte) As Integer
End Function

<DllImport(DllLocation, EntryPoint:="ConvertSymbolicToPMACExp", CharSet:=CharSet.Ansi)> _
Private Shared Function ConvertSymbolicToPMACExp(...) 'need to fill in parameters here
End Function

Public Function GetPVarAddress(ByVal sVariableName As String) As Integer
            Try
                Dim sResponse As New StringBuilder("A", 4096)
                Dim sTagStr As String
                Dim sResponse2 As String
                Dim sResult() As String
                Dim sAddress As String

                Dim iResult As Integer
                    sTagStr = ConvertSymbolicToPMACExp(sVariableName);
                    iResult = GetResponse(sTagStr, sResponse, 512, 0)
                    sResponse2 = sResponse.ToString()
                    sResult = sResponse2.Split(New Char() {"="c})
                    sAddress = Mid(sResult(1), 1)
                Return Integer.Parse(sAddress)
            Catch ex As Exception
                Console.Write("GetPVarAddress Error: " & ex.Message & vbCrLf)
            End Try
End Function
Reply
#8
I will give this a try --- where do I find the parameters for this method?

BTW --- since you just showed me another method available, where do I get a list of all the methods available?

If you or anyone has the DLLImport statements for these in C, that would work for me. I can convert to VB.
Reply
#9
I am using the Help->Contents in the Power PMAC IDE. Look under PowerPmacCLanguageManual->gplib.h->ConvertSymbolicToPmacExp().

Here is the function prototype:
void ConvertSymbolicToPMACExp (unsigned char * inpstr)

So I guess my previous example is a little off. My visual basic is rusty, so here is the equivalent C# code:

Code:
[DllImport(DllLocation)]
private static extern void GetResponse(string query, out StringBuilder response, int maxlen, byte echoMode);
[DllImport(DllLocation)]
private static extern void ConvertSymbolicToPMACExp(ref string query);

private string DoGetResponse(string var)
{
   ConvertSymbolicToPMACExp(var); // converts var tagnames to Pmac variables
   StringBuilder response = new StringBuilder();
   GetResponse(var, out response, 65535, 0x07); // do get response
   return response.ToString();
}

Those dll import statements are probably a little bit off, I did them off the top of my head and I don't know if you can directly convert a string pointer to a ref or not.
Reply
#10
I really actually just need to get the address of the P-variable. I send the address along with the value of a P-variable to my HMI to notify of memory changes.

The results I am getting are the same as when I do the command using GPASCII (without the -2).

"error #20: ILLEGAL CMD: AxesEnabled"

So, when InitLibrary is done in my MONO program, is it starting GPASCII with -2?
Reply
#11
Is it possible to include the rtpmacapi.h in the C# project and then use "GetSharedMemPtr(void)" function that has been declared as follows?

[DllImport(DllLocation, EntryPoint = "GetSharedMemPtr", CharSet = CharSet.Ansi)]
private static extern struct SHM* GetSharedMemPtr(void);

Can't seem to get it work...but I'm new to this...

ANYBODY try this?
Reply
#12
HRS,

I'm pretty sure you can't do this because the SHM structure is defined in one of Delta Tau's header files, and C# does not allow you to reference C headers directly.

Another problem is that C# isn't exactly pointer friendly (although it can be done with the 'unsafe' keyword, it is highly discouraged).

What is inside pSHM that you need access to? Could you access what you need through GetResponse() or any of the other pre-defined functions?
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)