Jump to content
OMRON Forums

Shared memory


DT-Europe
 Share

Recommended Posts

How can we access shared memory to exchange datas between C_PLCs and Script PLCs? Is the starting address $E00000? What is the end address? Is this address the same from both sides C_PLCs and Script PLCs? Will some of this memory be used for automatic functions (like automatic functions in DPR of Turbo)?
Link to comment
Share on other sites

  • Replies 4
  • Created
  • Last Reply

Top Posters In This Topic

[quote=DT-Europe] How can we access shared memory to exchange datas between C_PLCs and Script PLCs? Is the starting address $E00000? What is the end address? Is this address the same from both sides C_PLCs and Script PLCs? Will some of this memory be used for automatic functions (like automatic functions in DPR of Turbo)? [/quote] Shared memory is fixed based on the Power PMAC structures. To pass data between script PLCs and CPLCs you should use the user buffer. CPLCs access this the same way they access shared memory, just grab a pointer to the memory through our supplied function GetUserBufferPtr(void); A quick example is below. Remember the divide by four for the proper offset. #include #include // Global Rt/Gp Shared memory pointers volatile unsigned *pACC24E2A ; volatile struct SHM *pSharedMem; volatile struct SHM *pUserMem; int main(int argc, char *argv[]) { int i = 0; //--------------------------------------------------------- // Required for all Gp Programs //--------------------------------------------------------- if (InitLibrary ()) return 0; pSharedMem = GetSharedMemPtr(); // Not used in this example but often very useful pUserMem = GetUserBufferPtr(); pACC24E2A = GetIOMemPtr(); // pointer to I/O boards // Unlike the command processor the offsets are in 32 bit words so we must // divide by 4 to get the correct offset from the base io memory pointer *(pACC24E2A + 0x600034/4) |= 0x00400000; for(i = 0; i < 2000;i++) usleep(1000); *(pACC24E2A + 0x600034/4) &= ~0x00400000; //------------------------------- // Reguired Gp Cleanup Code //------------------------------- CloseLibrary (); return 0; }
Link to comment
Share on other sites

  • 10 months later...
Guest vanandel
1) How big are each of these regions: "SharedMem" "user buffer" "IOMem" ? 2) Is there any significance to "0x600034", or is it just an arbitrary offset in the user buffer? 3) When should I use memory in the GetSharedMemPtr() region vs the GetUserBufferPtr() region, vs the GetIOMemPtr() region? 4) How does a script PLC reference memory in each region? 5) Are there reserved areas in any of these 3 regions that I need to avoid using? If so, how do I know what areas to avoid? 6) Can a CPLC read commands from a network socket and then write values in shared memory? That is, are there any restrictions on what a CPLC can do? 7) How does a user written CPLC get started? That is, once I have compiled it, how do I configure the Power PMAC to run my CPLC? 8) Does a user written CPLC need to sleep() or block periodically to allow other CPLCs to run?
Link to comment
Share on other sites

[quote='vanandel' pid='183' dateline='1246053495'] 1) How big are each of these regions: "SharedMem" "user buffer" "IOMem" ? --- This should help with general questions [attachment=1336:name] 2) Is there any significance to "0x600034", or is it just an arbitrary offset in the user buffer? --- This is an address based on the ACC card being accessed. The example was to let someone access data on a UMAC ACC card from the CPLC world without using one of our predefined structures which is easier to use. 3) When should I use memory in the GetSharedMemPtr() region vs the GetUserBufferPtr() region, vs the GetIOMemPtr() region? --- These are different offsets in the shared memory buffer. The shared memory has the predefined structures which should give access to most things you need. The user buffer is an open memory area for you to use as you wish. One thing many people do is exchange data between CPLCs or between Script PLCs or between Script an CPLCs 4) How does a script PLC reference memory in each region? --- For the IO mem and Shared mem you have direct access to the predefined structure names so you should use these. For the user buffer you would define a PTR (also caled M-variable) to the location desired. 5) Are there reserved areas in any of these 3 regions that I need to avoid using? If so, how do I know what areas to avoid? --- User buffer is open for your use although I would avoid using the first 8-bytes because many PPMAC data structures point here when they are not defined so the possibility of a conflict exists. Think of the other two as accessing our locations and that is one reason why using the predefined structure names is better. 6) Can a CPLC read commands from a network socket and then write values in shared memory? That is, are there any restrictions on what a CPLC can do? --- Not many restrictions. There is an example in the forum to do this. See http://forums.deltatau.com/showthread.php?tid=59 about host program talking to a CPLC. 7) How does a user written CPLC get started? That is, once I have compiled it, how do I configure the Power PMAC to run my CPLC? --- There is an ini file that tells us which ones to start. This is called pp_proj.ini and is in the location /opt/ppmac/usrflash/project/configuration if you have SAVED the project. Since this is the only time startup issues apply this will be the one. Before you save it is in /var/ftp/usrflash/project/configuration. --- In this file is a section listing the CPLCs loaded and if they should run or not. Here is my example of that section. --- [LINUX_PROGRAMS] --- program1=/var/ftp/usrflash/Project/C Language/Background Programs/cplc1.out --- run1=1 --- last_program_number=1 I have forgotten the name at the moment. I will need to get back to this. 8) Does a user written CPLC need to sleep() or block periodically to allow other CPLCs to run? --- It is a good idea. I am thinking you are speaking of the background CPLCs. These run in the GP Linux so normal Lnux rules apply. If you are speaking of out user CPLC or RTI CPLC then these are really functions called by our PPMAC kernel so a sleep is not needed and probably not desired as you would normally use these expecting a predictable operating cycle. [/quote]
Link to comment
Share on other sites

  • 8 months later...
A few samples for reading and writing to the user buffer. 1. From a C App ------------------------------------------------------------- //-------------------------------------------------------------------------------- #include #include // Global Rt/Gp Shared memory pointers //------------------------------------------------------------- // The following is a projpp created file from the User defines //------------------------------------------------------------- #include "../../Include/pp_proj.h" int main(void) { int *mypushm; int i, j; struct SHM *pshm; void *pushm; InitLibrary(); // load PPmac API pshm = GetSharedMemPtr(); // Get pointer to shaered memory pushm = GetUserBufferPtr(); // get pointer to user buffer while(1<2){ // loop forever mypushm = (int *) pushm; // make int pointer for easy incrementing pshm->P[8]++; // increment P8 i = (int) pshm->P[8]; memcopy((unsigned char *) mypushm, (unsigned char *) &i, sizeof(i)); // copy to the user buffer Sys.Udata[0] memcopy((unsigned char *) (mypushm + 1), (unsigned char *) &i, sizeof(i)); // copy to the user buffer Sys.Udata[1] memcopy((unsigned char *) (mypushm + 2), (unsigned char *) &i, sizeof(i)); // copy to the user buffer Sys.Udata[2] memcopy((unsigned char *) &j, (unsigned char *) (mypushm + 2), sizeof(j)); // read from the user buffer Sys.Udata[2] pshm->P[9] = j; // place answer into P9 } CloseLibrary(); return 0; } 2. From a background CPLC ------------------------------------------------------------- #include #include #include void user_plcc() { int *mypushm, i, j; mypushm = (int *) pushm; // make int pointer for easy incrementing pshm->P[8]++; // increment P8 i = (int) pshm->P[8]; memcopy((unsigned char *) mypushm, (unsigned char *) &i, sizeof(i)); // copy to the user buffer Sys.Udata[0] memcopy((unsigned char *) (mypushm + 1), (unsigned char *) &i, sizeof(i)); // copy to the user buffer Sys.Udata[1] memcopy((unsigned char *) (mypushm + 2), (unsigned char *) &i, sizeof(i)); // copy to the user buffer Sys.Udata[2] memcopy((unsigned char *) &j, (unsigned char *) (mypushm + 2), sizeof(j)); // read from the user buffer Sys.Udata[2] pshm->P[9] = j; // place answer into P9 } 3. From a RTI CPLC ------------------------------------------------------------- #include #include #include void realtimeinterrupt_plcc() { int *mypushm, i, j; mypushm = (int *) pushm; // make int pointer for easy incrementing pshm->P[8]++; // increment P8 i = (int) pshm->P[8]; memcopy((unsigned char *) mypushm, (unsigned char *) &i, sizeof(i)); // copy to the user buffer Sys.Udata[0] memcopy((unsigned char *) (mypushm + 1), (unsigned char *) &i, sizeof(i)); // copy to the user buffer Sys.Udata[1] memcopy((unsigned char *) (mypushm + 2), (unsigned char *) &i, sizeof(i)); // copy to the user buffer Sys.Udata[2] memcopy((unsigned char *) &j, (unsigned char *) (mypushm + 2), sizeof(j)); // read from the user buffer Sys.Udata[2] pshm->P[9] = j; // place answer into P9 }
Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share


×
×
  • Create New...