Hola amigos del foro, estoy realizando un programa con el PIC24FJ128GA310, pero se me ha quedado corto, me sale un error que me dice que me he pasado 41832 PC Units, utilice el método de optimizacion de código que ofrece el compilador XC16 en la versión PRO (de prueba de 30 días) y la versión normal, pero las dos en tiempo de ejecución me alteran algunas variables y me dañan mi programa, también pensé en migrar mi micro al PIC24FJ256Ga410 pero en la empresa me dicen que no quieren cambiar de micro.
Que opción me recomendarían ustedes que es buena para solucionar este problema, gracias.
En cuanto a lo que comentas de que en ejecución se alteran variables y se daña el programa, eso no se posible. En tiempo de compilación todas las variables quedan asignadas a una direccion de memoria, sin posibilidad de que sean alteradas en tiempo de ejecución, salvo que toques por programa directamente la flash (por ejemplo con un bootloader). Lo único que puede corromper el programa en tiempo de ejecución es un desbordamiento de la pila, por hacer demasiadas llamadas anidadas con poca RAM, o lo que he comentado de que grabes directamente en la flash.
Hola amigos del foro, estoy realizando un programa con el PIC24FJ128GA310, pero se me ha quedado corto, me sale un error que me dice que me he pasado 41832 PC Units, utilice el método de optimizacion de código que ofrece el compilador XC16 en la versión PRO (de prueba de 30 días) y la versión normal, pero las dos en tiempo de ejecución me alteran algunas variables y me dañan mi programa, también pensé en migrar mi micro al PIC24FJ256Ga410 pero en la empresa me dicen que no quieren cambiar de micro.
Que opción me recomendarían ustedes que es buena para solucionar este problema, gracias.
¿Con cuales opciones de compilación estás trabajando?.
Desconozco el compilador xc16, pero si fuera un derivado de gcc podrías probar con -O2 (optimize), -O3, o si es exclusivamente tamaño -Os.
También podés hacer que al compilar se genere un segmento intermedio para cada función, para eso había una opción -ffunction-sections, y luego hay que agregar una opción al linker -Wl,--gc-sections
Esto lo que hace es eliminar las funciones que no están siendo llamadas, útil si estás incluyendo alguna librería que no la utilices del todo.
Si no es un derivado del gcc, bueno, a leer el manual del compilador y ver que opciones pueden ayudarte a reducir tamaño de memoria del programa.
También podés hacer que al compilar se genere un segmento intermedio para cada función, para eso había una opción -ffunction-sections, y luego hay que agregar una opción al linker -Wl,--gc-sections
Esto lo que hace es eliminar las funciones que no están siendo llamadas, útil si estás incluyendo alguna librería que no la utilices del todo.
Si no es un derivado del gcc, bueno, a leer el manual del compilador y ver que opciones pueden ayudarte a reducir tamaño de memoria del programa.
Esta opción no se como seria pero voy a intentar, me parece muy buena opción, si me puedes dar mas información acerca de esto, me seria de mucha ayuda, gracias.
A ver que pasa...
...
En cuanto a lo que comentas de que en ejecución se alteran variables y se daña el programa, eso no se posible. En tiempo de compilación todas las variables quedan asignadas a una direccion de memoria, sin posibilidad de que sean alteradas en tiempo de ejecución, salvo que toques por programa directamente la flash (por ejemplo con un bootloader). Lo único que puede corromper el programa en tiempo de ejecución es un desbordamiento de la pila, por hacer demasiadas llamadas anidadas con poca RAM, o lo que he comentado de que grabes directamente en la flash.
Puede que tengas razón pero y por que pasa que las variables tomen valores errados en cualquier momentos si compilo el código con la optimizacion, pero si comento el código en una parte para que el tamaño disminuya y poder compilarlo sin ninguna optimizacion no pasa, ademas que ya no es la primera vez que nos ocurre este problema con las optimizaciones.
¿ Como sabes que las variables toman valores erroneos ?, si lo estás haciendo con un Debug y el código está optimizado, no te vale, en ese caso incluso puedes tener variables "Out of Scope", como si no existiesen, todo eso es debido a la optimización (pero solo a efectos de un Debug, internamente son correctas).
Con el código optimizado, solo se me ocurre que saques el contenido de esas variables por un LCD o las envíes por RS232, ya verás como son correctas. En cualquier caso, si con el código sin optimizar, las variables son correctas, con toda seguridad seguirán siendo correctas una vez optimizado, y la única explicación para que se corrompa el programa en tiempo de ejecución es por el desbordamiento de la pila, algo bastante probable si vas tan apurado de RAM.
¿Tenés una captura de las opciones de xc16-ld para ver si hay algo similar a lo que yo tengo como --gc-sections?
¿ Como sabes que las variables toman valores erroneos ?, si lo estás haciendo con un Debug y el código está optimizado, no te vale, en ese caso incluso puedes tener variables "Out of Scope", como si no existiesen, todo eso es debido a la optimización (pero solo a efectos de un Debug, internamente son correctas).
Con el código optimizado, solo se me ocurre que saques el contenido de esas variables por un LCD o las envíes por RS232, ya verás como son correctas. En cualquier caso, si con el código sin optimizar, las variables son correctas, con toda seguridad seguirán siendo correctas una vez optimizado, y la única explicación para que se corrompa el programa en tiempo de ejecución es por el desbordamiento de la pila, algo bastante probable si vas tan apurado de RAM.
Los valores se imprimen en tiempo de ejecución sin debug por RS232, la RAM esta en 88%.
...¿Tenés una captura de las opciones de xc16-ld para ver si hay algo similar a lo que yo tengo como --gc-sections?
Me imagino que seria esta opción:
- Tienes que ingresar para ver archivos adjuntos -
Entonces hazle un Debug, eso no falla nunca, con el código sin optimizar. Lo que no es posible es que las variables se corrompan, algo en el programa las está modificando
Mmmmnop... ahí en el desplegable de "Option categories" está seleccionado "libraries", que no tiene relación con lo que comento; la opción figura en la tabla de la página 103 del manual del compilador:
http://ww1.microchip.com/downloads/en/DeviceDoc/50002071C.pdf
Pero tal vez en el desplegable donde ahora dice libraries hay otra categoría que tiene la opción equivalente a --gc-sections , aunque probablemente ya esté habilitada.
Lo que dice colotron es ahi en xc16-ld
en Additional options pones el --gc-sections
Cuando compiles te deberia aparecer el --gx-sections en la linea de comandos cuando invoca al linker.
PD: Voy a suponer que se que es CN, no se me ocurre ninguna abreviatura asi..
Creo que quiere decir change notification...
CN => Change Notification, es una interrupción del microcontrolador que avisa cuando un pin cambio de estado.
Ahora mismo esto haciendo cambios en el código, se me ha generado la duda si es que yo soy el que tengo algo mal programado, y el código se esta dañando por mi culpa, voy a esperar estas pruebas hasta el día de mañana para ver que conclusiones saco.
Exit from the Deep Sleep modes can be triggered from any of the following events:
• POR event
• MCLR event
• RTCC alarm (If the RTCC is present)
• External Interrupt 0
• Deep Sleep Watchdog Timer (DSWDT) time-out
El problema radica en una variable que esta en un CN, el micro esta dormido en DeepSleep, se despierta por un CN y aumenta una variable, esa variable en algún momento pasa de 0 a un valor de 4.256.785.145, dentro del CN se pregunta cual es el pin que lo despertó y si es el de la variable se aumenta, osea en algún momento la interrupción del CN entra 4.256.785.145, pero el equipo esta solo y quieto aislado, como puede ocurrir esto, cree tres variables solamente para verificar este problema, estas variables no se incrementan en ningún otro lado.
Exiting Deep Sleep generally does not retain the state of the device and is equivalent to a Power-on Reset (POR) of the device. Exceptions to this include the RTCC (if present), which remains operational through the wake-up, the DSGPRx registers and DSWDT
As exiting Deep Sleep mode causes a POR, most Special Function Registers reset to their default POR values. In addition, because VCORE power is not supplied in Deep Sleep mode, information in data RAM may be lost when exiting this mode
Lo segundo es que las interrupciones estaban declaradas asi "__attribute__((interrupt, no_auto_psv))" y se lo cambie por "__attribute__((interrupt, auto_psv))", me comento un compañero que vio esto en alguna parte y decía que así debería ir, la verdad no se por que, pero bueno, se lo cambiamos, si alguien sabe el por que, seria bueno que compartiera la información.
Lo primero es no optimizar todo el código, solo optimizamos algunos métodos, esto se realiza colocándole "__attribute__((optimize("-O1")))" al inicio del nombre del método.