Autor Tema: Microcontrolador PIC con memoria RAM infinita!  (Leído 4287 veces)

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

Desconectado RodrigoAndres

  • PIC16
  • ***
  • Mensajes: 171
Microcontrolador PIC con memoria RAM infinita!
« en: 17 de Junio de 2015, 12:11:12 »
hola a todos. he desidido pasarme al compilador MPLAB X porque es "mejor" que CCS. el problema que tengo haora es que el MPLAB X cree que el pic que estoy programando tiene memoria infinita.

vean lo siguiente, un pequeño codigo de ejemplo para mostrarles lo ke sucede:


Código: [Seleccionar]
int main(int argc, char** argv)
{
    unsigned int i = 0;
    unsigned int lecturas[50] = {0};
   
    OSCInit();
    ADCOpen();
   
    while(1)
    {
        lecturas[i] = ADCRead();
        i++;
        if(i > 50)
        {
            i = 0;
        }
    }
   
}

con una variable de 50 elementos, todo esta bien y funciona bien por exepxion de una cosa:


raro no? el compilador dice que tengo 0 bytes usados de memoria ram....

ahora probemos que pasa si hacemos que la variable tenga 1000 elementos:

Código: [Seleccionar]
int main(int argc, char** argv)
{
    unsigned int i = 0;
    unsigned int lecturas[1000] = {0};
   
    OSCInit();
    ADCOpen();
   
    while(1)
    {
        lecturas[i] = ADCRead();
        i++;
        if(i > 1000)
        {
            i = 0;
        }
    }
   
}
compilo el codigo sin ningun error..en cuanto a uso de memoria, me sigue diciendo ke tengo la RAM totalmente vacia:


Y si lo simulo usando un programa de simulacion que se llama PROTEUS, de LAB CENTER ELECTRONICS, obtengo lo siguiente:



Que al parecer son errores porque esas direcciones de memoria no existen en el pic. la verdad es que no se como arreglar este problema de que el compilador C30 cree que tengo memoria infinita o algo asi, he buscado mucho en internet y no encuentro nada, ademas asi no puedo saber cuanta memoria RAM estoy usando, les agradeseria su ayuda.

El microcontrolador ke estoy usando se llama DSPIC33FJ12GP201, es un microcontrolador que es como 20 veces mucho mejor que el PIC16F88 que antes utilizaba y por eso lo elegi.


Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2980
Re: Microcontrolador PIC con memoria RAM infinita!
« Respuesta #1 en: 17 de Junio de 2015, 12:29:33 »
Hola rodrigo

¿lo estas simulando verdad?

el problema que tienes, que no lo tienes tu si no el MPLAB, es que cuando simulas no te coge nada de la memoria ram, pero al meterlo en un pic de verdad ya veras como sube eso, y como la espuma por que los ultimos compiladores de microchip, cada vez son mas mierd* y consumen mucha mas memoria y usan mas ram

los fallos que te dan lo mas seguro es que para crear un array tan grande debes definir en tu linker scrip una zona de memoria para uqe te permita hacer unos array tan largos, asi te estas metiendo en zonas de memoria reservadas para otra cosa y seguramente ese es el error que suelta.

un saludo

Desconectado Tisco

  • PIC16
  • ***
  • Mensajes: 108
Re: Microcontrolador PIC con memoria RAM infinita!
« Respuesta #2 en: 17 de Junio de 2015, 12:58:47 »
En el caso del primer ejemplo:

Estás compilando con optimizaciones? Porque en este caso puede ser que el compilador te elimine tus variables porque "no estás haciendo nada" con ellas. No sé el compilador que estás usando, pero normalmente uno bueno te las eliminaría.

Si estás compilando con optimizaciones, prueba a deshabilitarlas a ver qué sucede.

También puede ser un bug en el MPLAB X, el compilador o el linker.


Saludos!

Desconectado RodrigoAndres

  • PIC16
  • ***
  • Mensajes: 171
Re: Microcontrolador PIC con memoria RAM infinita!
« Respuesta #3 en: 17 de Junio de 2015, 13:14:42 »
En el caso del primer ejemplo:

Estás compilando con optimizaciones? Porque en este caso puede ser que el compilador te elimine tus variables porque "no estás haciendo nada" con ellas. No sé el compilador que estás usando, pero normalmente uno bueno te las eliminaría.

Si estás compilando con optimizaciones, prueba a deshabilitarlas a ver qué sucede.

También puede ser un bug en el MPLAB X, el compilador o el linker.


Saludos!

Si, estoy compilando sin optimizaciones.  la verdad aun no logro solucionar el problema.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Microcontrolador PIC con memoria RAM infinita!
« Respuesta #4 en: 17 de Junio de 2015, 13:47:12 »
Cuando compilas te dice:

Código: [Seleccionar]
Memory Summary:
    Program space        used    86h (   134) of  8000h bytes   (  0.4%)
    Data space           used    68h (   104) of   600h bytes   (  6.8%)
    Configuration bits   used     7h (     7) of     7h words   (100.0%)
    EEPROM space         used     0h (     0) of   100h bytes   (  0.0%)
    ID Location space    used     8h (     8) of     8h bytes   (100.0%)
    Data stack space     used     0h (     0) of   53Ah bytes   (  0.0%)

Eso me paso con tu mismo programa, el primero y sin optimizaciones

Esto con 120 palabras de 16bits

Código: [Seleccionar]
Memory Summary:
    Program space        used    86h (   134) of  8000h bytes   (  0.4%)
    Data space           used    F4h (   244) of   600h bytes   ( 15.9%)
    Configuration bits   used     7h (     7) of     7h words   (100.0%)
    EEPROM space         used     0h (     0) of   100h bytes   (  0.0%)
    ID Location space    used     8h (     8) of     8h bytes   (100.0%)
    Data stack space     used     0h (     0) of   40Eh bytes   (  0.0%)

Estoy usando un PIC18F25K20


Programa (bits de configuracion en otro archivo):
Código: C
  1. #include <xc.h>
  2.  
  3. #define _XTAL_FREQ 4000000
  4. /*
  5.  *
  6.  */
  7.  
  8. void main() {
  9.  
  10.     unsigned int i = 0;
  11.     unsigned int lecturas[120];
  12.  
  13.     while(1)
  14.     {
  15.         lecturas[i] = i;
  16.         if(++i == 120)
  17.         {
  18.             i = 0;
  19.         }
  20.     }
  21. }

Active las optimizaciones y el resultado es el mismo..
En la grafica que pasaste y en el resultado luego de la compilacion AMBOS me dan iguales. No probe con 1000 por que son 2000 bytes y como dije juaperser hay que definir una nueva seccion en el linker. Eso esta explicaod en el manual de usuario de XC8


Que micro estas usando?

PD: No use las funciones por que no se de donde salieron ni cuales son. ESA es la diferencia de CCS y XC8 te acostumbras a manejarte con los registros y no con funciones prearmadas ( aunque XC8 tambien las tiene ) Pero si queres andar modificando registros en CCS tenes que estar definiendo uno por uno. Particularmente una de las tantas es la directiva #use (spi,i2c,rs232, etc )

No voy a negar que aceleren hacer las cosas y que me parece excelente, hacer 1 UART por soft tal vez en XC8 te tome mucho tiempo, mientras que en CCS es solo una linea,
El mayor problema, o el unico problema que tengo contra CCS es que te deja un nivel de abstracción demasiado grande. Y que en un programa medio complejo si hay un error te tenes que romper la cabeza.

En si no hay otra diferencia entre XC8 y CCS, solo las librerias y que CCS tiene funciones prearmadas en compilador y no un archivo X donde uno agregue librerias. Ademas de tener la politica por default que te cambie los sentidos de los pines si lees o escribis..
« Última modificación: 17 de Junio de 2015, 14:06:19 por KILLERJC »

Desconectado RodrigoAndres

  • PIC16
  • ***
  • Mensajes: 171
Re: Microcontrolador PIC con memoria RAM infinita!
« Respuesta #5 en: 17 de Junio de 2015, 14:06:16 »
EL PIC que estoy usando se llama  DSPIC33FJ12GP201  con el compilador C30 v3.12 de la empresa Microchip Technology Inc. The Embedded Control Solutions Company® y el entorno de desarrollo MPLAB® X Integrated Development Environment (IDE) v3.00

Ya entiendo ke es lo que estaba pasando:

cuando escribia lo siguiente:

Código: [Seleccionar]
int main(int argc, char** argv)
{
    unsigned int i = 0;
    unsigned int lecturas[50] = {0};
   
    OSCInit();
    ADCOpen();
   
    while(1)
    {
        lecturas[i] = ADCRead();
        i++;
        if(i > 50)
        {
            i = 0;
        }
    }
   
}

El compilador lo que hacia era guardarme los datos de la variable 'lectura' en la memoria de programa, no en la RAM.  Haciendo lo siguiente:

Código: [Seleccionar]
int main(int argc, char** argv)
{
    static unsigned int i = 0;
    static unsigned int lecturas[50] = {0};
   
    OSCInit();
    ADCOpen();
   
    while(1)
    {
        lecturas[i] = ADCRead();
        i++;
        if(i > 50)
        {
            i = 0;
        }
    }
   
}
logre hacer q el compilador guardara las variables en la memoria RAM, y ahora si me sale bien la memoria ke estoy usando. si le asigno un valor muy grande, me da error, que es como debe ser.

PERO no todo esta solucionado. al momento de hacer esto:

Código: [Seleccionar]
int main(void)
{
    unsigned int lecturas[3000] = {0};
    unsigned int i = 0;
     
    OSCInit();
    ADCOpen();
   
    while(1)
    {
        lecturas[i] = ADCRead();
        i++;
        if(i > 3000)
        {
            i = 0;
        }
        PORTB = lecturas[i];
    }
   
}

Se supone ke el compilador esta guardando la variable 'lecturas' en la memoria de programa. Todo compila bien sin ningun problema ni adbertencia, pero en la simulacion es un desastre y me manda el error k anteriormente coloque. Parece ser un bug del compilador porke el compilador no me dice ningun error ni nada pero en la simulacion funciona muy mal.
« Última modificación: 17 de Junio de 2015, 14:09:16 por RodrigoAndres »

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2980
Re: Microcontrolador PIC con memoria RAM infinita!
« Respuesta #6 en: 17 de Junio de 2015, 14:16:52 »
Veo que has pasado completamente de lo que te he dicho, pero bueno... tu sabrás, eso ya me ha pasado a mi y si lo estas simulando se lo que le pasa.

por cierto por cambiar de static a volatil no cambias de memoria.
« Última modificación: 17 de Junio de 2015, 14:22:23 por juaperser1 »

Desconectado RodrigoAndres

  • PIC16
  • ***
  • Mensajes: 171
Re: Microcontrolador PIC con memoria RAM infinita!
« Respuesta #7 en: 17 de Junio de 2015, 14:28:45 »
Veo que has pasado completamente de lo que te he dicho, pero bueno... tu sabrás, eso ya me ha pasado a mi y si lo estas simulando se lo que le pasa.

por cierto por cambiar de static a volatil no cambias de memoria.

claro que no. he leido todo pero creo que estas equivocado. El error sucede tanto en el simulador de MPLAB, como en el simulador ISIS.  en un rincon logre encontrar algo que decia que si se declara una variable volatil dentro de una funcion (en este caso 'main') estoy forsando al compilador C30 a guardar esa variable dentro de la memoria de programa.  esto no sucede si declaro esa variable de forma global. de la misma manera, si la declaro como static, eso no sucede y todo funciona como quiero.

Desconectado juaperser1

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 2980
Re: Microcontrolador PIC con memoria RAM infinita!
« Respuesta #8 en: 17 de Junio de 2015, 14:35:18 »
Si crees que estoy equivocado dimelo pero ¿nisiquiera responderme a la pregunta que te he hecho de si lo estabas simulando?

si crees que me equivoco desmientemelo, deja las simulaciones y cargalo en el micro y mira la memoria RAM cuando veas lo que ocupa, te darás cuenta de que no estoy equivocado.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Microcontrolador PIC con memoria RAM infinita!
« Respuesta #9 en: 17 de Junio de 2015, 18:30:55 »
Creo que el problema es tu falta de entendimiento del scope de las variables y la ubicacion de las mismas.
Por otra parte C30 desaparecio hace mucho y ahora es XC16, aunque muchas cosas siguen con "C30"

Compilador usado:
MPLAB X IDE v2.26 y XC16 v1.24

Voy a intentar hacer unos ejemplos:

Programa, cree un template y use tu codigo:

Código: C
  1. uint16_t lecturas[120];
  2.  
  3. /******************************************************************************/
  4. /* Main Program                                                               */
  5. /******************************************************************************/
  6.  
  7. int16_t main(void)
  8. {
  9.  
  10.     ConfigureOscillator();              //Vino por default en el codigo para el dsPIC33
  11.     InitApp();
  12.  
  13.     while(1)
  14.     {
  15.     uint8_t i = 0;
  16. //    static uint8_t probando[120];
  17.    
  18.     while(1)
  19.     {
  20.         lecturas[i] = i;
  21. //        probando[i] = i;
  22.         if(++i == 120)
  23.         {
  24.             i = 0;
  25.         }
  26.     }
  27.     }
  28. }



C scope : block , file , program (scope real y no simplificando en "local" y "global")

block = funciones, variable dinamica, por lo tanto es una "auto" variable de automatic allocation (ubicacion automatica)
file  = es lo que se conoce como static. y es una variable non-auto, es decir que tiene un guardado de duracion permanente
program = extern ( justamente en todo el programa el scope ) igual que el anterior

Lo que es permanente ( non-auto ) se guarda en el espacio de datos
Lo que esta al alcance del scope del la funcion unicamente (auto) es ubicada dinamicamente, es decir en el stack

En fin mi codigo esta con 1 sola variable con scope program ("global")
Esto se guardo en la seccion de datos .nbss ( es decir seccion de datos NO inicializados parte baja (8KB o menos = near))

Código: [Seleccionar]
Program Memory  [Origin = 0x200, Length = 0x1e00]

section                    address   length (PC units)   length (bytes) (dec)
-------                    -------   -----------------   --------------------
.text                        0x200                0xce           0x135  (309)
.text                        0x2ce                0x2e            0x45  (69)
.dinit                       0x2fc                 0x8             0xc  (12)
.text                        0x304                 0xc            0x12  (18)

                     Total program memory used (bytes):          0x198  (408) 3%


Data Memory  [Origin = 0x800, Length = 0x400]

section                    address      alignment gaps    total length  (dec)
-------                    -------      --------------    -------------------
.nbss                        0x800                   0            0xf0  (240)

                        Total data memory used (bytes):           0xf0  (240) 23%


Dynamic Memory Usage

region                     address                      maximum length  (dec)
------                     -------                      ---------------------
heap                             0                                   0  (0)
stack                        0x8f0                               0x310  (784)

                        Maximum dynamic memory (bytes):          0x310  (784)



Realizando unas pequeñas modificaciones.

Descomento el
Código: C
  1. static uint8_t probando[120];
y
Código: C
  1. probando[i] = i;

Para ver que ocurre:

Código: [Seleccionar]
Program Memory  [Origin = 0x200, Length = 0x1e00]

section                    address   length (PC units)   length (bytes) (dec)
-------                    -------   -----------------   --------------------
.text                        0x200                0xce           0x135  (309)
.text                        0x2ce                0x38            0x54  (84)
.dinit                       0x306                 0x8             0xc  (12)
.text                        0x30e                 0xc            0x12  (18)

                     Total program memory used (bytes):          0x1a7  (423) 3%


Data Memory  [Origin = 0x800, Length = 0x400]

section                    address      alignment gaps    total length  (dec)
-------                    -------      --------------    -------------------
.nbss                        0x800                   0           0x168  (360)

                        Total data memory used (bytes):          0x168  (360) 35%


Dynamic Memory Usage

region                     address                      maximum length  (dec)
------                     -------                      ---------------------
heap                             0                                   0  (0)
stack                        0x968                               0x298  (664)

                        Maximum dynamic memory (bytes):          0x298  (664)

Efectivamente puso los datos en el espacio de datos,, ahora tengo 360 bytes ( 120 de 16 bytes y 120 de 8 bytes )
Esta ves voy a probar que ocurre cuando no esta puesto como static.

Código: [Seleccionar]
section                    address   length (PC units)   length (bytes) (dec)
-------                    -------   -----------------   --------------------
.text                        0x200                0xce           0x135  (309)
.text                        0x2ce                0x38            0x54  (84)
.dinit                       0x306                 0x8             0xc  (12)
.text                        0x30e                 0xc            0x12  (18)

                     Total program memory used (bytes):          0x1a7  (423) 3%


Data Memory  [Origin = 0x800, Length = 0x400]

section                    address      alignment gaps    total length  (dec)
-------                    -------      --------------    -------------------
.nbss                        0x800                   0            0xf0  (240)

                        Total data memory used (bytes):           0xf0  (240) 23%


Dynamic Memory Usage

region                     address                      maximum length  (dec)
------                     -------                      ---------------------
heap                             0                                   0  (0)
stack                        0x8f0                               0x310  (784)

                        Maximum dynamic memory (bytes):          0x310  (784)


Exactamente lo previsto.. espacio de datos con 240 bytes, es decir solo los 120 de 16bytes, mientras que el otro a donde fue ? eso se va a encargar de manejarlo C con su stack, el stack se asigna como la maxima cantidad de memoria no utilizada, si ocurre un overflow de stack se produce una excepcion. Es exactamente el error que esta dandote el proteus


Creo que eso es ya mas asunto tuyo que del compilador, como es dinamico puede o no ser necesario mantener todos esos datos, por ejemplo si llamas una funcion y salis, ya no te importan sus variables y las desechas. ganando espacio de stack, en el main, asi de la misma forma lo toma el compilador.


Por curiosidad, dije que .bss es el espacio de datos NO inicializado, entonces que ocurre si lo inicializo con un valor, no puedo poner 0 por que es lo mismo que NO inicializarlo.

Cambio:

Código: C
  1. uint16_t lecturas[120];
por
Código: C
  1. uint16_t lecturas[120] = {1,2,3,4,5};



Finalmente:

Código: [Seleccionar]
Program Memory  [Origin = 0x200, Length = 0x1e00]

section                    address   length (PC units)   length (bytes) (dec)
-------                    -------   -----------------   --------------------
.text                        0x200                0xce           0x135  (309)
.dinit                       0x2ce                0xa8            0xfc  (252)
.text                        0x376                0x44            0x66  (102)

                     Total program memory used (bytes):          0x297  (663) 5%

Data Memory  [Origin = 0x800, Length = 0x400]

section                    address      alignment gaps    total length  (dec)
-------                    -------      --------------    -------------------
.ndata                       0x800                   0            0xf0  (240)

                        Total data memory used (bytes):           0xf0  (240) 23%

Ahora nuestro espacio es .data, seccion near por ser de menos de 8k.

No veo NINGUN problema.Por otra parte veamos si le pongo un const lo cual lo ubicaria dentro de la memoria de programa.Mas que claro comento la linea que le asigna un valor a ese punto

Código: [Seleccionar]
section                    address   length (PC units)   length (bytes) (dec)
-------                    -------   -----------------   --------------------
.text                        0x200                0xce           0x135  (309)
.const                       0x2ce                0xf0           0x168  (360)
.text                        0x3be                0x34            0x4e  (78)
.dinit                       0x3f2                 0x2             0x3  (3)

                     Total program memory used (bytes):          0x2ee  (750) 6%


Data Memory  [Origin = 0x800, Length = 0x400]

section                    address      alignment gaps    total length  (dec)
-------                    -------      --------------    -------------------

                        Total data memory used (bytes):              0  (0)


Dynamic Memory Usage

region                     address                      maximum length  (dec)
------                     -------                      ---------------------
heap                             0                                   0  (0)
stack                        0x800                               0x400  (1024)

                        Maximum dynamic memory (bytes):          0x400  (1024)


Ahi aparece como const dentro de la memoria de programa, la memoria de datos esta en 0, y el stack es de 1024! es decir TODA la memoria de datos.
Hay muchas mas opciones, como elegir una seccion del espacio de programa para que pueda ser visto como una extension del espacio de datos, etc.
Eso lo vas a ver en el manual de XC16

Sobre near/far es por un tema del micro... se crea un codigo mas eficiente si las variables estan dentro del espacio near. Es lo que dice el manual.

Creo que esto soluciona todas las dudas que tienen.
El stack no aparece como "RAM" ocupada por que si viene por defecto usar todo el espacio de datos que no se usa como stack, seria siempre 100%.

Distinto es cuando usan un RTOS y definen un espacio de stack, imagino que el RTOS crea un stack para cada tarea.
Burdamente como crear una array de ese tamaño para cada tarea. Entonces ahi ya no contaria como stack.
Creo que es por la filosofia de Microchip al no estar declarado en ningun lado el tamaño de stack sino tomar todo lo NO utilizado.
« Última modificación: 17 de Junio de 2015, 18:57:16 por KILLERJC »

Desconectado RodrigoAndres

  • PIC16
  • ***
  • Mensajes: 171
Re: Microcontrolador PIC con memoria RAM infinita!
« Respuesta #10 en: 17 de Junio de 2015, 19:21:05 »
bueno ya veo que es normal. lo que no entiendo es eso de "stack", es lo mismo stack del PIC que pila de programa??

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Microcontrolador PIC con memoria RAM infinita!
« Respuesta #11 en: 17 de Junio de 2015, 20:23:05 »
no lo que vos conoces como stack es lo que llama "Hardware stack" o un stack que usaban los PICs 16 para guardar la direccion de retorno. pero unicamente para eso

Aqui el "stack" se usa para muchas mas cosas, y directamente se usa una parte de la RAM para eso.

Por ejemplo el micro tiene unos registros de W0 a W15, cada uno tiene normalmente se hace una convencion y por ejemplo W3 a W5 se usa para pasar los argumentos a funciones

Si llamas a otra funcion con mas argumentos, esos argumentos se pasan a traves de ese stack, tambien tiene el comiezo del stack anterior. lo que le llaman frame pointer. Tambien se pasan la direccion de retorno etc..
En fin.. por el stack se pasan muchos datos. En los PIC16 con C tambien se crea un "stack" para esos motivos.




 

anything