shansen Posted October 27, 2011 Share Posted October 27, 2011 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 More sharing options...
bradp Posted October 31, 2011 Share Posted October 31, 2011 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 More sharing options...
shansen Posted November 1, 2011 Author Share Posted November 1, 2011 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 More sharing options...
BoneSkier Posted November 9, 2011 Share Posted November 9, 2011 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 More sharing options...
shansen Posted November 10, 2011 Author Share Posted November 10, 2011 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 More sharing options...
BoneSkier Posted November 10, 2011 Share Posted November 10, 2011 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 More sharing options...
shansen Posted November 10, 2011 Author Share Posted November 10, 2011 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 More sharing options...
BoneSkier Posted November 10, 2011 Share Posted November 10, 2011 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 More sharing options...
shansen Posted November 10, 2011 Author Share Posted November 10, 2011 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 More sharing options...
BoneSkier Posted November 14, 2011 Share Posted November 14, 2011 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 More sharing options...
HRS Posted January 13, 2012 Share Posted January 13, 2012 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 More sharing options...
shansen Posted January 13, 2012 Author Share Posted January 13, 2012 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 More sharing options...
Recommended Posts