Il sistema operativo dispone di un’area di memoria che può essere utilizzata da diversi oggetti, l’utilizzo di questa memoria non diminuisce la memoria a disposizione del programma utente.
Con la funzione SysRMAlloc si chiede al sistema un blocco di memoria da utilizzare, quando disponibile la funzione ne ritorna l’indirizzo di allocazione. A differenza della funzione SysMAlloc questa funzione permette tramite la funzione SysRMFree di liberare la memoria allocata quando non è più utilizzata, in questo modo è possibile riutilizzarla. La funzione SysRMGetSize ritorna la dimensione della memoria allocata.
Per ottimizzarne l’utilizzo la memoria allocata viene automaticamente rilocata dal sistema operativo che ne sposta automaticamente l’indirizzo di allocazione aggiornando di conseguenza il buffer che lo contiene. Quindi per utilizzarla occorre sempre fare riferimento all’indirizzo memorizzato nel buffer indicato in DataPtr.
Approfondimenti
Tramite il comando RMStats è possibile visualizzare le statistiche di allocazione. Con il comando EngCommand -rmt è possibile comandare la continua rotazione dei blocchi di memoria allocati al fine di scoprire eventuali errori nell’utilizzo.
- In questo articolo informazioni sulla memoria dei sistemi.
SysRMAlloc, relocatable memory allocation
La funzione esegue l’allocazione dinamica di uno spazio di memoria della dimensione in byte definita da parametro Size. Nella variabile DataPtr occorre fornire l’indirizzo del buffer dove la funzione memorizza l’indirizzo alla memoria allocata. La funzione ritorna FALSE se errore allocazione e TRUE se memoria allocata.
Descrizione
Size (UDINT) Indica la dimensione in bytes dell’area da allocare.
DataPtr (PVOID) Occorre indicare l’indirizzo del buffer dove memorizzare il puntatore alla memoria allocata.
La funzione ritorna un (BOOL) FALSE se errore allocazione memoria, TRUE se memoria allocata.

SysRMGetSize, relocatable memory buffer size
La funzione ritorna la dimensione della memoria precedentemente allocata da una funzione SysRMAlloc. Occorre fornire l’indirizzo del buffer che contiene l’indirizzo della memoria da disallocare nella variabile DataPtr. La funzione ritorna 0 se memoria non allocata.
Descrizione
DataPtr (PVOID) Occorre indicare l’indirizzo del buffer che contiene l’indirizzo della memoria allocata.
La funzione ritorna un (UDINT) con la dimensione di memoria. 0 se memoria non allocata.

SysRMFree, relocatable memory free
La funzione esegue la disallocazione di uno spazio di memoria precedentemente allocato da una funzione SysRMAlloc. Occorre fornire l’indirizzo del buffer che contiene l’indirizzo della memoria da disallocare nella variabile DataPtr. La funzione ritorna FALSE se errore disallocazione e TRUE se memoria disallocata.
Non è possibile disallocare la memoria allocata con la funzione SysMAlloc.
Descrizione
DataPtr (PVOID) Occorre indicare l’indirizzo del buffer che contiene l’indirizzo della memoria da disallocare.
La funzione ritorna un (BOOL) FALSE se errore disallocazione, TRUE se memoria disallocata.

Esempi
Come utilizzare gli esempi.
Connettendosi con un telnet alla porta indicata ad ogni secondo viene incrementato il valore di un contatore e ne viene inviato il valore come stringa al terminale.
LogicLab (Ptp116, ST_SysRMAlloc)
PROGRAM ST_SysRMAlloc
VAR
Fp : eFILEP; (* File pointer *)
SOut : @STRING; (* String output pointer *)
MSize : UDINT; (* Memory size *)
Counter : UDINT; (* Counter *)
TimeBf : UDINT; (* Time buffer (mS) *)
TCPServer : SysTCPServer; (* TCPServer management *)
END_VAR
// *****************************************************************************
// PROGRAM "ST_SysRMAlloc"
// *****************************************************************************
// An example of how allocate a memory buffer and how to use it.
// -----------------------------------------------------------------------------
// -------------------------------------------------------------------------
// INITIALIZATION
// -------------------------------------------------------------------------
// First program execution loop initializations.
IF (SysFirstLoop) THEN
// TCP server parameters.
TCPServer.FilesArr:=ADR(Fp); //Files array
TCPServer.LocalAdd:=ADR('0.0.0.0'); //Local address
TCPServer.LocalPort:=1010; //Local port
TCPServer.MaxConn:=1; //Accepted connections
TCPServer.FlushTm:=50; //Flush time (mS)
TCPServer.LifeTm:=30; //Life time (S)
TCPServer.RxSize:=128; //Rx buffer size
TCPServer.TxSize:=128; //Tx buffer size
// Time init.
TimeBf:=SysTimeGetMs(); //Time buffer (mS)
END_IF;
// Manage the TCP server.
TCPServer(Enable:=TRUE); //TCPServer management
IF NOT(SysFIsOpen(Fp)) THEN RETURN; END_IF;
// -------------------------------------------------------------------------
// COUNT AND SENDING VALUE
// -------------------------------------------------------------------------
// Every 1,5 second print out the counter value.
IF ((SysTimeGetMs()-TimeBf) >= TO_UDINT(T#1s500ms)) THEN
// Try to allocate memory, when it's possible counter is managed.
IF (SysRMAlloc(64, ADR(SOut))) THEN
TimeBf:=SysTimeGetMs(); //Time buffer (mS)
MSize:=SysRMGetSize(ADR(SOut)); //Memory size
Counter:=Counter+1; //Counter
IF (MSize = 64) THEN
eTO_JUNK(DateTimeFormat(TO_LDATE_AND_TIME(SysDateGetNs()), ADR('\[H\:i\:s\.v\]\ '), SOut, MSize));
eTO_JUNK(SysCVsnprintf(SOut, MSize, ADR('MSize:%d'), UDINT_TYPE, ADR(MSize)));
eTO_JUNK(SysCVsnprintf(SOut, MSize, ADR(', Counter:%04d$r$n'), UDINT_TYPE, ADR(Counter)));
eTO_JUNK(Sysfwrite(SOut, TO_INT(Sysstrlen(SOut)), 1, Fp));
END_IF;
eTO_JUNK(SysRMFree(ADR(SOut))); //Fre memory
END_IF;
END_IF;
// [End of file]