Autor Tema: ¿Cómo reducir el consumo de ram usando CCS?  (Leído 3199 veces)

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

Desconectado rafaelrg06

  • PIC12
  • **
  • Mensajes: 54
¿Cómo reducir el consumo de ram usando CCS?
« en: 04 de Agosto de 2015, 13:27:38 »
Hola amigos, tengo una duda importante que hace tiempo me viene dando vueltas:
Tengo un código que tiene 6 matrices, desde 2*3 hasta 2*15 de tamaño. En el código solo uso 1 de ellas en un momento dado, nunca uso más de 1 matriz. Sin embargo, desconozco la forma de lograr que el CCS solo cargue en RAM una matriz, (descartando en ram a las restantes) y que luego, cuando sea necesario usar la otra, "descargar" la actual y cargue la nueva matriz, con el ahorro de memoria que esto conlleva.
Yo tengo un código con una estructura case y una función dentro de cada uno de ellos que es la que se encarga de llamar a la matriz deseada. La estructura switch -case vuelve prácticamente imposible el llamar a 2 matrices simultáneamente (segun mi apreciación, claro está). Si cambio la programacion y defino las matrices dentro de los case (para que tengan alcance local, ya que como están en ejemplo debajo son de alcance global), entonces el consumo de ram aumenta significativamente.
¿Alguien conoce como resolver este asunto?, ¿tienen algunas otras ideas de como reducir el consumo de memoria ram programando con CCS? Desde ya el agradecimiento.
El micro que uso es un 16f628a.


El código es algo parecido a esto:

//configuracion del pic
...
...
int matriz1[3][2] = {255, 3
                     255, 3
                     255, 3};
int matriz2[15][2] = {0};
                 
int matriz2[15][2] = {0};
int matriz2[12][2] = {0};
int matriz2[12][2] = {0};
int matriz2[12][2] = {0};

...
//seccion de funciones
...
//seccion de interrupciones
...

void main
{
while(true)
{

   switch(estado)
   {
      case(0): //aqui no carga ninguna matriz
         
            while(estado ==0)
            {
         restart_wdt();         //Resetear el watchdog
            }
         break;
      case(1): //carga de matriz1
         
                arrow(matriz1);//esta es la funci'on que carga la matriz
         break;
      case(2):  //carga de matriz2
      arrow(matriz2);//esta es la funci'on que carga la matriz
         break;
      case(3):  //carga de matriz3
      arrow(matriz3);//esta es la funci'on que carga la matriz
         break;
      case(4):  //carga de matriz4
      arrow(matriz4);//esta es la funci'on que carga la matriz
         break;
      case(5):  //carga de matriz5
      arrow(matriz5);//esta es la funci'on que carga la matriz
         break;
      case(6):  //carga de matriz6
      arrow(matriz6);//esta es la funci'on que carga la matriz
         break;
     
   } //Cierre del switch(estado)
}//Cierre del while(true)
}//Cierre del main

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: ¿Cómo reducir el consumo de ram usando CCS?
« Respuesta #1 en: 04 de Agosto de 2015, 21:40:39 »
Citar
Tengo un código que tiene 6 matrices, desde 2*3 hasta 2*15 de tamaño. En el código solo uso 1 de ellas en un momento dado, nunca uso más de 1 matriz. Sin embargo, desconozco la forma de lograr que el CCS solo cargue en RAM una matriz, (descartando en ram a las restantes) y que luego, cuando sea necesario usar la otra, "descargar" la actual y cargue la nueva matriz, con el ahorro de memoria que esto conlleva.

Dejame ver si entiendo, por que no directamente definir una matriz de 2*15 y usar esa para todos los casos? si necesitas solo 3 valores entonces utilizas 3 de los 15 nomas.

Ahora si tu problema es que estas matrices tienen distintos valores iniciales. Por el PIC que estas usando ( que no posee posibilidad de leer de la flash) vas a necesitar guardar los datos en la EEPROM.
Entonces cada vez que uses una matriz distinta, vas a tener que leer de la EEPROM todos los valores para esa matriz y guardarlo en la matriz ( 2 * 15), obviamente vas a llenar la EEPROM de valores. y en tu programa seguis manteniendo la matriz 2*15 + una variable que te indique cual es el maximo, si 3 ,5,9 o 15

Citar
Yo tengo un código con una estructura case y una función dentro de cada uno de ellos que es la que se encarga de llamar a la matriz deseada. La estructura switch -case vuelve prácticamente imposible el llamar a 2 matrices simultáneamente (segun mi apreciación, claro está). Si cambio la programacion y defino las matrices dentro de los case (para que tengan alcance local, ya que como están en ejemplo debajo son de alcance global), entonces el consumo de ram aumenta significativamente.

Imagino que si por que ya cuando lo definis como local, las variables son creadas en el stack que utiliza C y no una direccion absoluta como seria con las globales.

Desconectado rafaelrg06

  • PIC12
  • **
  • Mensajes: 54
Re: ¿Cómo reducir el consumo de ram usando CCS?
« Respuesta #2 en: 05 de Agosto de 2015, 15:27:09 »
Hola KILLERJC:
La respuesta que me diste es un poco novedosa para mí por 2 razones:

-La primera es que nunca he trabajado con la EEPROM y por eso me surgen algunas inquietudes, por ejemplo: ¿las variable las cargaría en la EEPROM por software en la propia programación (digamos leyendo las variables en un inicio, cargándolas en la EEPROM y a partir de ahí solo utilizarlas desde la EEPROM, o por el contrario, grabarlas directamente en el hardware de la EEPROM directamente desde el grabador del micro (PICKIT3 en este caso)? En el segundo caso (el de grabarla la EEPROM desde el grabador de PIC) ¿con que herramienta podría generar el archivo a grabar en la EEPROM?

-La segunda interrogante es la siguiente: ¿no se supone que si en C se declara una variable como local (digamos dentro de una función) la misma se crea cuando se llama dicha función y se destruye automáticamente al salir, dejando libre la memoria que ocupó dicha variable? Lo que estoy viendo (según mi apreciación, que puede estar sujeta a errores) es que aún en este tipo de condiciones el consumo de memoria no disminuye. ¿Tiene que ver esto con el stack que mencionas?, si pudieras explicarme un poco eso del stack quizás pudiera entender mejor como el compilador maneja este asunto de la memoria y las variables.

Te reitero las gracias y por favor, te agradecería que me siguieras ayudando en esto.

Desconectado allennet

  • PIC16
  • ***
  • Mensajes: 112
Re: ¿Cómo reducir el consumo de ram usando CCS?
« Respuesta #3 en: 05 de Agosto de 2015, 17:49:09 »
tambien si son constantes (que solo cargas el valor y los muestras) solo agrega "const" ejemplo
const int matris1
y se agrega a la flash
"La curiosidad mato al gato, pero murio sabiendo"

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: ¿Cómo reducir el consumo de ram usando CCS?
« Respuesta #4 en: 06 de Agosto de 2015, 03:39:50 »
tambien si son constantes (que solo cargas el valor y los muestras) solo agrega "const" ejemplo
const int matris1
y se agrega a la flash

Creo que no le sirve de nada por que le PIC16F628A no puede leer desde la Flash, no creo haberme confundido y haber mirado mal el datasheet.
Pero tal ves con const lo grabe en la EEPROM, eso depende de lo que diga el linker

Citar
-La primera es que nunca he trabajado con la EEPROM y por eso me surgen algunas inquietudes, por ejemplo: ¿las variable las cargaría en la EEPROM por software en la propia programación (digamos leyendo las variables en un inicio, cargándolas en la EEPROM y a partir de ahí solo utilizarlas desde la EEPROM, o por el contrario, grabarlas directamente en el hardware de la EEPROM directamente desde el grabador del micro (PICKIT3 en este caso)? En el segundo caso (el de grabarla la EEPROM desde el grabador de PIC) ¿con que herramienta podría generar el archivo a grabar en la EEPROM?

Esto depende, yo no se como tenes definido tus arrays,

- Si cada array tiene valores distintos y son todos constantes (es decir siempre cargas los mismos al comienzo) entonces ahi sugiero ir por grabarlos en la EEPROM, en la Flash como dije no por que ese PIC no puede leer de la misma.
- Si cada array tiene los mismos valores pero solo usas algunos nomas y nuevamente comienzan con un valor siempre igual, entonces mejor aun y usas la EEPROM
- Si los valores de los array dependen de otra condicion entonces y no son siempre los mismos valores en cada array de comienzo, entonces no tenes que guardar nada. Creo que este es tu caso, ya que estas "cargando" los valores al array dentro del switch, si es asi entonces no necesitas guardar nada en la EEPROM, y solo tener en cuenta que deebrias limitarte a usar solo algunos valores.

En C hay formas de guardar en el EEPROM, en C creo que es:

#rom getenv("EEPROM_ADDRESS")={0x00,0x23,......,0x34}

Aunque no estoy muy seguro por que no use CCS, eso te lo va a agregar en el .hex para que lo grabes.

Citar
-La segunda interrogante es la siguiente: ¿no se supone que si en C se declara una variable como local (digamos dentro de una función) la misma se crea cuando se llama dicha función y se destruye automáticamente al salir, dejando libre la memoria que ocupó dicha variable? Lo que estoy viendo (según mi apreciación, que puede estar sujeta a errores) es que aún en este tipo de condiciones el consumo de memoria no disminuye. ¿Tiene que ver esto con el stack que mencionas?, si pudieras explicarme un poco eso del stack quizás pudiera entender mejor como el compilador maneja este asunto de la memoria y las variables.

Asi es...

Una variable global, sabes el espacio que ocupa y C sabe que no se destruye asi que lo crea en un espacio que no va a tocar en la RAM.
En cambio una local ( ya sea en el main o donde sea ) debe hacer espacio para esas variables, entonces usa la RAM que sobra como stack, que funcion cumple este stack?, almacena todas las variables locales, cuando se llama a una funcion se crea mas informacion apuntando a la base de la "seccion" anterior (ej correspondiente al main) y comienza a guardarse las nuevas variables locales a partir de ese punto del stack, cuando se sale de esa funcion, se toma la direccion de la seccion anterior (main) y se carga el stack pointer con ese valor
Lo que le llaman Frame, es como separan entre una funcion u otra, aca te doy una imagen para que me entiendas:
https://upload.wikimedia.org/wikipedia/en/a/a7/ProgramCallStack2.png
Donde si seguimos con el ejemplo anterior el Frame (N-3) es el main, luego llama a una funcion y se crea el frame (N-2) con las variables locales de esa funcion, si se llama a otra funcion con variables locales se crea el proximo y asi... cuando se deja de usar vuelve el stack pointer a apuntar al frame anterior.

Asi se maneja el stack.
Si vos creas tus variables locales en el main, no hay forma que se borren. por que quedan en ese stack a no ser que tu switch llame a una funcion distinta y ahi cree cada uno de los arrays. Pero creo que esto no es lo que queres hacer vos.
Tambien hay otra cosa llamada Heap en C, pero creo que no lo implementan aca en los micros.

Ademas si creas un solo array, no vas a tener problema de RAM ya que ocuparias 30 de 224 bytes.

Desconectado rafaelrg06

  • PIC12
  • **
  • Mensajes: 54
Re: ¿Cómo reducir el consumo de ram usando CCS?
« Respuesta #5 en: 06 de Agosto de 2015, 12:16:57 »
Muy bien, me parece muy buena la explicación, quedé bastante esclarecido, muchas gracias. El único punto es que no me queda claro cómo escribir en la eeprom usando CCS, pero voy a buscar un poco en el foro. De cualquier manera agradecería a quien supiera la respuesta!!!!

Saludos y agradecido por sus respuestas.