¿Cómo puedo reducir el tamaño de un cargador de arranque AVR ethernet?

4

Estoy escribiendo un gestor de arranque compatible con Ethernet para un AVR ATmega328 MCU. Actualmente estoy ejecutando el límite de tamaño de 4k y necesito algunos consejos de diseño.

Requisitos del cargador de arranque:

  • Necesita poder actualizar la aplicación a través de un simple protocolo de mensajería basado en UDP (similar a TFTP).
  • Como el dispositivo funciona en una variedad de LAN, debería ser compatible con DHCP.

Con mi código actual, necesito alrededor de 4k para el controlador de Ethernet, DHCP, ARP y UDP. Plus 1.5k para la mensajería real y la programación de la aplicación.

Las optimizaciones del compilador están activadas.

Mis consideraciones actuales para continuar son:

  1. El código no está particularmente optimizado, así que supongo que podría guardar algunos bytes siguiendo AVR035 . Sin embargo, dudo que pueda guardar suficiente tamaño de código en esta ruta.
  2. Simplemente podría ampliar el área del gestor de arranque reservando 2k desde el área de la memoria superior de la aplicación para el gestor de arranque. Tengo que tener mucho cuidado de no sobrescribir esa área al programar. Y, terminaría con un gestor de arranque grande y complejo que probablemente tenga errores, que no puedo actualizar en el campo.
  3. Podría mover algunas funciones del gestor de arranque a la aplicación. DHCP podría ser un buen candidato: la aplicación obtiene una dirección IP a través de DHCP y la almacena en EEPROM. El gestor de arranque puede simplemente usar la dirección IP almacenada y no necesita hacer el DHCP por sí mismo. Sin embargo, esto podría ser peligroso si la aplicación falla, por ejemplo. por error de software o corrupción aleatoria.

¿Qué ruta sugerirías? ¿Hay otras ideas que debería considerar?

    
pregunta henning77

4 respuestas

3

Logré reducir el tamaño del gestor de arranque a alrededor de 3k. Esto es lo que hice, tal vez ayude a alguien con una tarea similar:

Quité el soporte DHCP y ARP del cargador de arranque. Supongo que siempre puedo llegar al dispositivo a través de la transmisión UDP, por lo que no lo necesito para obtener una dirección IP cuando ejecuto el cargador de arranque.

También hice muchos ajustes de código, lo que ayudó a reducir el tamaño un poco más. Sin embargo, la eliminación de DHCP / ARP fue la mayor parte.

    
respondido por el henning77
1

Un enfoque que a veces puede ser útil (incluso no para el autor de la pregunta original, para otras personas que necesitan cargadores de arranque pequeños) es tener un cargador de arranque de dos partes. Una parte estaría en la memoria "permanente" y, básicamente, tendría suficiente inteligencia para enviar un paquete de difusión, escuchar una respuesta y lanzar una respuesta recibida de aspecto adecuado en la memoria y ejecutarla. De lo contrario, realizaría una suma de comprobación en la segunda parte, ejecutándola si parece válida. La segunda parte estaría en el almacenamiento grabable y podría contener la lógica para ARP y otras cosas similares. Esa parte, a su vez, podría utilizarse para realizar actualizaciones de la aplicación.

Tenga en cuenta que es posible que la segunda parte no se ajuste completamente dentro de un paquete de Ethernet de 1.5K, pero no debería haber dificultad para ajustar la lógica suficiente dentro de un paquete de Ethernet de 1.5K para cargar algunos paquetes más de código de cargador de arranque (especialmente desde que el hardware ya estará configurado para ese propósito). El Apple II utiliza este tipo de enfoque para cargar desde un disquete. Una PROM de 256 bytes configura una tabla de 128 bytes para decodificar datos GCR de 7 bits en nybbles de 4 bits, hace avanzar el mecanismo del cabezal varias veces, busca un encabezado de sector cero y luego lee 256 bytes de datos a la dirección de $ 0800. El código allí es lo suficientemente grande como para leer los siguientes 15 sectores de la misma pista (ya que la tabla que requiere ya se ha producido), y el código dentro de esos 15 sectores puede terminar de cargar el sistema operativo.

Configurar un cargador de arranque para que funcione de esta manera puede ser algo menos conveniente que tener un cargador de "cargar todo en un solo paso", pero ofrece la ventaja de permitir que la parte inmutable del cargador de arranque sea muy pequeña.

    
respondido por el supercat
1

Hice un gestor de arranque para el atmega328 que se actualiza a través de Ethernet utilizando TFTP. Tengo DHCP en el espacio de la aplicación y los resultados entran en eeprom. El gestor de arranque lee el eeprom, por lo que el gestor de arranque tiene efectivamente DHCP siempre que la aplicación se ejecute al menos una vez en la red.

    
respondido por el brian
0

Sin ver su código, o al menos el diseño de algunos de ellos, es difícil decir qué puede cambiar y omitir / reciclar.

¿Has probado con diferentes optimizaciones? En un programa de 4k, creo que he visto variaciones de casi 1k simplemente cambiando la optimización utilizada, (esto fue hace un tiempo, puede que no haya sido tan dramático). Aunque dudo que eso te ofrezca la reducción de ~ 33% que harías necesitar. Intentaría escribir o encontrar algunos ejemplos de ASM que puedan ser más pequeños de lo que haría el compilador y usarlos en lugar de algunos de sus códigos, luego compilarlos y ver cuánta diferencia hace.

También puede compilar, recorrer el asm, extraer las secciones que le gusta intercambiar en su código, luego cambiar la optimización, compilar y repetir. ¡Pero esto sería tedioso!

Su mejor apuesta es probablemente extender el área del cargador de arranque y asegurarse de que el cargador de arranque no sobrescriba esto cuando esté siendo programado.

    
respondido por el Garrett Fogerlie

Lea otras preguntas en las etiquetas