Vai al contenuto

Funzioni gestione memoria rilocabile

Vai all indice del manuale di programmazione
Tipo: Funzione
Libreria LogicLab: eLLabXUnified12
Libreria Codesys: Non disponibile

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.

    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

    Immagine funzione SysRMAlloc

    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.

    Immagine F_SysRMGetSize

    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.

    Immagine F SysRMFree

    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]
    Was this article helpful?