Práctico 9 - Ejercicio 5

Práctico 9 - Ejercicio 5

de Franco Pelua Camacho -
Número de respuestas: 4
Hola! buenas tardes. 
Tengo una propuesta de solución para el ejercicio 5, pero no se si esta bien. Este ejercicio me resulto particularmente más difícil que los anteriores y me gustaría tener un poco de feedback. 

Tengo dudas especialmente con el uso de la variable isRequestingInterrupt. La duda que me genera es a la hora de resetearla a 0. Dicha variable se inicializa en cero, luego, en la primera interrupción por parte de algún controlador de entrada, se configura en 1. Recién la vuelvo a configurar en 0 tras haber hecho un polling en todos los puertos para ver cual (o cuáles) estaban solicitando interrumpir.

La duda que me genera es si esta decisión de primero pollear todos los puertos y luego resetear la variable es correcta, y sino, ¿Cómo debería de manejar esta variable?

La otra consulta es respecto al código de las interrupciones. ¿Debería comenzar las rutinas de atención a las interrupciones con un disable() y finalizarlas con un enable()? En algunos ejemplos vi que hacen eso, lo cuál me parece raro porque entiendo que dentro de las rutinas de atención a interrupciones, automáticamente quedan enmascaradas nuevas interrupciones, hasta que se sale de dicha rutina. 

¡Gracias de antemano y saludos!

En respuesta a Franco Pelua Camacho

Re: Práctico 9 - Ejercicio 5

de Franco Pelua Camacho -
Analizando un poco más la rutina de atención a la interrupción "intSalida", note que escribí una operación de escritura al puerto de salida. Dado que esta acción es la que funciona de trigger para la invocación por hardware de intSalida, ¿esto generaría una especie de recursión? evidentemente si así fuese sería indeseado. Igualmente, si es verdad que al estar dentro de una rutina de atención a la interrupción, nuevas interrupciones están deshabilitadas, supongo que no es problema, ¿no?
En respuesta a Franco Pelua Camacho

Re: Práctico 9 - Ejercicio 5

de Federico Rivero -
Hola Franco,

Perdón por la demora en la respuesta. Varios comentarios:

1) Sobre tu consulta de 'La duda que me genera es si esta decisión de primero pollear todos los puertos y luego resetear la variable es correcta, y sino, ¿Cómo debería de manejar esta variable?'.

Sí, es correcto, aunque también hay que notar que si pusieras la variable en 0 antes de realizar el polling tampoco estaría mal. Por la forma en que funcionan estos puertos, donde el bit de EST_CONT_N baja a 0 luego de ser leído, no aparecen posibles problemas de concurrencia. De hecho se podría descartar la interrupción int_entrada y simplemente realizar polling de los puertos EST_CONT_N todo el tiempo y la solución funcionaría. 

2) Sobre tu consulta: 'La otra consulta es respecto al código de las interrupciones. ¿Debería comenzar las rutinas de atención a las interrupciones con un disable() y finalizarlas con un enable()?' No! No es necesario comenzar las interrupciones así porque al ingresar a la interrupción las mismas están deshabilitadas (es parte de las acciones de hardware que realiza la CPU previo a atender a una interrupción). Si agregás disable() al principio y enable() al final, por más que no van a tener efecto práctico en la solución, lo vamos a calificar como un error conceptual. Me atrevo a decir que eso no aparece en ninguna solución. Quizás lo que viste es comenzar una interrupción con un enable(), lo cual podemos realizar en ciertas ocasiones y con mucho cuidado, para habilitar interrupciones dentro de una interrupción. Podrían haber casos donde quieras eso, pero van a ser la excepción. Además desaconsejamos hacerlo porque es fácil equivocarse.

3) Sobre tu última consulta: 

Analizando un poco más la rutina de atención a la interrupción "intSalida", note que escribí una operación de escritura al puerto de salida. Dado que esta acción es la que funciona de trigger para la invocación por hardware de intSalida, ¿esto generaría una especie de recursión? evidentemente si así fuese sería indeseado. Igualmente, si es verdad que al estar dentro de una rutina de atención a la interrupción, nuevas interrupciones están deshabilitadas, supongo que no es problema, ¿no?

Correcto, como las interrupciones están deshabilitadas, no te van a interrumpir tu interrupción. Además, es de suponer que la interrupción intSalida va a demorar cierto tiempo en llegar. No está explicitado, pero la existencia de esta interrupción implica que la transfernecia de los bytes de salida es 'lenta' en comparación a la ejecución de la CPU.

Finalmente, un par de comentarios sobre la solución:

4) Al inicio no es necesario poner disable() ya que la máquina es dedicada, (as interrupciones comienzan deshabilitadas y tu código es lo primero que se ejecuta). En una máquina no dedicada sí tenés que incluir el disable() porque deberías asumir que otra rutina ya habilitó las interrupciones.

5) Fijate que por cómo usaste las estructuras de datos, vos mandás los datos en forma LIFO (last in first out), como un stack. No está explicitado tampoco pero el envío debería ser FIFO (deberías usar una cola). Fijate que al enviar de forma LIFO estás desordenando los bytes de entrada.

Saludos,
Federico
En respuesta a Franco Pelua Camacho

Re: Práctico 9 - Ejercicio 5

de Valentino Bobbio Baldi -
tengo una duda en if(buffer_size<=max_buffer-2){}:
cuando se ejecuta buffer[buffer_size+1]=IN(ports[i]) se está guardando EST_CONT_n, luego al ejecutar OUT(0x20, buffer_item_copy) dentro de if(outputBusFree) se está emitiendo un byte 0..01 ó 0..00 cuando en realidad debería emitir el número del puerto. por lo tanto no debería ser buffer[buffer_size+1]=(IN(ports[i])-0x10)/2? (ya que al puerto n, le corresponden las direcciones 0x10+n*2 y 0x10+n*2+1)

después un detalle, isRequestinInterrupt=0 se está ejecutando durante cada iteración del for