Autor Tema: Not enough RAM for all variables  (Leído 9602 veces)

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

Desconectado carafaelet

  • PIC12
  • **
  • Mensajes: 61
Not enough RAM for all variables
« en: 02 de Diciembre de 2008, 18:48:29 »
Hola amigos, Not enough RAM for all variables es el error que me da cuando intento compilar el código expuesto mas abajo, que básicamente digitaliza unas señales analógicas i las envia por 232 (que ya me funciona perfectamente) y a su vez se pretende que a través de 232 le puedan llegar órdenes como por ejemplo que deje de capturar las señales analógicas, que encienda un led,.. Y esto último es precisamente lo que me esta dando problemas y es lo que expongo a continuación:
Código: [Seleccionar]

void rece_232()
{

int buffer[tam_buf],i=0;
buffer[i++]=getc();
for(i=0; i<8; i++)
{
byt0[i]=buffer[i];
}
for(i=8; i<16; i++)
{
byt1[i]=buffer[i];
}
for(i=16; i<24; i++)
{
byt2[i]=buffer[i];
}
for(i=24; i<32; i++)
{
byt3[i]=buffer[i];
}
for(i=32; i<40; i++)
{
byt4[i]=buffer[i];
}

}

#INT_RDA
Interrupcio_recep232()
{
rb2=1;
rece_232();
}

Donde los siguientes parámetros estan definidos de forma global
Código: [Seleccionar]
#define tam_buf   40
#define tam_byt   8
int conta_byt=0,cont_sens,byt0[tam_byt],byt1[tam_byt],byt2[tam_byt],byt3[tam_byt],byt4[tam_byt];

El problema viene cuando se usa el tipo de dato especial:
Código: [Seleccionar]
int nombre_variable[x], esto me ocupa muchiiiisima memoria RAM, aunque tengo que decir que antes de usar esto ya me movia con un uso de la RAM entre el 75% y el 85%, a que puede deberse? Por si sirve de algo comentar que la función principal del programa (main) es muy corta y lo que hace es ir llamando a funciones que a la vez se llaman entre ellas y que se encuentran en diversos .c  con sus respectivos .h (esto lo tengo que arreglar y linkar). Uso un 16F877A transmitiendo a 9600 baudios.

Un saludo.
En esta vida hay 10 clases de personas, las que saben binario y las que no.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Not enough RAM for all variables
« Respuesta #1 en: 02 de Diciembre de 2008, 19:58:37 »
Hola

¿Cuánto vale x en la línea int nombre_variable[ x ]?

Recuerda que la ram de los pics está seccionada en bancos y si pones arreglos que excedan el tamaño de un banco o que no quepan en un banco debido a que ya hay muchos registros empleados, entonces el compilador no puede partir en fragmentos el arreglo y simplemente no puede compilar tu programa.

El PIC16F877A tiene 368 bytes de uso general, pero seccionados en 4 arreglos, es decir, ram no continua:

- 0x020 a 0x07f (96 bytes banco 0)
- 0x0a0 a 0x0ef (80 bytes banco 1)
- 0x110 a 0x16f (96 bytes banco 2)
- 0x190 a 0x1ef (96 bytes banco 3)

Y además de la ram que tú empleas en tu proyecto, el compilador reserva su propia ram para subrutinas y demás cosas internas que él realiza.

Desconectado carafaelet

  • PIC12
  • **
  • Mensajes: 61
Re: Not enough RAM for all variables
« Respuesta #2 en: 03 de Diciembre de 2008, 05:40:32 »
Gracias apañero!! Si observas en el código, mi variable x tiene como valor "tam_buf" y "tam_byt" que estan definidas como un valor constante de 40 y 8 respectivamente. Lo que queria decir al poner int nombre_variable[ x ] es que esto usa mogollon de memoria, además no se si me sirve para lo que yo quiero hacer, que és recoger una trama de 5 bytes (40 bits), recibida por 232, para posteriormente analizarla y actuar segun lo que pida. Además es que me descoloca un poco el que este usando tanta memoria, no se no entiendo que haya podido ocupar ya toda la RAM, mas bien me da la sensación de que no hago algo bien y estoy ocupoando mas memoria de la necesaria..  :?
En esta vida hay 10 clases de personas, las que saben binario y las que no.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Not enough RAM for all variables
« Respuesta #3 en: 03 de Diciembre de 2008, 13:22:34 »
Si publicas el código completo talvez se te pueda ayudar más.  :)

Desconectado carafaelet

  • PIC12
  • **
  • Mensajes: 61
Re: Not enough RAM for all variables
« Respuesta #4 en: 03 de Diciembre de 2008, 14:43:06 »
Gracias de nuevo  :) , no lo he publicado antes porque en total son 15 ficheros (lo cual tengo que arreglar agrupando código) con mas de 1300 lineas de código.. Y quitando de esta parte, el resto funciona todo perfectamente. A continuación pongo el main por ser la función principal, pero bueno si entendeis que el error pueda venir de otra parte me lo comentais y lo posteo, aunque ya digo que el resto de funciones cumplen su papel a la perfección.

Código: [Seleccionar]
#include <16F877A.h>       //Capçalera del Pic utilitzat
#include <elecponic.h>     //Capçalera del programa ppal
#include <pins16F877A.h>   //Capçalera de definició dels pins del uC
#include <hardware.c>      //Llibreria del mode de funcionament manual
#include <serie.c>         //Llibreria del mode de funcionament Labview
#include <antirebots.c>    //Llibreria del sistema antirebots




short labview=0,manual=0;


void main()
{



//fun_sensar();

rb1=1;
init(); //Inicialitza

while(1)

{
if(labview==1)     //Selecció Labview
{
//fun_sensar();
}

if(manual==1)     //Selecció Manual
{
hardware();
}
}


Luego tambien lo que hago establecerme los bits y registros con su propio nombre, por ejemplo los de la función de lectura en la conversión A/D:
Código: [Seleccionar]
#nolist

#byte ADCON1=0x9F  //Bits de configuració del conversor AD
#byte ADRESH=0x1E
#byte ADRESL=0x9E
#bit adcs1=0x1F.7
#bit adcs0=0x1F.6
#bit chs2=0x1F.5
#bit chs1=0x1F.4
#bit chs0=0x1F.3
#bit godone=0x1F.2
#bit adon=0x1F.0

#list

Esto lo hago asi para no usar las "built functions" del compilador, y soy yo mismo el que va poniendo a zero o a uno los bits o configurando el registro entero donde se encuentren siguiendo los pasos que indica el datasheet. Y lo hago así porque aprendo mas sobre que registro se acuta y como, ya que con las funciones esto no lo sabes. Me funciona muy bien aunque quizà sea esto lo que este ocupando mucha memoria? No se, seguire pensando a ver que mas puedo estar haciendo mal y lo posteo.
« Última modificación: 03 de Diciembre de 2008, 15:30:29 por carafaelet »
En esta vida hay 10 clases de personas, las que saben binario y las que no.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Not enough RAM for all variables
« Respuesta #5 en: 03 de Diciembre de 2008, 20:36:07 »
Mencionaste anteriormente que el programa compila bien sin la línea int nombre_variable[ x ], ¿cuánta memoria RAM usa ese programa en el peor de los casos?

Para saberlo hay un archivo.sta que genera CCS y dice algo así...

Código: [Seleccionar]
RAM used: 12 (7%) at main() level
          24 (14%) worst case

... el que interesa es el worst case. Súmale al worst case los bytes que mide nombre_variable y checa si cabe en la RAM.

Otro método para calcular la RAM casi total es haciéndolo a mano. Sumas los bytes de las variables de cada subfunción y luego consideras el peor caso, que es cuando una subfunción llama a todas las subfunciones que puede llamar.

Si no quedas satisfecho con tus sumas puedes darle una leída a este tema que habla del mismo problema que tienes.

http://www.todopic.com.ar/foros/index.php?topic=23314.msg186791#msg186791

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Not enough RAM for all variables
« Respuesta #6 en: 04 de Diciembre de 2008, 13:10:29 »
otra forma es reasignar las variables a mano, asignadolas todas en un banco (las que se puedan) y tratar de desocupar un banco entero solo para el array

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado carafaelet

  • PIC12
  • **
  • Mensajes: 61
Re: Not enough RAM for all variables
« Respuesta #7 en: 05 de Diciembre de 2008, 15:06:11 »
Si migsantiago la información sobre la ram que aparece en archivo.sta es la misma que te aparece cuando compilas el código, de ahi que dijese antes que me estaba moviendo entre un 75 i 85% de ram. De momento he optado por definirme un arreglo de tamaño 5, que creo que es lo que yo buscaba ya que no caí en la cuenta de que realmente me estava definiendo un array de 40 bytes y en realidad lo que necesito es un array de 5 bytes (40bits), que es lo que recibo por 232. Asi si que me lo compila ya que no se saldrà del banco de memoria como bien dices migsantiago, ahora mismo tengo:
Memory usage:   ROM=45%      RAM=19% - 82%

Ahora me falta conseguir que el pic capture esos 5bytes correctamente, pero bueno eso ya es otro cantar..

PalitroqueZ, lo que comentas es interesante porque ademàs las variables estarian mas ordenadas y se tendria un mayor control sobre ellas. En ensamblador parece algo mas obvio, pero en C como seria mas o menos el algoritmo o la instrucción? Y en el CCS existirà alguna función para ello.. hmmm....

Saludos
En esta vida hay 10 clases de personas, las que saben binario y las que no.

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Not enough RAM for all variables
« Respuesta #8 en: 05 de Diciembre de 2008, 18:17:55 »
...pero en C como seria mas o menos el algoritmo o la instrucción? Y en el CCS existirà alguna función para ello.. hmmm....
...

con el ccs, se usa las directiva #locate


http://www.todopic.com.ar/foros/index.php?topic=20313.msg172312#msg172312

es una ejemplo que pongo, porque no se si el arrays que tienes supera el espacio de un banco.

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado carafaelet

  • PIC12
  • **
  • Mensajes: 61
Re: Not enough RAM for all variables
« Respuesta #9 en: 06 de Diciembre de 2008, 16:08:55 »
Grácias PalitroqueZ, esta muy claro el ejemplo y es una función bastante sencilla de usar, supongo que lo unico a tener en cuenta es que esto deberas hacerlo con todas las variables o con ninguna para evitar machacar las que almacena el CCS con las que almacenas tu diciendole exactamente donde la quieres, no? A parte de eso esta el tema que comentas, de la longitud del array, al estar fracccionada la memoria en bancos, hay que ir con cuidadin..
En esta vida hay 10 clases de personas, las que saben binario y las que no.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Not enough RAM for all variables
« Respuesta #10 en: 07 de Diciembre de 2008, 21:48:23 »
Hablando sobre #locate, tuve problemas al implementarla para una simulación que estoy haciendo. Mi código es el siguiente, bastante simple...

Código: [Seleccionar]
#include "16f877a.h"

//Obligo al compilador a ubicar variables en esta posición de memoria
#locate resultado=0x50 //entero de 8 bits
#locate mult=0x51      //entero de 8 bits

void main()
{
int8 resultado=0;
int8 mult=12;

resultado=12*mult;

//ahora para poder ver en la simulación de vhdl el resultado pongo
//código en asm para pasar el valor a w
while(1)
   {
   #asm
   movf 0x50,w
   movf 0x51,w
   #endasm
   }
}

El código en ensamblador en ninguna parte utiliza las localidades 0x50 y 0x51 para sus cálculos, únicamente lo hace en la parte que obligué a trabajar en ASM...

Código: [Seleccionar]
  0x0000 : 0x3000   movlw   0x00
  0x0001 : 0x008A   movwf   0x0A
  0x0002 : 0x282B   goto    0x2B
  0x0003 : 0x0000   nop   
  0x0004 : 0x01F7   clrf    0x77
  0x0005 : 0x01F8   clrf    0x78
  0x0006 : 0x0823   movf    0x23 , W
  0x0007 : 0x1003   bcf     0x03 , 0
  0x0008 : 0x1824   btfsc   0x24 , 0
  0x0009 : 0x07F7   addwf   0x77 , F
  0x000A : 0x0CF7   rrf     0x77 , F
  0x000B : 0x0CF8   rrf     0x78 , F
  0x000C : 0x18A4   btfsc   0x24 , 1
  0x000D : 0x07F7   addwf   0x77 , F
  0x000E : 0x0CF7   rrf     0x77 , F
  0x000F : 0x0CF8   rrf     0x78 , F
  0x0010 : 0x1924   btfsc   0x24 , 2
  0x0011 : 0x07F7   addwf   0x77 , F
  0x0012 : 0x0CF7   rrf     0x77 , F
  0x0013 : 0x0CF8   rrf     0x78 , F
  0x0014 : 0x19A4   btfsc   0x24 , 3
  0x0015 : 0x07F7   addwf   0x77 , F
  0x0016 : 0x0CF7   rrf     0x77 , F
  0x0017 : 0x0CF8   rrf     0x78 , F
  0x0018 : 0x1A24   btfsc   0x24 , 4
  0x0019 : 0x07F7   addwf   0x77 , F
  0x001A : 0x0CF7   rrf     0x77 , F
  0x001B : 0x0CF8   rrf     0x78 , F
  0x001C : 0x1AA4   btfsc   0x24 , 5
  0x001D : 0x07F7   addwf   0x77 , F
  0x001E : 0x0CF7   rrf     0x77 , F
  0x001F : 0x0CF8   rrf     0x78 , F
  0x0020 : 0x1B24   btfsc   0x24 , 6
  0x0021 : 0x07F7   addwf   0x77 , F
  0x0022 : 0x0CF7   rrf     0x77 , F
  0x0023 : 0x0CF8   rrf     0x78 , F
  0x0024 : 0x1BA4   btfsc   0x24 , 7
  0x0025 : 0x07F7   addwf   0x77 , F
  0x0026 : 0x0CF7   rrf     0x77 , F
  0x0027 : 0x0CF8   rrf     0x78 , F
  0x0028 : 0x118A   bcf     0x0A , 3
  0x0029 : 0x120A   bcf     0x0A , 4
  0x002A : 0x283D   goto    0x3D
  0x002B : 0x0184   clrf    0x04
  0x002C : 0x301F   movlw   0x1F
  0x002D : 0x0583   andwf   0x03 , F
  0x002E : 0x1683   bsf     0x03 , 5
  0x002F : 0x141F   bsf     0x1F , 0
  0x0030 : 0x149F   bsf     0x1F , 1
  0x0031 : 0x151F   bsf     0x1F , 2
  0x0032 : 0x119F   bcf     0x1F , 3
  0x0033 : 0x3007   movlw   0x07
  0x0034 : 0x009C   movwf   0x1C
  0x0035 : 0x1283   bcf     0x03 , 5
  0x0036 : 0x01A1   clrf    0x21
  0x0037 : 0x300C   movlw   0x0C
  0x0038 : 0x00A2   movwf   0x22
  0x0039 : 0x00A3   movwf   0x23
  0x003A : 0x0822   movf    0x22 , W
  0x003B : 0x00A4   movwf   0x24
  0x003C : 0x2804   goto    0x04
  0x003D : 0x0878   movf    0x78 , W
  0x003E : 0x00A1   movwf   0x21
  0x003F : 0x0850   movf    0x50 , W
  0x0040 : 0x0851   movf    0x51 , W
  0x0041 : 0x283F   goto    0x3F
  0x0042 : 0x0063   sleep 
  0x0043 : 0x3FFF   Data    0x3FFF      ; ?
  0x0044 : 0x3FFF   Data    0x3FFF      ; ?

Solo se usan en mi código ASM pero nunca en el de C. Por ahora intentaré otra forma de pasarlas por w, pero si saben el porqué, porfas avísenme  :mrgreen:

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Not enough RAM for all variables
« Respuesta #11 en: 08 de Diciembre de 2008, 16:09:54 »
...supongo que lo unico a tener en cuenta es que esto deberas hacerlo con todas las variables o con ninguna para evitar machacar las que almacena el CCS con las que almacenas tu diciendole exactamente donde la quieres, no? A parte de eso esta el tema que comentas, de la longitud del array, al estar fracccionada la memoria en bancos, hay que ir con cuidadin..

si ese es el detalle, que habría que salirse un poco de la lógica del C y pensar un poco en asm  :?

Santiago ya me pongo a revisar el programa  :P

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Not enough RAM for all variables
« Respuesta #12 en: 08 de Diciembre de 2008, 23:51:40 »
Gracias Pali.

Creo que locate sirve para proteger direcciones de memoria para que ccs no las toque para nada. En la ayuda de CCS dice que locate funciona como #byte pero con la excepción de que byte si permite el uso de memoria.

La verdad está muy confuso y preferí checar el código que viene en el archivo .lst para ver en donde guardaba CCS las variables.  :z)

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: Not enough RAM for all variables
« Respuesta #13 en: 09 de Diciembre de 2008, 19:09:00 »
Hola

...
Creo que locate sirve para proteger direcciones de memoria para que ccs no las toque para nada. ...

para eso está la directiva #reserve

Al programa de ejemplo que subiste, le falta definir las variables de manera adecuada.

por ejemplo, para asignar una variable, hay que declararla primero

Código: C
  1. ...
  2. int8 resultado;
  3. int8 mult;
  4. #locate resultado=0x50 //entero de 8 bits
  5. #locate mult=0x51      //entero de 8 bits
  6. ...

en tal caso no hace falta declararlas posteriormente, solo procesarlas (guardar, sacar valores), entonces quedaría:

Código: [Seleccionar]
...
void main()
{
resultado=0;
mult=12;
...

el listado generado por ccs:

Código: [Seleccionar]
.................... resultado=0;
0036:  BCF    03.5
0037:  CLRF   50
.................... mult=12;
0038:  MOVLW  0C
0039:  MOVWF  51
.................... 
.................... resultado=12*mult;
003A:  MOVWF  21
003B:  MOVF   51,W
003C:  MOVWF  22
003D:  GOTO   004
003E:  MOVF   78,W
003F:  MOVWF  50
.................... 
.................... //ahora para poder ver en la simulación de vhdl el resultado pongo
.................... //código en asm para pasar el valor a w
.................... while(1)
....................    {
....................    #asm
....................    movf 0x50,w
0040:  MOVF   50,W
....................    movf 0x51,w
0041:  MOVF   51,W
....................    #endasm

« Última modificación: 10 de Diciembre de 2008, 15:26:30 por PalitroqueZ »
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Not enough RAM for all variables
« Respuesta #14 en: 09 de Diciembre de 2008, 20:35:57 »
Ahora sí compila bien como tú dices Pali, gracias  :mrgreen: