Passa al contenuto principale

Funzioni gestione memoria rilocabile

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 topic ulteriori informazioni sull'utilizzo della allocazione dinamica della memoria.
  • In questo articolo informazioni sulla memoria dei sistemi.
  • In questo articolo un programma che esegue una richiesta HTTP di dati in cui viene allocato dinamicamente un buffer di pagina.
  • In questo topic un esempio di allocazione memoria per invio richiesta e ricezione pagina da server HTTP.

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​

Immagine funzione SysRMAlloc

ParametroTipoDescrizione
SizeUDINTIndica la dimensione in bytes dell'area da allocare.
DataPtrPVOIDOccorre indicare l'indirizzo del buffer dove memorizzare il puntatore alla memoria allocata.
OutBOOLFALSE errore allocazione memoria, TRUE 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​

Immagine F_SysRMGetSize

ParametroTipoDescrizione
DataPtrPVOIDOccorre indicare l’indirizzo del buffer che contiene l’indirizzo della memoria allocata.
OutUDINTLa 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​

Immagine F SysRMFree

ParametroTipoDescrizione
DataPtrPVOIDOccorre indicare l’indirizzo del buffer che contiene l’indirizzo della memoria da disallocare.
OutBOOLFALSE errore disallocazione, TRUE 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 *)
Counter : UDINT; (* Counter *)
TimeBf : UDINT; (* Time buffer (mS) *)
MSize : UDINT; (* Buffer size *)
SOut : @STRING; (* String output pointer *)
BSize : UDINT := 64; (* Buffer size definition *)
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 to handle incoming connection.

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(BSize, ADR(SOut))) THEN
MSize:=SysRMGetSize(ADR(SOut)); //Memory size
TimeBf:=SysTimeGetMs(); //Time buffer (mS)
Counter:=Counter+1; //Counter

eTO_JUNK(DateTimeFormat(TO_LDATE_AND_TIME(SysDateGetNs()), ADR('\[H\:i\:s\.v\]\ '), SOut, BSize));
eTO_JUNK(SysCVsnprintf(SOut, BSize, ADR('MSize:%d'), UDINT_TYPE, ADR(MSize)));
eTO_JUNK(SysCVsnprintf(SOut, BSize, ADR(', Counter:%04d$r$n'), UDINT_TYPE, ADR(Counter)));
eTO_JUNK(Sysfwrite(SOut, TO_INT(Sysstrlen(SOut)), 1, Fp));

eTO_JUNK(SysRMFree(ADR(SOut))); //Fre memory
END_IF;
END_IF;

// [End of file]