Jump to content
OMRON Forums

Get Address of Global (P-var) Easily?


shansen
 Share

Recommended Posts

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:

 

Gather.Addr[0] = MyGlobalVar1.a

 

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

 

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?

Link to comment
Share on other sites

  • Replies 11
  • Created
  • Last Reply

Top Posters In This Topic

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

Link to comment
Share on other sites

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:

 

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:

 

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:

 

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:

 

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)?

Link to comment
Share on other sites

  • 2 weeks later...

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.

 

Link to comment
Share on other sites

BoneSkier,

 

How are you defining AxesEnabled? If I do:

 

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:

 

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

Link to comment
Share on other sites

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:

 

_

Private Shared Function GetResponse(<[in](), MarshalAs(UnmanagedType.LPStr)> ByVal q As String, 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

 

 

Link to comment
Share on other sites

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:

_
Private Shared Function GetResponse(<[in](), MarshalAs(UnmanagedType.LPStr)> ByVal q As String,  ByVal a As StringBuilder, ByVal maxlen As Int32, ByVal echomode As Byte) As Integer
End Function

_
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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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:

 

[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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

  • 1 month later...

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?

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share


×
×
  • Create New...