¿La forma más fácil de deshacerse de __clz_tab en el código compilado de winavr?

3

He portado un programa del entorno arduino a un build de makefile usando winavr, que, a su vez, se basa en avr-gcc (al igual que arduino).

Sin embargo, mi programa comenzó a fallar, y después de una investigación descubrí que me estaba quedando sin memoria de datos debido a un aumento de 256 bytes en el montón, a pesar de que no había cambiado el programa en absoluto.

Al mirar el archivo del mapa, veo que se incluye una nueva tabla, __clz_tab , que es de 256 bytes, y reside en la RAM.

¿Cómo me deshago de esta tabla y reclamo mi RAM?

    
pregunta Adam Davis

1 respuesta

6

libc, incluido con gcc y avr-gcc, tiene una función que se usa para contar los ceros iniciales al convertir de un int o uint en un float o un double . Esta función usa una tabla de 256 bytes para acelerar la operación de conteo de cero, lo cual está bien para computadoras con mucha memoria, pero no tan buena para los microcontroladores donde 256 bytes es 1/4 o 1/8 del ram total disponible.

avr-gcc incluye una biblioteca, libm.o que tiene definiciones alternativas para algunas funciones, incluida la función que requiere __clz_tab . Esta definición requiere menos memoria, por lo que debe indicar al vinculador que vincule contra libm.

Esto se hace agregando -lm a la línea de comando del vinculador.

Sin embargo, la posición de este parámetro de comando es importante: solo resolverá los enlaces a los símbolos antes de este parámetro, por lo que para aprovechar al máximo el parámetro -lm debería estar lo más cerca posible del final de la línea de comando.

En mi Makefile se ve así:

CXX=avr-gcc
CFLAGS=$(MCU) $(CPU_SPEED) -g  -Os -w -Wl,--gc-sections -ffunction-sections -fdata-sections
LFLAGS= -Wl,--section-start=.text=0x0000,-Map=program.map
INCLUDE=-I ../include/arduino/
LIBS=-L ../lib -larduino -lm

default: program.hex 

program.hex: program.elf
    avr-objcopy -O ihex $< $@

program.elf: bcu_usb.cpp main.cpp programmer.cpp
    $(CXX) $(CFLAGS) $(LFLAGS) $(INCLUDE) $^ -o $@ $(LIBS)

Tenga en cuenta que el último elemento en la línea de comando del compilador es $(LIBS) y el último elemento en LIBS es el -lm que garantiza que compiler da prioridad a las definiciones en libm cuando hay varias definiciones disponibles.

Las versiones recientes de avr-gcc han resuelto este problema por lo que esto no ocurre incluso sin el -lm , sin embargo, el IDE arduino todavía está instalando y utilizando las versiones anteriores de avr-gcc, y winavr no se ha actualizado ya que este error fue corregido.

Puede leer el informe de errores aquí:

enlace

    
respondido por el Adam Davis

Lea otras preguntas en las etiquetas