2011-06-16 18 views
9

Cuando le doy al compilador Keil la opción "--callgraph", , calcula estáticamente el "Uso máximo de pila" exacto para mí.¿Cómo se determina el uso máximo de la pila en el sistema integrado?

Desgraciadamente, hoy me da un mensaje de "Uso máximo de pila = 284 bytes + Desconocido (Funciones sin apilamiento ...)", junto con una lista de "Funciones sin información de pila".

Nigel Jones dice que la repetición es una idea realmente mala en sistemas embebidos ("Computing your stack size" 2009), así que he tenido cuidado de no hacer funciones mutuamente recursivas en este código.

Además, me aseguro de que ninguno de mis manejadores de interrupciones vuelvan a habilitar las interrupciones hasta su instrucción final de retorno de la interrupción, por lo que no tengo que preocuparme por los controladores de interrupción reentrantes.

Sin repetición o controladores de interrupción reentrantes, debería poder determinar estáticamente el uso máximo de la pila. (Y la mayoría de las respuestas a How to determine maximum stack usage? no se aplican). Según tengo entendido, el software que maneja la opción "-callgraph" primero encuentra la profundidad máxima de la pila para cada controlador de interrupción cuando no se interrumpe por una interrupción de prioridad más alta y la profundidad máxima de la pila de la función main() cuando no está interrumpido Luego los suma todos para encontrar la profundidad máxima total (peor de los casos) de la pila. Esto ocurre cuando la tarea de fondo principal() está en su profundidad máxima cuando se interrumpe por la interrupción de prioridad más baja, y esa interrupción está en su profundidad máxima cuando se interrumpe por la siguiente interrupción de prioridad más baja, y así sucesivamente .

Sospecho que el software que maneja --callgraph se confunde sobre las pequeñas funciones de lenguaje ensamblador en la lista "Funciones sin información de la pila". El --callgraph documentation parece implicar que necesito calcular manualmente (o hacer una estimación conservadora) la cantidad de pila que utilizan, son muy cortos, así que debería ser simple, y luego "Usar directivas de marcos en código de lenguaje ensamblador para describe cómo tu código usa la pila ". Uno de ellos es el código de inicio inicial que restablece la pila a cero antes de saltar a main(), por lo que, en efecto, esto consume cero. Otro es el controlador de interrupción "Fault" que se bloquea en un bucle infinito hasta que apago el ciclo - es seguro asumir que esto consume cero stack.

Estoy utilizando el Keil uVision V4.20.03.0 para compilar el código del LM3S1968 ARM Cortex-M3.

Entonces, ¿cómo utilizo las "directivas de trama" para decirle al software que maneja "--callgraph" cuánta pila utilizan estas funciones? ¿O hay algún método mejor para determinar el uso máximo de la pila?

(Ver How to determine maximum stack usage in embedded system with gcc? para casi la misma pregunta dirigida al compilador gcc.)

+2

Quizás pueda codificar equivalentes C falsos (desde el punto de vista del uso de la pila) de sus módulos de ensamblaje. y ejecuta tu análisis con esos. –

+0

Agregué la etiqueta 'keil' ya que esta es una pregunta específica del compilador. Con suerte, eso atraerá más atención especializada al problema. – bta

+0

No estoy seguro de si está preguntando cómo hacer que GCC haga análisis similares o cómo deshacerse del mensaje "+ Desconocido" de Keil (o tal vez esté buscando ambos, en cuyo caso debería haber dos preguntas separadas). Como parece que has determinado que el "+ Desconocido" proviene de funciones que usan la pila cero, parece que esencialmente puedes ignorarlo. –

Respuesta

3

Uso del --info = pila en la opción del vinculador. El archivo de mapa incluirá un uso de pila para todas las funciones con enlace externo.

En un entorno de tarea única, el uso de la pila para main() le dará el requisito total. Si está utilizando un RTOS como RTX, donde cada tarea tiene su propia pila, entonces necesita ver el uso de la pila para todos los puntos de entrada de la tarea y luego agregar algo más (64 bytes en el caso de RTX) para el contexto de la tarea almacenamiento.

Ésta y otras técnicas aplicables a Keil y más en general están descritos here

3

John Regehr de la Universidad de Utah tiene una buena discusión de medir el uso de la pila en sistemas embebidos en http://www.embedded.com/design/prototyping-and-development/4025013/Say-no-to-stack-overflow, aunque tenga en cuenta que el enlace a ftp. embedded.com está desactualizado, y una ocurrencia de "sin interrupciones desactivadas" debería tener la primera o la última palabra negada. En el mundo comercial, Coverity tiene un corrector de desbordamiento de pila configurable, y algunas versiones de CodeWarrior tienen un pragma warn_stack_usage semi-documentado. (No se menciona en mi versión de la documentación del compilador, pero está en el documento "Targeting Palm OS" de MetroWerks.)

+0

Excelente enlace, y espero usar algunas de esas técnicas para algunos trabajos de Freescale HCS08 que estoy haciendo (2KB de RAM, así que cada byte cuenta y no quiere perderlos en la pila no utilizada). Pequeño mundo: en los años 90 creaste la aplicación Kagi Register para Newton, y creé el sitio web order.kagi.com. – tomlogic

Cuestiones relacionadas