Autor Tema: Interrupcion dentro de interrupcion en LPC1769 - CMSIS  (Leído 5190 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado elgarbe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2178
Interrupcion dentro de interrupcion en LPC1769 - CMSIS
« en: 26 de Diciembre de 2013, 07:48:28 »
Hola, tengo una gran duda, hay algún problema en llamar a una funcion que usa interrupciones, dentro de la interrupcion por, por ejemplo, timer?

Me explico, tengo 2 sensores (acelerometro y gyroscopo) en un bus I2C. El driver I2C hace uso de las interrupciones del I2C. Tengo una funcion que me permite escrivir en un registro de un dispositivo I2C. Como yo quiero leer periódicamente los sensores uso el timer 0 que me interrumpe cada 5ms (la lectura de los sensores tarda 1mseg). El tema es que si en la interrupcion pongo el llamado a la funcion de escritura o lectura en I2C la cosa no funciona, el driver I2C me termina devolviendo TIME_OUT.
En cambio si en la interrupcion por timer pongo una bandera y en el main verifico dicha bandera y mando a leer, entonces funciona bien....

Alguna idea?

Saludos!
« Última modificación: 26 de Diciembre de 2013, 13:17:24 por un Moderador »
-
Leonardo Garberoglio

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Interrupcion dentro de interrupcion en LPC1769 - CMSIS
« Respuesta #1 en: 26 de Diciembre de 2013, 13:31:06 »
Hola Leo,

Los Cortex-M3 tienen un sistema de interrupción bastante complejo e interesante (NVIC). Hay 32 niveles de prioridad. A menor valor, mayor prioridad. Por defecto (si mal no recuerdo) durante un POR se le asigna prioridad máxima (valor 0) a todas las interr. La regla básica es que una interrupción sólo interrumpe a otra si su prioridad es mayor. Si es igual o menor, tiene que esperar a que termine de ejecutarse la interr. actual (y posiblemente otras pendientes si las hubiere).

Si entendí bien, tu idea es dentro de la interrupción del Timer, leer datos del I2C. El inconveniente radicaría en que mencionás que la lib del I2C está usando interrupciones para realizar la lectura. Entonces, lo que podés hacer es darle mayor prioridad a las interr. del I2C para que puedan interrumpir a la subrutina de interr del Timer.

Para darle prioridades a las diversas interr. Existe la función NVIC_SetPriority:

static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)

podés encontrar algo de documentación dentro del archivo que la define: core_cm3.h

Ejemplo (sacado de un software que hice hace un año atrás para un LPC1343):

  NVIC_SetPriority(TIMER_32_1_IRQn, 0);      //TIMER32_1 interrupt priority
  NVIC_SetPriority(UART_IRQn, 1);         //UART interrupt priority

En ese ejemplo, se puede ver que estableciendo las prioridades con esos valores el Timer puede interrumpir a la interr. de la UART, pero no al reves.

Los Cortex-M3 guardan (empujan) y restauran (sacan) los registros de trabajo, SP, etc. automáticamente al entrar/salir de una interr. al stack (lo mísmo aplica para una interr. que sucede dentro de otra interr.). Si bien es una ventaja no tener que estar pendiente de eso, tienen una penalización en tiempos de ingreso/regreso de las interrupciones bastantes altas que no puede evitarse, cosa que en otras arquitecturas por tener que hacerlo por software cada uno puede optar si desea guardar los registros claves o bien ganar tiempo y no guardarlos (teniendo en cuenta los peligros que eso implica).

Cualquier duda consultame.

Saludos!

"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado elgarbe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2178
Re: Interrupcion dentro de interrupcion en LPC1769 - CMSIS
« Respuesta #2 en: 26 de Diciembre de 2013, 15:23:03 »
Más claro imposible!

Ya me parecía que algo debía haber, estuve 1 día entero debugeando!!!! primero pense que era problemas de tiempo, que la lectura I2C tomaba más tiempo y se me encolaban varias interrupciones de timer, pero cuando lo saque y lo puse en el main y funcionó mas rapido que el tiempo del timer lo unico que me quedaba pensar era que habría algun problema con interrumpir dentro de una interrupcion. Ahora veo la confirmacion!!! que alivio!

Voy a probar de establecer las prioridades y te cuento.

Ya que estoy te pregunto, para tareas repetitivas (como en este caso, leer periodicamente sensores) es preferible usar RIT o los timer's? el systick lo uso para generar una base de tiempos de 1ms para retardos y demás... que es lo que se acostumbra?

Saludos!!!
-
Leonardo Garberoglio

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Interrupcion dentro de interrupcion en LPC1769 - CMSIS
« Respuesta #3 en: 26 de Diciembre de 2013, 16:59:11 »
Ya me parecía que algo debía haber, estuve 1 día entero debugeando!!!! primero pense que era problemas de tiempo, que la lectura I2C tomaba más tiempo y se me encolaban varias interrupciones de timer, pero cuando lo saque y lo puse en el main y funcionó mas rapido que el tiempo del timer lo unico que me quedaba pensar era que habría algun problema con interrumpir dentro de una interrupcion. Ahora veo la confirmacion!!! que alivio!

Ja ja! Bueno, es que se pone un poco compleja la cosa cuando entrás a trabajar con interrupciones de interrupciones. Hasta donde conozco y razono la arquitectura de los ARM Cortex-M3 no es posible que se encolen varias interrupciones del mísmo origen. Lo que sí puede pasar es que si el código dentro de la interr. lleva más tiempo en ejecutarse de lo que demora en volver a interrumpir ese Timer, el CPU se la pase entrando y saliendo del vector de interr. del Timer, sin poder ejecutar código alguno fuera de las interrupciones.

Ya que estoy te pregunto, para tareas repetitivas (como en este caso, leer periodicamente sensores) es preferible usar RIT o los timer's? el systick lo uso para generar una base de tiempos de 1ms para retardos y demás... que es lo que se acostumbra?

Personalmente usaría el RIT. Especialmente porque el RIT si bien está principalmente pensado para ser utilizado bajo un RTOS, al no tener ninguna otra capacidad más que poder generar interrupciones cada cierto intervalo de tiempo (con un pequeño plus de poder enmascarar bits del comparador para lograr cierta complejidad en los tiempos a interrumpir) no nos perdemos de la posiblidad de tener que sacrificar algún módulo ya que si utilizases un Timer para hacer lo mísmo, automáticamente perderías la posibilidad de usar ese Timer a presente/futuro para generar PWMs, utilizarlo como Counter, etc.

Igualmente la dinámica que ocurre cuando uno comienza a activar varias interrupciones suele ser bastante compleja cuando el CPU comienza a correr ya que comienzan a ocurrir y se suelen producir desfasajes entre las interrupciones. Ni hablar cuando se utilizan prioridades de interrupción. Hay que diseñar todo bien para no tener dolores de cabezas después. Tené en cuenta que las prioridades, técnicamente, pueden cambiarse dinámicamente en tiempo de ejecución, por si te es de utilidad alguna.

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado elgarbe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2178
Re: Interrupcion dentro de interrupcion en LPC1769 - CMSIS
« Respuesta #4 en: 26 de Diciembre de 2013, 17:06:45 »
Perfecto, entiendo. muchas gracias por el dato y consejo.

Bueno, ahora si, la última y no jodo más... nunca hice nada en c/c++ visual, por lo que estaría comenzando desde cero. El tema es que quiero comenzar con algo que me sirva si algún dia quiero hacer algo más. Hoy sería solo un monitor del uart y mostrar algunos datos.... que me aconsejas? vc.net, c#, qt... otro?

Saludos y gracias!
-
Leonardo Garberoglio

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Interrupcion dentro de interrupcion en LPC1769 - CMSIS
« Respuesta #5 en: 26 de Diciembre de 2013, 17:40:10 »
Personalmente, me parece que te va a resultar más sencillo C# o VB.NET.

Como sos entendido en el tema de C, mi principal candidato sería C#. Qt está muy bueno, pero la curva de aprendizaje puede ser más dura.

No me jodés EN ABSOLUTO.

Saludos!
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.