Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Writing to M vars from C

I need to write to specific M variables by number (M100...M105) from my C code. I found a way to do this using the following code:

//set characters of the string
instring[0] = 'M'; //M variable M100...M105
instring[1] = '1'; //1
instring[2] = '0'; //0
instring[3] = (char) (chan + 48); //write the final number (add the ascii number offset for the character 0)
instring[4] = '\0'; //null terminator
SetPmacNativeVar(cptr, 1); //set trigger variable for use by script code M100...M105 = 1

It works, but surely there must be a nicer way?

You can find codes below in "pp_proj.h" file.

#define SetPtrVar(i, x)                 SetEnumPtrVar(i, x)
#define SetPtrArrayVar(i, j, x)         SetEnumPtrArrayVar(i, j, x)
#define GetPtrVar(i)                    GetEnumPtrVar(i)
#define GetPtrArrayVar(i, j)            GetEnumPtrArrayVar(i, j)

It has better performance to access M pointer variables in you code.
Please check it !
I wanted to follow up that the #define macros in the pp_proj.h file were added as a method of adding more convenience and type safety to the original way to access P and M vars while still allowing legacy applications to run without change.

I recommend using the Delta Tau automatic assign variables where you can. Sometimes you need to explicity access a block of M or P vars and here is what I do:

I recommend trying the mode PPScriptMode in your project. This will impart type safety on your variable access. It also makes P variables much more convenient to access because they show up as just double typed global variables. Place a "#define _PPScriptMode_" in your code before including pp_proj.h

#define _PPScriptMode_
#include "../Include/pp_proj.h"

//Define our M variables starting at M4000.
//We use (ptrM) to case the numbers for type safety
//(not to confuse them with P vars)
#define MyHardCodedMVar00 (ptrM)4000
#define MyHardCodedMVar01 (ptrM)4001
#define MyHardCodedMVar02 (ptrM)4002

//Do similar for PVar absolute access
#define MyHardCodedPVar00 pshm->P[4000]
#define MyHardCodedPVar01 pshm->P[4001]
#define MyHardCodedPVar02 pshm->P[4002]

void SomeFunction()
    SetPtrVar(MyHardCodedMVar00, 3.14159265);
    SetPtrVar(MyHardCodedMVar01, 1.234);
    SetPtrVar(MyHardCodedMVar02, 2.345);

    MyHardCodedPVar01 = 1.234 + 2.345;

    //The following errors out at compile time.
    //cannot convert type double to ptrM
    //SetPtrVar(MyHardCodedPVar00, 1.23456)  //<---Compile Error

    //The following errors out at compile time.
    //ptrM not a storage type
    //MyHardCodedMVar00 = 1 + 2;  //<---Compile Error


I hope that this helps. Again, I recommend using the auto-assign variables if you can. The above programs will work if you define the P and M vars in one of the pmh files in the IDE and include pp_proj.h in your C code. You still get the type safety and ability to use meaningful names, its just that the IDE compile process assigned the M and P var numbers for you automatically and burys that in the pp_proj.h generated header file so you don't have to think about it.

You can get the best performance by just duplicating your pointer (i.e. your original M-Variable) as a C pointer (i.e. by mapping the memory location directly with a C pointer).
(04-30-2015, 09:22 AM)CharlesP Wrote: You can get the best performance by just duplicating your pointer (i.e. your original M-Variable) as a C pointer (i.e. by mapping the memory location directly with a C pointer).

I didn't know you could do that with M vars? Where in pshm-> are the M vars called out?

At any rate using the ptrM convention for M vars does allow you to have separation from P and M vars in your function calls.

It's not quite what I meant; I meant creating a separate pointer directly in C that re-maps the same memory location that you mapped with your M-Variable in Script, effectively not even using the M-Variable. You can see some examples of me doing this in the ACC-11E manual starting on page 18:

It can get a little ugly, though, doing each memory address individually. Most of the time you can map a whole card's structure like shown on pages 753 and following of the Power PMAC User Manual, but for some parts of the PPMAC memory (e.g. ACC-11E's I/O memory space), you have to do it address-by-address.

Forum Jump:

Users browsing this thread: 1 Guest(s)