Libertonia
Portada · Todo · Software Libre · Desarrolladores · Comunidad · Internet · Tecnología · Meta · Diarios
Ver: Modo: Orden:
gestion de interrupciones | 9 comentarios (9 temáticos, editoriales, 0 ocultos)
La solución del manual (none / 0) (#1)
por jorginius ("jorginius" en Google Mail) a las Sun May 8th, 2005 at 10:50:10 PM CET
(Información Usuario) http://www.rodriguezmoreno.com

Las interrupciones se ejecutan en un contexto especial desde donde no se suele poder realizar ciertas operaciones, como un delay(), usar semaforos...

¿Por?. Evidentemente no tienes las primitivas POSIX dentro de un manejador de interrupciones, pero sí que tienes primitivas de bloqueo y de exclusión. Ya me dirás si no cómo accedes al hardware de manera controlada. Esto es así en QNX, Linux o el SO que más rabia te dé.

Precisamente, la manera estándar de resolver lo que propones es una cola de interrupciones y un spinlock/cola de espera.

La parte divertida es que, al haber dos spinlocks (el de acceso al hardware y el de la cola donde vas metiendo/leyendo las interrupciones) tienes que evitar el deadlock, pero vamos... Es de libro :-)



Ahm, no me había fijado (none / 0) (#2)
por jorginius ("jorginius" en Google Mail) a las Sun May 8th, 2005 at 11:02:58 PM CET
(Información Usuario) http://www.rodriguezmoreno.com

Que en tu ejemplo el hardware se lee desde el bottom_half. Eso chirría un poco. El hardware debería leerse desde el manejador, con las interrupciones inhabilitadas, ¿no?.

El manejador sería algo así cómo:
spin_lock(&hwlock);
leo_registro_y_lo_guardo();
spin_unlock(&hwlock);
wake_up(&hwwait); /* hale, a trabajar */


[ Padre ]


Detalle de implementacion (none / 0) (#6)
por ridiculum a las Tue May 10th, 2005 at 12:55:46 AM CET
(Información Usuario)

Si, esta hecho asi por un motivo simple: delay(). El hardware esta mapeado en memoria y claro, entre lectura y lectura debe transcurrir un tiempo impuesto por el hardware. Eso lo hago con un delay() que normalmente estan prohibidos en los manejadore de interrupcion. Es solo por eso, me facilitaba la vida. El hardware, cuando lo leo desde el bottom half esta con las interrupciones deshabilitadas, al menos las que conciernen al dispositivo.

Supongo que si se mueve el acceso al hardware al manejador, habria que leer todos los registros susceptibles de ser modificiados por una proxima irq y guardarlos en la cola, no?
Supongo que una vez que accedo al hardware, debo hacer un enable_irq()?.

Y ya que estamos, sigamos para bingo. Supongamos que he sido capaz de escribir la cola y todo (y que aparentemente funciona), ¿como se sabe a que proceso hay que darle los datos que, por ejemplo, se han recibido del dispositivo? ¿habra que guardar en algun sitio que procesos estan bloqueado en una IRQ y cual de ellas, no? ¿o se hace por dispositivo por el tema de lineas compartidas?

PD Que conste que ahora mismo el chiringuito esta funcionando y va bien, pero se que siento curiosidad por como se resuelve este problema de forma correcta.

[ Padre ]


 
A veces creo que la vida es mas dificil (none / 0) (#5)
por ridiculum a las Tue May 10th, 2005 at 12:44:36 AM CET
(Información Usuario)

Puse semaforos por que estaba pensando en mi entorno particular. Solo tengo semaforos (y gracias). No tengo spinlocks ni ninguna otra primitiva de sincronizacion (bueno, supongo que el rendevouz de ada no cuenta). Evidentemente el API no es POSIX.

Y tu dirás, por que no te haces tu propio spinlock?. Bueno supongo que podria, aunque no me saldria tan decente como los de que hacen la gente que sabe, con una espera activa se podria atajar.

En la cola de interrupciones (supongo que una por linea de IRQ) tendras un aviso de que hubo una irq y que se debera comprobar en el bottom half antes de irse a dormir si la cola esta vacia, no?.

[ Padre ]


En líneas generales... (none / 0) (#9)
por jorginius ("jorginius" en Google Mail) a las Tue May 10th, 2005 at 05:20:33 PM CET
(Información Usuario) http://www.rodriguezmoreno.com

Hago un remix y te contesto por aquí a los dos posts.

Supongo que una vez que accedo al hardware, debo hacer un enable_irq()?.

En principio sí, lo único que tiene que ser atómico es el acceso al hardware y a lo que compartan las interrupciones y el bottom half, si lo hay.

Luego cada dispositivo es un mundo y hay que calibrar lo que tiene que ir en el manejador y lo que puede ser ejecutado con las interrupciones activadas.

¿como se sabe a que proceso hay que darle los datos que, por ejemplo, se han recibido del dispositivo?

¿Quién y a qué proceso?, ¿el sistema operativo?, ¿a un proceso de usuario o a un hilo del sistema?. Hay mil formas. No es problema.

Solo tengo semaforos (y gracias). No tengo spinlocks ni ninguna otra primitiva de sincronizacion Un spinlock es, a fin de cuentas, un semáforo binario. Uno rápido, con espera activa preferentemente.

Si tienes semáforos lo tienes todo.

En la cola de interrupciones (supongo que una por linea de IRQ)

No tiene por qué. Depende del diseño, de donde reconozcas la interrupción, etc. Puedes guardar un identificador y que haya un dispatcher que esté recorriendo la cola y llamando al manejador adecuado según el id.

A veces resulta que es el hardware mismo el que encola las interrupciones.

Una "cola global" es bastante típica. Por ejemplo: al llegar una interrupción hardware, el top half, aparte de hablar con el hardware y pasar lo que le dé el dispositivo a un buffer, encola una tarea (el bottom half o manejador de segundo nivel). Luego el planificador se ocupará de ejececutar esas tareas ya con las interrupciones habilitadas.

Ah, una cosa que te aseguran todos los SO AFAIK es que, aunque los bottom half pueden ser interrumpidos, uno no puede estar ejecutándose más de una vez simultáneamente (las nuevas interrupciones que llegan por la misma línea se encolan pero no se procesan hasta que no se acaba con las antiguas).

tendras un aviso de que hubo una irq y que se debera comprobar en el bottom half antes de irse a dormir si la cola esta vacia, no?.

Bueno, la idea era un semáforo que lleve la cuenta de las interrupciones que quedan pendientes por procesar en la cola. El manejador lo incrementa y, si no hay más interrupciones, el bottom half se bloquea en el semáforo.

No sé, es un ejemplo: la idea es esa pero luego lo implementas como quieras. Este esquema tal cual no funciona si quieres más de un bottom half por interrupción pero se puede adaptar.

[ Padre ]


 

gestion de interrupciones | 9 comentarios (9 temáticos, editoriales, 0 ocultos)
Ver: Modo: Orden:
Menu
· crear cuenta
· FAQ
· búsqueda
· Fuentes de Noticias

Login
Nueva cuenta
Usuario:
Contraseña:

ecol Logo Powered by Scoop
Todas las Marcas Registradas y copyrights de esta página son propiedad de sus respectivos dueños.
Los comentarios son propiedad del que los escribe.
Los iconos de las noticias y el logotipo son propiedad de Javier Malonda.
El Resto © 2002 Escomposlinux.org y aledaños.

Puedes sindicar los contenidos de libertonia en formato RSS 1.0 y RDF 0.9. También se puede sindicar la cola de envíos pendientes de moderación.

El proyecto escomposlinux.org está dedicado a la memoria de tas

crear cuenta | faq | búsqueda