Consejos en cuanto a optimización de flash utilizada (ATtiny85)

Buenas!
Antes que nada, y como una especie de presentación, sólo voy a decir que programo desde hace unos cuantos años, y que me metí en el mundo de la electrónica hace un par. Desde hace un buen tiempo tengo ganas de registrarme en el foro, pero como la mayoría de las dudas las pude resolver mezclando algo de experiencia previa en otros lenguajes y san google, todo quedó en el olvido :stuck_out_tongue:

La cuestión es; desde hace un tiempo estoy haciendo algo similar a un Timer para la cocina de mi casa.
Estoy usando un display LCD I2C de 20x4, un RTC DS3231, un DS18B20 (temperatura), y un par de cosas más, (buzzer activo, array de resistencias para poder manejar unos cuantos botones a la vez con una sola entrada analógica).

Cabe aclarar que todo lo programado funciona bien, y hoy terminé de agregarle las últimas funciones que tenía en mente (sí, luego de reescribir, por falta de espacio, todo el código un par de veces …).
El problema, es que estoy intentando agregarle algo más (quiero agregarle una batería de respaldo y monitorearla con el ATtiny, y si los astros se alinearan, alarmas activadas por el RTC).

Para lo primero, calculo que voy a necesitar alrededor de 300 bytes de espacio libres.

Y tengo 32.

Estuve durante la última semana leyendo un poco en torno a optimización de código (espacio vs. velocidad, etc). Hay un par de documentos de Atmel muy buenos (si los encuentro de nuevo los posteo). Logré aprovechar varias de esas técnicas (y gracias a parte de ellas llegué hasta acá), pero me falta un poquito.

Quería saber si alguien le podría pegar una ojeada al código y comentarme qué se podría hacer (lo más probable es que no lo puedan compilar, tengo que actualizar las bibliotecas dentro de libraries/); todo el código está en github: https://github.com/fermino/ATtiny-TempAlarm

Gracias de antemano! Espero poder hacer del foro un lugar frecuente jajaja

=================================

Edito, ya actualicé las bibliotecas. Como nota adicional, esto usando Stino (plugin de sublime text) y Arduino 1.6.13 para compilar todo.

=================================

Edito 2, hice un merge de i2c-lcd a master, así que todo está en la rama principal a partir de ahora.

Hola ferminolaiz, bienvenido.

Has puesto el reto que mas gusta por aquí. optimizar. Hay muy buenos colegas en esos menesteres y si se puede mejorar algo ten por seguro que lo mejoraran.

Saludos.

Edito: Dices que usas el IDE 1.6.13, ¿ como subes el código al ATtiny ? Si lleva algun bootloader, puedes encontrarte hasta unos 2k de espacio extra simplemente usando el SPI para el upload.

¿ Cuanta memoria Flash ocupa tu código actual ?

Aunque me figuro que todo eso ya lo habrás tenido en cuenta ;)

El código actualmente lo estoy subiendo usando un ATmega328p como programador ISP, así que no puedo rescatar nada por ese lado :(

Y, lo de los 32 bytes libres va en serio :P, actualmente el código está utilizando 8160 (99.6%) / 242 (47.3%) bytes.

Una duda que tengo es si la versión de avr-gcc de la IDE 1.8.x podrá optimizar algo más; durante el transcurso del día tendré que probarlo.

Saludos!

La versión en sí misma puede que no, pero hay flags de la linea de comando que hacen muy buen trabajo optimizando el código. Necesitas listar (verbose activado) el proceso de compilación para analizar que flags usa.

Léete el manual del gcc y en concreto del g++ y verás las opciones.

Aunque esto exige comentarios maaass amplios, he ojeado el proyecto y veo que le has dado un toque profesional (de programacion seria, vamos) y la duda que me asalta es, si quitamos funciones no usadas de las librerias e incluso hacemos la "chapuza" de juntarlo todo en un unico programa, ¿ crees que se obtendrian esos preciosos bytes que buscas ?

Saludos.

En cuanto a la optimización, por lo que vi la ide ya compila con -Os y -flto, no sé si habrá alguna otra opción disponible.

Puede que sí, puede que no. Una de las opciones que se me pasaron por la mente, siendo que antes los modulos eran nada más que .ino's y funciones (no poo), fue, para evitar tener que usar variables globales y demás (que según el documento ese de Atmel el addressing de variables globales utiliza casi el doble de instrucciones en relación con las locales), buscar cómo podía consolidar todo en un archivo. No encontré nada que me permitiera, por decirlo de alguna manera, hacer un inline de las diferentes funciones y que ellas pudieran acceder a las variables del scope de setup().

Lo único que se me ocurre que se puede llegar a ahorrar si se junta todo serían los punteros a LCD y Switches, y no sé si algo más.

BTW, ¿a qué te refieres con funciones no usadas?

Saludos!

Hay que hacer muchas pruebas para llegar a afinar tanto, porque el compilador fiel a su funcion optimiza, pero no siempre como esperamos.

Cuando hacemos un #include de una libreria (básicamente clase) el compilador añade todas las funciones declaradas en la clase al código, con lo cual engorda en funcion de la libreria usada y no en base a las funciones utilizadas.

Mi comentario va sobre hackear las librerias que usas customizandolas para tu aplicacion en concreto. Algo ganaras.

Respecto a los flags de optimizacion hay muchos mas y los puedes ver en la descripcion del gcc Ahora te busco el link y te lo posteo.

Uhm, tenía entendido que -Os eliminaba las funciones no utilizadas, voy a probar eliminando alguna de las bibliotecas que uso para el LCD y OneWire a ver qué tal. Casi todo lo demás lo estoy haciendo a mano (leer RTC, sensores, etc).

Tal vez haciendo una lib minimalista para el LCD logre ganar algo.

Cualquier cosa te comento, mil gracias!

PD: El hecho es que ya estoy medianamente realizado con el proyecto, logré añadirle todas las funciones principales; así que si no logro ganar algo de espacio con esto, no creo llevarlo mucho más lejos; haré el PCB y listo :P

Acá está el documento de Atmel que había mencionado: http://www.atmel.com/Images/doc8453.pdf

Saludos!

Hola, ferminolaiz.
No he podido compilar tu proyecto, ya que no tengo las librerías concretas que has usado ni tengo implementado el dispositivo ATtiny85. He intentado seguir un poco algunos de tus archivos y, sinceramente, no sé si va a ser posible reducir esos 300 bytes, pero parece difícil, pues en el código actual no he observado ningún “derroche” evidente.
Sobre todo, no sé si merecerá la pena eltrabajo que te estás dando (por ejemplo, rehacer la librería LCD), para obtener un incierto éxito; en lugar de dar un salto a un uC un poco más potente.
Salvo que se trate (como me temo :)) de una “cuestión de honor”; en cuyo caso podríamos ir repasando poco a poco las distintas partes de tu código a ver si hay algo que rascar, aunque veo muy lejanos los 300 bytes.

Jajajaj, efectivamente, actualmente es más una cuestión de "honor" que otra cosa, ya logré añadirle todas las funciones que quería, y más (a excepción de lo de la batería, que no es una prioridad). Desde la primera versión,que sólo tenía control de temperatura, estuve jugando con los límites (llegué al 90%), y al final pude agregarle bastantes cosas más. Además, aprendí muchísimo en el proceso.

Actualmente tengo los 20x4 caracteres del LCD utilizados, y mañana voy a estar empotrándolo en la pared, así que más o menos la cuestión está cerrada.

Por cierto, todas las bibliotecas que utilicé están en una carpeta del repositorio; y el core para el ATtiny85 que utilicé fue el de HighLowTech.

Saludos!