Autor Tema: Que hacer cuando nos quedamos cortos con la RAM  (Leído 1754 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado RICHI777

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1498
Que hacer cuando nos quedamos cortos con la RAM
« en: 16 de Octubre de 2009, 13:14:52 »
Hola gente, aca dejo algunos consejos de que hacer cuando nos quedamos cortos con la RAM. Los consejos van orientados a micros de 8 bits de FreeScale, pero basicamente se pueden aplicar a otros micros.

Zero Page y resto de la memoria
En los micros HC(S)08 la memoria RAM arranca desde la posición 0x80 hasta la posición final que depende de cada familia, los 128 bytes más bajos ( 0x80 - 0xFF ) se denominan ZERO PAGE y en esta zona el micro puede acceder en forma mas eficiente que al resto de la memoria, por esta razon el compilador separa el acceso a la misma.
Si arrancamos un projecto normal con el compilador todas las alocaciones de variables globales son colocadas a partir de la direccion 0x100 y de esta manera tendremos 128 bytes que nunca serán usados. Si queremos acceder a estas posiciones podemos usar estas dos técnicas, existen más pero no me parecen prolijas.

Mediante pragmas
Código: C
  1. #pragma DATA_SEG _DATA_ZEROPAGE
  2. int Index1;
  3.  
  4. #pragma DATA_SEG DEFAULT
  5. int Index2;

En este caso Index1 se alocara entre las direcciones 0x80 y 0xFF e Index2 entre las direcciones 0x100 y el final. Lo bueno de este método es que el compilador al saber a que región pertenece cada variable, aprovecha los modos de direccionamiento mas eficientes para cada caso, la contra que tiene este método es que el código queda menos limpio al colocar estos pragmas.

Modificando el archivo de configuración del linker
En este caso tocamos el archivo de configuración del linker para nuestro proyecto ( extension PRM ) de la sgte manera:
Código: C
  1. NAMES END
  2.  
  3. SEGMENTS
  4.     RAM                      =  READ_WRITE   0x0080 TO 0x086F;
  5.     ROM                      =  READ_ONLY    0x1860 TO 0xFFAF;
  6.     ROM1                     =  READ_ONLY    0x0870 TO 0x17FF;
  7.     ROM2                     =  READ_ONLY    0xFFC0 TO 0xFFCB;
  8. END
  9.  
  10. PLACEMENT
  11.     DEFAULT_RAM              INTO  RAM;
  12.     _PRESTART,               /* startup code */
  13.     STARTUP,                 /* startup data structures */
  14.     ROM_VAR,                 /* constant variables */
  15.     STRINGS,                 /* string literals */
  16.     VIRTUAL_TABLE_SEGMENT,   /* C++ virtual table segment */
  17.     DEFAULT_ROM,
  18.     COPY                     /* copy down information: how to initialize variables */
  19.                              INTO  ROM; /* ,ROM1,ROM2: To use "ROM1,ROM2" as well, pass the option -OnB=b to the compiler */  
  20. END

Al realizar esto el linker empieza alocar desde la dirección 0x80, los pro de este método es que no tengo que estar ensuciando el código con pragmas, la contra ahora es que el compilador no va usar instrucciones mas eficientes al acceder a las variables alocadas entre 0x80 y 0xFF.

Uso de uniones
Las uniones son similares a las estructuras, pero el tamaño final de la misma es igual al máximo elemento de los componentes que la componen, si se quiere saber mas sobre uniones se debe consultar bibliografía.

Código: C
  1. typedef union
  2. {
  3.   byte TCPTxBuffer[256];
  4.   byte ModemAnswer[128];
  5.   dword RetriesCnt;
  6. }tOverlayBuffer;

En este caso el tamaño de la union tOverlayBuffer sera de 256 bytes porque TCPTxBuffer mide eso y es el elemento mas grande, de esta manera estoy colocando 3 variables en un mismo bloque de memoria de 256 bytes, sino usara la union deberia destinar 256+128+4 = 388 bytes ! con el ahorro de 132 bytes. Pero no todo lo que reluce en la vida es oro, la cuestión es que como ahora las variables estan compartidas el uso de las mismas no puede ser simultaneo. Para el correcto uso de esta técnica, uno deberá analizar el arbol de ejecución de nuestras funciones y determinar que variables son accedidas/modificadas en diferentes ramas y asi colocarlas dentro de la union.

Uso de máscaras en vez de flags booleanos

Código: C
  1. bool IsButton1Pressed;
  2. bool IsButton2Pressed;
  3. bool GPSInited;

En este caso tenemos tres flags que indican un estado ( on-off ) y como el bool es C es normalmente un typdef de un byte para los tres flags ocupamos 3 bytes, podemos reemplazar estos 3 bytes por un solo byte utilizando estas macros:

Código: C
  1. #define IS_BUTTON1_PRESSED 0x01
  2. #define IS_BUTTON2_PRESSED 0x02
  3. #define GPS_INITED            0x04
  4.  
  5. #define CLEARFLAG( Flag, FlagMask )                      \
  6.                    (( Flag ) &= ( ~FlagMask ))                  
  7.                    
  8. #define SETFLAG( Flag, FlagMask )                         \
  9.                  (( Flag ) |= ( FlagMask ))                      
  10.                  
  11. #define ISFLAGSET( Flag, FlagMask )                       \
  12.                    ((( Flag ) & ( FlagMask )) != 0 )            
  13.  
  14. /* Aloco mascara global */
  15. byte GlobalMask;
  16. ...
  17.  
  18. /*Seteo Flasg */
  19. SETFLAG( GlobalMask, IS_BUTTON1_PRESSED );
  20.  
  21.  
  22. /* Borro Flag */
  23. CLEARFLAG( GlobalMask, IS_BUTTON2_PRESSED );
  24.  
  25. /* Pregunto */
  26. if ( ISFLAG( GlobalMask, GPS_INITED ))
  27.  ...
  28. else
  29.  ...

Las máscaras deben ser definidas como constantes con un solo bit prendido, por eso en un byte podemos solamente usar 8 máscaras ( 0x01-0x02-0x04-0x10-0x20-0x40-0x80) de esta manera podemos ahorrarmos 7 bytes por cada 8 flags globales. Tambien podemos apilar mascaras tanto para el Set, Clear o verificacion usando el operador (|) or .

Existen otras técnicas, como por ejemplo el uso de tipos bit, pero no son estandares del ANSI C, asi que no las uso y no todos los compiladores la soportan.

Espero les sirva.

Saludos !
« Última modificación: 17 de Octubre de 2009, 23:34:14 por RICHI777 »

Desconectado LABmouse

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3575
    • Juntos es mejor
Re: Que hacer cuando nos quedamos cortos con la RAM
« Respuesta #1 en: 17 de Octubre de 2009, 22:38:17 »
Estupenda explicación, muchas gracias por dedicar tiempo a enseñarnos!

SALUDOS!

Desconectado RICHI777

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1498
Re: Que hacer cuando nos quedamos cortos con la RAM
« Respuesta #2 en: 17 de Octubre de 2009, 23:36:07 »
Gracias amigo, pero no se compara a todo lo que ud da a este foro !

Saludos !


 

anything