I'm trying in a c++ application reading GDS variable ( equivalent of the SampleRuntime application).
I'd like to access Profinet Controler Diagnostics ( PNIO_CONFIG_STATUS_ACTIVE, PNIO_FORCE_PRIMARY...) but i can't retrieve in which buffer it's mapped ( to be able to access the frame by ArpPlcIo_GetBufferPtrByBufferID function )
For AXIO diags, these data are mapped in the 1:IN/1:OUT frames (allowing to read data and diagnostics accessing the same buffer), but I found this information only by reading the sampleruntime application example code.
it's possible to get the buffer for one data using ArpPlcIo_GetBufferPtrByPortName("Arp.Io.PnC", "Arp.Io.PnC/PNIO_FORCE_PRIMARY", &gdsBuffer;) but i've not found the information if calling multiple time this function will reserve one buffer each time it's called, or if it will point on only one buffer.
I don't want to reserve/release the buffer each time i'm reading a data, so I must guess in which buffer these data are mapped to reserve only one time the buffer.
To synthetize I've two questions
- is the profinet system data mapped in some reserved frame number for profinet controller ( like IN1 / OUT1 ) like AXIO diagnostics
- are new buffer ressources allocated each time we call ArpPlcIo_GetBufferPtr... or is there some kind of unique allocation ( multiple Get, only one release ).
could you provide me answers or documentation where I could find this information please?
Thanks to our developers, here are the answers to your two quite interesting questions:
1. The PROFINET data is not mapped into just one input and one output area as for the AXIO controller. Therefore for [b]system data[/b] a separate memory area is available that can be accessed using:
[code]ArpPlcIo_GetBufferPtrByBufferID("Arp.Io.PnC", "SysVars" &bufferHandle;);[/code]
Using the buffer handle you can get the offsets of the required data using:
[code]ArpPlcGds_GetVariableOffset()[/code]
or
[code]ArpPlcGds_GetVariableBitOffset()[/code]
(the second one is for Boolean information).
Reading the data from the GDS must be between [b]ArpPlcGds_BeginRead()[/b] and [b]ArpPlcGds_EndRead()[/b] using the buffer handle.
Below is a code snippet showing roughly how to determine the variable offsets.
2. Each call of [b]ArpPlcIo_GetBufferPtr...[/b] will return a different buffer handle although they may address the same area. Therefore you must release each handle separately.
It is recommended to get each buffer once in your application, use it, and then store it (e.g. in a member variable) as long as you need it. If you do not need the buffer any more e.g. during shutdown of your application then you should release it.
Note: the code snippet below does not store the buffer handle, as just suggested :)
=============================================================================
[code]#define ARP_IO_PN\t"Arp.Io.PnC"\t// ID of PROFINET IO Component
// Access System Variables of the PROFINET Controller
TGdsBuffer* pGdsPncSysVars = nullptr;
if(ArpPlcIo_GetBufferPtrByBufferID(ARP_IO_PN, "SysVars", &pGdsPncSysVars;))
{
\tString pnioConfigStatusActiveName = Formatter::FormatCommon("{}/PNIO_CONFIG_STATUS_ACTIVE", ARP_IO_PN);
\tString pnioForcePrimaryName = Formatter::FormatCommon("{}/PNIO_FORCE_PRIMARY", ARP_IO_PN);
\tsize_t offsetConfigStatusActive = 0;
\tunsigned char bitOffsetConfigStatusActive = 0;
\tif(ArpPlcGds_GetVariableBitOffset(pGdsPncSysVars, pnioConfigStatusActiveName, &offsetConfigStatusActive;, &bitOffsetConfigStatusActive;))
\t{
\t\tLog::Info("Offset for {0}: {1}.{2}", pnioConfigStatusActiveName, offsetConfigStatusActive, (int)bitOffsetConfigStatusActive);
\t}
\telse
\t{
\t\tLog::Error("Error calling ArpPlcGds_GetVariableBitOffset for {0}", pnioConfigStatusActiveName);
\t}
\tsize_t offsetForcePrimary = 0;
\tunsigned char bitOffsetForcePrimary = 0;
\tif(ArpPlcGds_GetVariableBitOffset(pGdsPncSysVars, pnioForcePrimaryName, &offsetForcePrimary;, &bitOffsetForcePrimary;))
\t{
\t\tLog::Info("Offset for {0}: {1}.{2}", pnioForcePrimaryName, offsetForcePrimary, (int)bitOffsetForcePrimary);
\t}
\telse
\t{
\t\tLog::Error("Error calling ArpPlcGds_GetVariableBitOffset for {0}", pnioForcePrimaryName);
\t}
bool result = ArpPlcIo_ReleaseGdsBuffer(pGdsPncSysVars);
}
else
{
\tLog::Error("Error calling ArpPlcIo_GetBufferPtrByBufferID for PN SysVars buffer");
}[/code]