Facultad de Ingeniería Eléctrica. Departamento de Electroenergética. Tesis de Grado. Título: Sistema de Digitalización de Señales Eléctricas Basado en la Tarjeta AX5411. Autor: José Alejandro López Sarmiento. E – mail: [email protected] Tutores: M.Sc. Ing. Alejandro García Rodríguez. Ing. Juan Antonio Gutiérrez Fernández. Consultante: Ing. Yoany Guerra Contino. Curso: 2003 – 2004. Hago constar que el presente trabajo ha sido realizado en la Universidad Central ‘‘ Marta Abreu ´´ de Las Villas como parte de la culminación de estudios de la carrera de Ingeniería Eléctrica y autorizo que sea utilizado por la Universidad para los fines que considere convenientes. La Universidad tendrá derecho a publicarlo de forma parcial o total. Este trabajo no podrá ser utilizado, publicado o presentado en eventos de ningún tipo sin la autorización de la Universidad. ___________________________________ José Alejandro López Sarmiento. Autor. Los abajo firmantes certificamos que el presente trabajo ha sido realizado según acuerdo de la dirección de nuestro centro y el mismo cumple con los requisitos que debe tener un trabajo de esta envergadura referido a la temática señalada. _________________________ José Alejandro López Sarmiento. Autor. _____________________________ Luis Alberto Hernández Lugones. Jefe del Departamento de Electroenergética de la Facultad de Ingeniería Eléctrica de la UCLV. Dios no nos hubiera dado la posibilidad de soñar, si no nos hubiera dado la oportunidad de hacer realidad nuestros sueños. Rabindranath Tagore. Dedicatoria: U • A mis padres, por su dedicación y su apoyo incondicional. • A mi tío Armando Sarmiento Rojas por su preocupación y su ayuda. • A toda mi familia, por su ayuda en todo momento. • A mis compañeros de estudios, por su amistad. Agradecimientos: U • A mi tutor, M.Sc. Alejandro García Rodríguez por su ayuda y su apoyo. • Al Ing. Yoany Guerra Contino, porque sin su orientación no me hubiera sido posible hacer este trabajo. • Al Dr. Roberto Ballesteros por su valiosa ayuda. • Al Dr. Julián Luciano Cárdenas porque su ayuda también ha sido invalorable. • A mis profesores, por la formación que me dieron. TAREA TÉCNICA. Este trabajo consiste en poner a punto la tarjeta de adquisición de datos AX5411. Esta tarjeta es una tarjeta fabricada en el año 1994 pero es compatible con una PC moderna. El principal inconveniente es que los drivers con que se compraron están hechos para el sistema operativo MS-DOS y por tanto no corren en Windows. Nuestro objetivo principal es programar los drivers adecuados para Windows 2000, XP. Además nos proponemos proponer varias aplicaciones que pueden tener tarjetas de adquisición de datos similares. Los abajo firmantes somos los responsables por este trabajo. ___________________________ ____________________________ José Alejandro López Sarmiento. M.Sc. Alejandro García Rodríguez. Diplomante Tutor RESUMEN. Con el surgimiento de la computación comenzó un proceso de automatización que ha penetrado, incluso, en nuestros hogares. Tareas que antes se hacían manualmente ahora se hacen de forma automática. Los sistemas SCADA (System of Control and Data Adquisition) son un ejemplo de ello, algunos de estos se basan en PC. Y ese es, precisamente nuestro caso. En el Centro de Investigaciones de Soldadura ha surgido la necesidad de hacer este sistema para analizar la señal del arco eléctrico de la soldadura. Pero no es solo en el CIS donde hay esta necesidad, en la Facultad de Ingeniería Mecánica también es necesaria para medir desviaciones etc, ya que usando un transductor se puede convertir la desviación en una señal de voltaje proporcional. La tarjeta es capaz de convertir esa señal analógica de voltaje es una palabra digital que luego es leída por la CPU de la PC y mostrada en un gráfico en la pantalla. La dificultad es, como ya se mencionó en la TAREA TÉCNICA que los drivers que se adquirieron junto con la tarjeta no corren en Windows, por lo que uno de nuestros objetivos es hacer los drivers correctos para Windows 2000. En el trabajo se explica cómo funciona el sistema operativo Windows 2000 y el hardware de la tarjeta para que el lector pueda lograr una buena comprensión del problema al que nos enfrentamos y de las herramientas para resolverlo. Tarjetas de adquisición de datos como la AX5411 tienen un campo de aplicación muy amplio en la industria, la investigación y la docencia. Índice: Introducción ..................................................................................................3 Capítulo 1 : Análisis bibliográfico .................................................................. 5 1.1 Estado del Arte .......................................................................................5 1.2 Trabajos previos .....................................................................................9 Capítulo 2 : Características de la tarjeta AX5411. Criterios para su programación................................................................................................12 2.1 Características generales de la AX5411 ....................................................12 2.2 Características del subsistema de conversión analógico – digital. Fundamentos de la medición digital ........................................................................................13 2.3 Programación de la AX5411 ..................................................................15 Capítulo 3 : Interacción entre el sistema operativo y la tarjeta AX5411 ...........27 3.1 Modo Kernel vs modo usuario ................................................................27 3.2 Componentes de Windows 2000 .............................................................29 3.2.1 La API Win32 .....................................................................................29 3.2.2 Servicios, funciones y rutinas ...............................................................30 3.2.3 Procesos, hilos y trabajos .....................................................................31 3.2.4 Memoria virtual ..................................................................................34 3.2.5 Objetos y handles ................................................................................35 3.2.6 El registro ...........................................................................................36 3.2.7 Vista, a grandes rasgos, de la arquitectura del sistema operativo Windows 2000 ...................................................................................................................37 3.3 Componentes del subsistema de entrada / salida ......................................40 3.4 El Administrador de Entrada / Salida (I/O Manager) ...............................42 3.5 Los Device Drivers ...............................................................................43 3.6 Estructura de un driver ..........................................................................44 3.7 El Administrador de Plug and Play ( PnP Manager ) ...............................47 3.8 El Administrador de Energía (Power Manager) .......................................50 3.9 Estructura de los datos de entrada / salida ...............................................53 3.9.1 Los ficheros objeto (file objects ) ........................................................53 3.9.2 Driver objects y device objects ............................................................56 3.9.3 Los Paquetes de Solicitud de Entrada / Salida (I/O Request Packets) .....59 3.10 Procesamiento de la I/O .......................................................................61 3.10.1 Tipos de I/O. Sincrónica y Asincrónica .............................................61 3.10.2 Solicitud de Entrada / Salida en un driver simple (sin capas) ..............62 3.10.3 Atendiendo la interrupción ...............................................................63 3.10.4 Solicitud de I/O en drivers en capas ..................................................6 3.11 Sincronización ....................................................................................70 3.12 Conclusiones sobre el subsistema de I/O de Windows 2000 ..................72 3.13 Especificidades del sistema. Herramientas para hacer el driver ..............73 Capítulo 4 : Conceptos finales y resultados de las pruebas ............................77 4.1 Pruebas al hardware (tarjeta) .................................................................77 4.2 Comunicación entre el driver (Driax5411.sys) y la aplicación (CALLAX5411.exe) .................................................................................................................78 4.3 Prueba de funcionamiento al sistema ....................................................80 Conclusiones ............................................................................................84 Recomendaciones .....................................................................................85 Referencias Bibliográficas ..........................................................................86 Bibliografía ...............................................................................................87 Anexos .....................................................................................................88 Introducción: Los sistemas SCADA han entrado en la industria cubana aún tímidamente. Sin embargo, gozan de la aceptación de los especialistas que interactúan con ellos. Sin embargo, se ha apostado demasiado por comprar estos sistemas SCADA hechos y los servicios de técnicos extranjeros para instalarlos, lo cual cuesta. Por tanto es apremiante que nuestros ingenieros y técnicos entren más en contacto con esta tecnología a fin de que sean capaces de implementar, en la medida de lo posible, estos sistemas sin recurrir a la ayuda extranjera. Nuestro trabajo pretende dar solución a una necesidad del Centro de Investigaciones de Soldadura, de la Universidad Central `` Marta Abreu ´´ de Las Villas donde es necesario medir el arco eléctrico de la soldadura en tiempo real, y analizar esta forma de onda. Para lograr esto se ha utilizado la tarjeta de adquisición de datos AX5411 conectada a una PC. Tarjetas como ésta se usan prácticamente en la totalidad del mundo. Las aplicaciones industriales van desde la medición del consumo energético hasta mediciones relacionadas con el proceso tecnológico propiamente dicho. A lo largo de este trabajo se va a describir el funcionamiento de la tarjeta y los algoritmos para su programación. También se describirá con detenimiento el sistema de entrada / salida del sistema operativo Windows 2000, puesto que es imprescindible conocerlo para poder acceder a la tarjeta conectada a la PC. Y al final se describirán las pruebas a que se sometió el sistema. Capítulo 1. Análisis Bibliográfico. Capítulo 1: Análisis Bibliográfico. Introducción. El Centro de Estudios de Soldadura de la Facultad de Ingeniería Mecánica de la Universidad Central de Las Villas, a tono con las principales prioridades de la soldadura a nivel mundial, comienza estudios sobre la estabilidad de onda del arco eléctrico de la soldadura que hasta ahora se han visto en un nivel práctico insuficiente por falta de tecnologías adecuadas de sensado y digitalización del voltaje y la corriente del arco eléctrico. Este tema constituye una necesidad tanto para la docencia como para la investigación, lo cual ha sido referido en modernas publicaciones del campo de la soldadura. Nuestro análisis lo hemos dirigido en tres direcciones fundamentales: SCADA (System of control and data adquisition)(Sistema de control y adquisición de datos) Investigación sobre el sistema operativo Windows 2000 para poder hacer el driver necesario para la tarjeta AX5411. Estudio de las posibles aplicaciones de tarjetas similares. También hemos hecho una revisión de los trabajos anteriores. En los siguientes epígrafes vamos a abordar el estado del arte. 1.1 Estado del Arte. En el mundo hay muchas empresas que se dedican a hacer y comercializar tarjetas como la AX5411. El mercado es inmenso porque, como ya he dicho anteriormente, esta tecnología está presente en casi la totalidad del mundo por su importancia para la industria y la investigación. Una de las empresas punteras en esto es AXIOM Tecnologies Co , cuyos productos están presentes en buena parte del mundo. Basta con visitar su sitio1 para darse cuenta de la variedad de productos que oferta. AXIOM vende tarjetas de adquisición de datos para distintos buses de una PC (PCI, ISA, USB etc). Cada tarjeta es vendida con su driver para Windows 98, Millenium, 2000, XP, 2003 Server etc, y una DLL que es la que llama al driver (más adelante veremos cómo se hace eso), de modo que cuando se compra una sólo hay que hacer una aplicación en cualquier superlenguaje (Delphi, C++, Visual Basic etc) que llame a las funciones de 1 www.axiomtec.com esa DLL. Es sencillo trabajar con ellas. También se vende junto con la tarjeta un manual de usuario que describe el hardware de la tarjeta en cuestión y las funciones que hay que usar para controlarla.[3] Si usted visita el sitio de esta empresa verá que es muy variada su oferta. Normalmente estas tarjetas tienen varios bloques, conversión analógico – digital, digital – analógico, varias entradas y salidas digitales de distintos tamaños (en bits), temporización etc. A veces es posible generar formas de onda con ellas etc. Alguna de estas tarjetas tienen una CPU independiente (autónoma respecto a la de la motherboard de la PC) que realiza funciones de control que el usuario no puede cambiar. De aquí el lector puede ver que también se pueden usar estas tarjetas para el control de procesos. Otra forma es usar autómatas programables los cuales AXIOM también oferta. La firma AXIOM no es la única, como ya se ha dicho, hay muchas empresas en el mundo que se dedican a este campo. Para tener una idea más completa de la magnitud de el uso y las aplicaciones de los sistemas de medición digitales lo más indicado es ver algunas patentes de sistemas análogos; ya que el sistema que proponemos es, a fin de cuentas, un sistema de medición digital. La Oficina de Patentes de los Estados Unidos tiene un sitio en Internet donde se pueden ver las patentes desde el siglo XVIII hasta nuestros días: visitándolo podemos encontrar muchos ejemplos de patentes de sistemas de medición digital de información (o sea de señales de distinta naturaleza). A continuación de estas líneas usted podrá ver algunos ejemplos: Patente: US 5,404,317 Fecha: 4 de abril de 1995. Título : Dispositivo de medición digital. Inventor: Song; Jang – Shii y Tsai, David. Se trata de un dispositivo de digital para medir señales eléctricas conectado a una PC. Tiene 4 canales para medir que se multiplexan. Una tarjeta en la que hay una CPU independiente controla el proceso de multiplexado, conversión y trasmisión a la CPU de la computadora personal. [1] Patente: US 5,657,237 Fecha: 12 de agosto de 1997. Título: Instrumento y método de medición de señales eléctricas periódicas. Inventor: Mazzoni, Herminio. Asignada a: Electrex S.r.l El método involucra el uso de un instrumento con, al menos, un amplificador operacional para sensar el valor del voltaje analógico, y luego la corriente relativa ; introduciendo un retardo conocido y aplicando un voltaje de referencia a la entrada del amplificador operacional para lograr que las señales de entrada sean positivas (semiperíodo positivo). Entonces los valores analógicos son convertidos en digitales y los valores de corriente son corregidos restándoles el voltaje de desplazamiento del operacional. El instrumento incluye un convertidor analógico – digital como parte de una unidad de procesamiento de datos, un sample and hold, memoria, con un registro de desplazamiento, y una unidad programable de control. El dispositivo es capaz de medir tanto potencia activa como potencia reactiva.[1] Patente: US 5,736,848 Fecha: 7 de abril de 1998. Título: Sistema de medición analógico – digital y calibración para energía eléctrica. Inventor: De Vries; Jacob , Peter; Jan, Cermeno; Raul , Hodel; Peter. Asignada a: Landis & Gyr Tecnology Innovation AG. El sistema mide la energía de salida de una o varias fuentes eléctricas, haciendo primero una medición analógica de potencia y luego convirtiendo en resultado a una palabra digital. El convertidor A – D incluye un modulador sigma – delta en serie con un filtro digital. La palabra digital resultante luego es introducida a un cuantificador digital a través de una interfase serie. Un valor programable de calibración es introducido al cuantificador desde una computadora. [1] Patente: US 6,243,652 Fecha: 5 de junio de 2001. Título: Sistema para la medición digital del voltaje pico y RMS en un sistema de alto voltaje. Inventor: Fawcett; Timothy J. (Runcorn, UK) , Fore; Neil S. (Hale, UK) Asignada: Hubbell Incorporated. El sistema de medición de voltaje emplea un detector de valor máximo para la medición del voltaje pico. También cuenta con memoria en la cual se almacenan las muestras de voltaje tomadas a intervalos predeterminados. Estos valores almacenados en la memoria son usados luego para calcular el voltaje RMS.[1] Patente US 6,195,617 Fecha: 27 de febrero de 2001 Título: Osciloscopio para mediciones simultáneas y muestra en un eje de tiempo común. Inventor: Miller; Martín T. (Geneva, CH) Asignada: LeCroy S.A. (CH) Un método para presentar información que primariamente es leída y luego almacenada en memoria para ser mostrada en pantalla luego. Las señales son mostradas como funciones del tiempo en un eje de tiempo común. [1,2] El cliente. Como ya es conocido los sistemas SCADA están implementados en la mayoría de las industrias y centros docentes y de investigación, así como en la vida cotidiana. Cualquier industria que se respete necesita sistemas SCADA para múltiples cosas, por ejemplo: en una industria química muchas veces es necesario conocer, en tiempo real, la temperatura, concentración, presión, etc, dentro de tanques en los que ocurre un proceso dado. Todas estas variables se miden convirtiéndolas primero en voltaje que es leído por un sistema de digitalización de señales. El sistema de digitalización de señales puede ser la tarjeta AX5411 o una similar. En el C.A.I‘‘ Uruguay ’’ 2 podemos constatar el funcionamiento de un sistema SCADA que se usa para controlar y medir los parámetros necesarios (potencia activa y reactiva y la dirección de su flujo, voltaje, fase, frecuencia tanto en el SEN3 como en la planta del Central) en la planta. Este sistema consta de un autómata que está conectado a una PC en el despacho de carga de la planta. Hay uno similar para controlar las calderas. En los dos casos el autómata usa una tarjeta de adquisición de datos para medir las variables necesarias. Pueden medirse variables de naturaleza mecánica como desplazamientos, torsiones etc. En general pueden medirse variables de cualquier naturaleza siempre y cuando se cuente con transductores que conviertan la señal a medir en señales de voltaje proporcionales. La tarjeta AX5411 también tiene entradas y salidas digitales, que pueden ser de 8 o de 16 bits. De la misma forma, cualquier sistema de control las tiene ya que es la forma de adquirir datos que han sido convertidos por otro sistema, o para 2 El CAI ‘‘ Uruguay ’’ está en el municipio de Jatibonico, provincia Sancti Spíritus, Cuba. Está considerado un coloso de la industria azucarera cubana. 3 Sistema Electroenergético Nacional. comunicarse con otros sistemas inteligentes. En el mundo se puede observar la tendencia a que las industrias estén automatizadas ‘‘por partes’’; o sea, que cada parte del proceso productivo tenga su controlador, que puede ser un PLC4, o una computadora que a su vez le envía datos y recibe órdenes de un controlador central. De ahí la importancia de estas entradas y salidas digitales. En general los sistemas SCADA han inundado la vida cotidiana: están en casi todas partes aunque las personas no los vean. Quizás algunas personas piensen que esta es una tecnología exclusiva del primer mundo, pero están equivocadas, no es un lujo sino una imperiosa necesidad incluso en industrias de países del tercer mundo. Dada la tendencia mundial y las necesidades de nuestra industria, Cuba debe seguir el camino que ha iniciado para que nuestros productos sean competitivos en el mercado mundial. 1.2 Trabajos y aplicaciones previas. No se pueden dejar de mencionar los trabajos previos, que son una cantidad importante, ya que el campo de aplicación es inmenso. Por razones de tiempo y espacio no se pueden enumerar todos por lo que se han escogido algunos de los más representativos. La tarjeta AX5411, como ya se ha dicho, es relativamente antigua y, sin embargo, navegando en Internet se descubre que aún se usa. Existe un trabajo titulado ‘‘ Estudio y Diseño de Desarrollo de una Aplicación de Tiempo Real y de un Simulador para su Comprobación: Péndulo Invertido ’’ realizado por el señor Rubén Migueles García en el cual su autor propone un sistema análogo al nuestro, desde el punto de vista de que usa la misma tarjeta conectada a una PC, pero con la diferencia de que él no desarrolla los drivers para Windows 2000 sino para Linux y la señal a medir no es de naturaleza eléctrica sino mecánica: se trata de medir posición. En este trabajo el autor explica (en los primeros capítulos y sin muchos detalles, lo cual es lógico ya que ello requeriría todo un libro) las características de sistemas operativos más adecuados para tiempo real como MaRTE O.S. En este trabajo el autor tropezó con la misma dificultad que en este: los drivers no le fueron útiles. 4 Progamable Logic Controller . También en la Universidad de Camagüey se hizo una aplicación con la tarjeta AX5411. En este caso se trata de un sistema aplicable a la industria azucarera ya que se usa la tarjeta para realizar mediciones propias del proceso tecnológico. Este trabajo se titula: ‘‘ Instalación Experimental Versátil para la Gasificación y Pirólisis del Bagazo de Caña en lechos fluidizados con fines energéticos’’. La tarjeta AX5411 ha encontrado usos también en investigaciones científicas. En Australia se realizó una investigación en la que se utilizó la AX5411 para digitalizar las señales de la presión arterial, la frecuencia cardiaca y otros parámetros del funcionamiento del sistema cardiovascular de varios pacientes y voluntarios. Aunque solo han sido mencionados trabajos en los que se utiliza la tarjeta AX5411 sería un error pensar que solo ésta se usa. En la actualidad existen tarjetas más modernas, con drivers hechos para Windows 2000, XP etc que son usadas ampliamente. 5 Capitulo 2: Características de la Tarjeta AX5411. Criterios para su programación. Capítulo 2: Características de la Tarjeta AX5411. Criterios para su programación. Introducción: El sistema SCADA que proponemos se basa en la tarjeta AX5411. Esta es una tarjeta de adquisición de datos que, a pesar de ser relativamente antigua puede ser muy útil en la industria, la investigación y la docencia. No se debe perder de vista que en la actualidad existen otras tarjetas más modernas y más adaptadas a las PCs modernas en cuanto a hardware y a los sistemas operativos Windows. No quiere decir esto que hay que desecharla, no, se le puede sacar provecho. En los siguientes capítulos se describirá con más detalle como usarla en las condiciones actuales. 2.1 Características generales de la tarjeta AX5411. La tarjeta Ax5411 es una tarjeta de adquisición de datos diseñada para conectarse al bus ISA de una PC. Esta es una de sus características que limitan su uso ya que las PCs más modernas, por lo general, no tienen bus ISA. Los drivers que se adquirieron junto con la tarjeta no funcionan en Windows, por lo que ha sido necesario hacer el driver que es capaz de manejar la tarjeta en el sistema operativo Windows 2000. En este caso no había más opción que montarse en el sistema operativo, ya que este es amo y señor de la PC. Pero en este capítulo vamos a postergar adentrarnos en Windows 2000 y vamos a concentrarnos en el hardware que tenemos que controlar sin perder de vista con qué fin nos proponemos hacer esto. Lo primero que hay que conocer es dónde conectar la tarjeta. Bueno eso es lo más simple: la tarjeta AX5411 es compatible con el bus ISA y es ahí justamente donde hay que conectarla. La tarjeta ocupará 16 direcciones de I/O consecutivas en el espacio de direcciones de la PC. La tarjeta tiene un switch que le permite al usuario seleccionar la dirección base (desde x200 hasta x3F0), de esta manera se puede evitar posibles conflictos con otros dispositivos periféricos. La tarjeta consta de tres subsistemas, el subsistema de conversión analógico – digital, el de entrada y salida digital y el de conversión digital – analógico. 2.2 Características del subsistema de conversión analógico – digital y fundamentos de la medición digital. El subsistema de conversión A/D merece un epígrafe aparte ya que esta es la aplicación más fuerte de la tarjeta. Para comenzar se dará una idea general de los fundamentos de la medición digital de información. Ante todo es necesario aclarar que lo que se mide es voltaje. Para medir corriente, temperatura, presión u otra señal de cualquier otra naturaleza primero hay que convertirla en una señal de voltaje proporcional. Figura2.1 Estructura básica de un sistema de medición digital, basado en una PC. Cualquier sistema de medición digital tiene tres componentes que no pueden faltar: el convertidor analógico – digital, el sample and hold, y el multiplexor. El multiplexor puede ser digital o analógico, o sea, multiplexar señales analógicas o palabras digitales. En el caso de la AX5411 lo que se multiplexa son las señales de entrada analógicas. También los sistemas de medición digitales pueden tener otro elemento: un amplificador para acomodar la señal de entrada cuando es muy pequeña. La AX5411 tiene uno de ganancia programable, lo que permite seleccionar el rengo de medición por la fórmula: Rango = Máxima escala Ganancia [3] donde la ganancia puede ser 1, 2, 4, 8 ó 16. La ganancia se selecciona por programación. 6 Figura 2.2. Subsistema de conversión analógico – digital de la tarjeta AX5411. El convertidor A / D es el corazón de este sistema, es que nos permite convertir una señal analógica en una palabra digital proporcional. El convertidor A / D divide el rango de la señal analógica de entrada en tantos escalones como combinaciones pueda tener la palabra digital de salida. Por ejemplo, el de la tarjeta es de 12 bits por tanto hay 4096 escalones entonces, si el voltaje máximo de entrada es 5V, 5V es 111111111111 en binario (4095 en decimal), 000000000001 es 0.001221V por tanto si obtiene una lectura de 4095 no es que el sistema no es fiable sino que usted tiene que hacer una regla de tres para obtener el valor real. El sample and hold es el circuito de muestreo y retención que retiene el valor de la señal analógica de entrada mientras el convertidor A / D la convierte. Esto nos 6 Cuando se ha seleccionado +/- 5V los rangos disponibles son: +/- 5V, +/- 2.5 V, +/- 1.25 V, +/- 0.625 V y +/- 0.3125 V. Y cuando se ha seleccionado +/- 10V los rangos son: +/- 10V, +/- 5V, +/- 2.5V, +/- 1.25 V y +/- 0.625V. permite muestrear una señal de voltaje alterno y así poder representar la señal en un gráfico. Es muy importante señalar que la frecuencia de muestreo siempre tiene que ser mayor que la de la señal que se está midiendo. 2.3 Programación de la AX5411. La tarjeta tiene 16 registros (para la motherboard son direcciones de I/O consecutivas) que si los programamos podemos controlar la tarjeta y realizar la tarea que nos proponemos. Vamos a ver cómo son esos registros y qué hacen. A partir de aquí no voy a poner la dirección de los registros, sólo el desplazamiento con respecto a la dirección base, por ejemplo, y asumiendo que la dirección base sea 300h, cuando digo : +1 me refiero al registro 301h. +0 : D3 D2 D1 D0 C3 C2 C1 C0 Bits 0 – 3 : C0 – C3 . Se usan para especificar uno de los canales de conversión A – D como el canal de entrada para una conversión. Bits 4 – 7 : D0 – D3 . Estos bits son la parte menos significativa del dato. +1: D11 D10 D9 7 6 5 D8 4 D7 D6 3 D5 D4 2 1 LC2 LC1 0 Este registro es la parte más significativa del dato. +2 : UC3 UC2 7 6 UC1 5 UC0 LC3 4 3 bits 7 – 4 : UC3 – UC0 . Canal final. bits 3 – 0 : LC3 – LC0 . Canal de inicio. 2 1 LC0 0 Este es un registro de lectura / escritura que controla los canales de inicio y final por donde se va a leer las señales analógicas. El nibble alto define el canal final y el bajo el canal de inicio. Aproximadamente 4 µs después de que el convertidor analógico – digital comienza la conversión, mientras el sample and hold está sosteniendo el canal anterior, el canal activo del multiplexor se incrementa y se prepara para la conversión del próximo canal. Cuando se termina la conversión del último canal el ciclo comienza de nuevo con el canal de inicio. Para realizar conversiones en un solo canal se pone en el canal de inicio y el final el mismo número, correspondiente al canal deseado. +3 : IP7 IP6 7 IP5 6 5 IP4 IP3 4 3 IP2 IP1 2 IP0 1 0 Entrada digital (sólo lectura). +8 : EOC 7 X X 6 INTP 5 4 NC3 3 NC2 NC1 2 NC0 1 0 Registro de estado. Bits 0 – 3 : NC0 – NC3 : Este es el número del canal en el que se va a hacer la próxima conversión si EOC = 0. El canal cambia poco tiempo después de que EOC pasa a nivel alto y cuando EOC = 1 es indeterminado. Esto es muy útil porque brinda información sobre la próxima conversión. Bit 4. INTP. Este bit se refiere a la señal de interrupción. Cuando la interrupción está deshabilitada INTP = 0. Después de la generación de una interrupción INTP = 1 y permanece ahí hasta un reset o hasta que se escriba en el registro +8 limpiando así la interrupción. Por eso la subrutina de atención a la interrupción debe tener esto en cuanta, limpiando la interrupción para que después pueda producirse de nuevo. Bits 5 – 6 . X significa no importa. Bit 7 EOC. Indica el fin de una conversión. EOC = 0 significa que la conversión ha terminado y EOC = 1 que la conversión aún está en proceso y no hay un dato válido en el buffer. El comienzo de una conversión pondrá EOC a 1. +9 : INTE I2 I1 I0 TRG DMA E E T1 T0 Bits 0 – 1 T1 y T0. Estos bits controlan la fuente de inicio de los pulsos de arrancada para el convertidor analógico – digital. T1 T0 Acción 0 X Arrancada sólo por software. 1 0 Arrancada por pulso externo (EXTRG). 1 1 Arrancada por pulso del temporizador de la tarjeta (8254). Tabla 2.1 Modos de arranque del sistema de conversión A – D de la tarjeta AX5411. Bit 2 DMAE. Habilita el acceso directo a memoria (DMA). Cuando DMAE = 1 está habilitado y cuando DMAE = 0 está deshabilitado. Con este registro solamente se habilita en la tarjeta, es responsabilidad del usuario programar el acceso directo a memoria como tal. Bit 3 TRGE. Pulso externo (EXTRG) y TRGE están ligados. TRGE EXTRG Temporizador 0 0 Habilitado. 0 1 Habilitado. 1 0 Deshabilitado. 1 1 Habilitado. Tabla 2.2 Relacion entre el bit TRGE y la entrada EXTRG y su efecto en el temporizador interno de la tarjeta AX5411. Bits 4 – 6 . I0 – I2. Seleccionan el nivel de interrupción deseado para procesar la interrupción. I2 I1 I0 Nivel de interrupción. 0 0 0 Inválido. 0 0 1 Inválido. 0 1 0 Nivel 2. 0 1 1 Nivel 3. 1 0 0 Nivel 4. 1 0 1 Nivel 5. 1 1 0 Nivel 6. 1 1 1 Nivel 7. Tabla 2.3 Niveles de interrupción. Bit 7. INTE. Este bit habilita o deshabilita la interrupción. Cuando INTE = 0, está deshabilitada, cuando INTE = 1 está habilitada. Si INTE = 1 y DMAE = 0 se genera una interrupción al terminar una conversión A / D y hay un dato válido en el buffer. Si DMAE = 1 y INTE = 1 la interrupción se genera cuando ha terminado una transferencia de DMA. +10: DI7 DI6 DI5 DI4 DI3 7 6 5 4 3 DI2 DI1 DI0 2 1 0 DI10 DI9 DI8 1 0 Byte bajo de la entrada digital (sólo lectura). +11: DI15 7 DI14 6 DI13 5 DI12 4 DI11 3 Byte alto de la entrada digital (sólo lectura). 2 +1: X X X 7 6 X R3 5 4 R2 3 R1 2 R0 1 0 Bits 7 – 4 : No importa. Bits 0 – 3 : Ganancia del amplificador. R3 R2 R1 R0 Ganancia 0 0 0 0 1 0 0 0 1 2 0 0 1 0 4 0 0 1 1 8 0 1 0 0 16 Cualquier otro valor es inválido. Tabla 2.4 Ganancias programables del amplificador de la tarjeta AX5411. +3: OP7 OP6 OP5 7 6 5 OP4 OP3 4 OP2 3 OP1 OP0 1 0 2 Salida digital (sólo escritura). +4: B3 B2 7 B1 6 BO 5 X X 4 3 X X 2 1 0 B6 B5 B4 Byte menos significativo. +5: B11 7 B10 6 B9 5 B8 4 B7 3 +4 y +5 son registros del canal de conversión D / A 0 2 1 0 +6: B3 B2 7 B1 BO 6 5 X X 4 3 X X 2 1 0 B6 B5 B4 Byte menos significativo. +7: B11 7 B10 6 B9 B8 5 B7 4 3 2 1 0 Byte más significativo. +6 y +7 son los registros del canal de conversión D / A 1 Los registros de los canales de conversión digital – analógico son de sólo escritura, primero debe programarse el registro del byte menos significativo y luego el más significativo. Hasta que no se ha escrito en el byte más significativo no se inicia la conversión. +8: Escribiendo en +8 se limpia la interrupción INTP y así se puede asegurar que vuelva a producirse después. +10: DO7 DO6 7 6 DO5 5 DO4 DO3 4 DO2 3 2 DO11 DO10 DO1 1 DO0 0 Salida digital (byte menos significativo). +11: DO15 DO14 DO13 DO12 7 6 5 4 3 2 DO9 DO8 1 0 Salida digital (byte más significativo). Los registros +10 y +11 son los registros de la salida digital. Como el lector seguramente se habrá dado cuenta hay salidas y entradas digitales de 16 y de 8 bits. La tarjeta AX5411 puede contar tiempo también. Por otra parte había dicho que una de las formas de mandar a convertir al convertidor A / D es por el temporizador interno de la tarjeta, Pues para esto se utiliza el contador – temporizador 8254 de Intel. El 8254 consta de tres contadores, un registro de canal de datos, una lógica de control y un registro de palabra de control. Los contadores 1 y 2 están conectados en cascada y son los que operan como fuente de pulso para iniciar la conversión. La ventaja que nos ofrece esta conexión en cascada es que de esa forma se puede variar la frecuencia de muestreo del sistema de conversión A – D variando las palabras de cuenta convenientemente. La fuente de reloj del contador 1 es una señal de frecuencia seleccionable (1MHz ó 10MHz). El contador 0 puede usarlo el usuario para aplicaciones especiales, por ejemplo para contar el tiempo. Antes de comenzar a programar el 8254 hay que poner a 1 los bits 1 y 0 del registro +9. Estos bits significan los siguiente: TRGE Cuando está a 1 habilita el temporizador, en 0 lo deshabilita. CLKE Cuando es 1 conecta el contador 0 a una fuente interna de 100kHz, si es 0 lo conecta a una fuente externa. Tabla 2.5 Funcion de lis bits TRGE y CLKE en la programación del contador – temporizador 8254 en la tarjeta AX5411. Hay cuatro registros que hay que programar para usar el 8254 de la tarjeta, tres registros de los contadores y uno de control. La siguiente tabla muestra las direcciones de los registros que hay que programar: Dirección Registro Función +12 Contador 0 lectura / escritura +13 Contador 1 lectura / escritura +14 Contador 2 lectura / escritura +15 Registro de palabra de control Tabla 2.6 Direcciones de los contadores del 8254 en la tarjeta AX5411. Los registros de lectura / escritura se usan para escribir la cuenta de cada contador y el de la palabra de control para colocar la palabra de control antes de programar la cuenta de cada contador individual. El siguiente registro es el de la palabra de control. +15: SC1 SC0 7 6 RW1 5 RW0 4 M2 3 M1 M0 2 BCD 1 0 Los bits 7 – 6 : SC1 y SC0 se usan para seleccionar a qué contador se le envía la palabra de control o para enviar un comando read – back. La tabla muestra el significado de esos bits. SC1 SC0 Contador 0 0 Selecciona el contador 0 0 1 Selecciona el contador 1 1 0 Selecciona el contador 2 1 1 Comando read – back. Tabla 2.7 Selección de los contadores en la palabra de control. Los bits RW1 y RW0 seleccionan el tipo de operación: RW1 RW0 Tipo 0 0 Comando counter – match 0 1 Leer / escribir solo byte menos significativo. 1 0 Leer / escribir sólo byte más significativo. 1 1 Comando read – back. Tabla 2.8 Selección del tipo de operación. Bits M2, M1 y M0: se usan para elegir el modo de trabajo de cada contador. M2 M1 M0 Modo 0 0 0 Modo 0 0 0 1 Modo 1 X 1 0 Modo 2 X 1 1 Modo 3 1 0 0 Modo 4 1 0 1 Modo 5 Tabla 2.9 Selección del modo de trabajo del contador. Bit 0: BCD: cuando está a 0 los contadores cuentan en binario (16 bits), si es 1 cuentan en BCD. El comando counter – latch , al igual que la palabra de control se escribe en la palabra de control, también los bits SC0 y SC1 seleccionan uno de los tres contadores, pero los bits 4 y 5 se diferencian de los de la palabra de control. Cuando se envía un comando counter – latch a un contador el latch del contador se carga con el valor de la cuenta en el momento en que se recibe. Esto permite leer el contenido de los contadores `` al vuelo ´´ sin afectar el progreso de la cuenta. Si un contador es puesto en latch, y antes de ser leído se le envía un nuevo comando el último es ignorado hasta que sea leído. Con cualquier método, la cuenta debe leerse de acuerso al formato programado específicamente, para cada contador, esto es, si el contador está programado para cuentas de dos bytes, deben realizarse dos operaciones de lectura. El comando read – back permite comprobar el valor de cuenta, el modo programado y los estados de la señal OUT y la bandera de cuenta cero del contador seleccionado. Al igual que una palabra de control o el comando counter – latch, se escribe en el registro de control. Se distingue de los otros comandos por los bits 6 y 7 que deben ponerse a 1. Para leer la cuenta pueden seleccionarse uno, dos, o los tres contadores poniendo sus bits correspondientes a 1. De esa forma, el comando puede usarse para poner el latch los registros de los múltiples contadores deseados. Así pues, un solo comando es equivalente a varios comandos counter – latch. La cuenta de cada uno de esos contadores puestos en latch se mantiene hasta que es leída. Un contador es sacado de latch automáticamente cuando es leído por la CPU, pero el resto permanecen en latch hasta que son leídos. El formato del comando read – back. 1 1 7 6 COU STAT NT US 5 4 CNT2 3 CNT1 2 CNT0 1 0 0 COUNT: Ver conteo del contador seleccionado. STATUS: Ver estado del contador seleccionado. CNT2: Selecciona el contador 2. CNT1: Selecciona el contador 1. CNT0: Selecciona el contador 0. Hasta ahora sólo ha mencionado los modos de trabajo de los contadores del 8254. Pero es imprescindible conocerlos para poder programar el 8254 y por tanto a la tarjeta. 1. Modo 0: en este modo se puede utilizar al contador seleccionado como contador de eventos. Después de escribir la palabra de control, la señal de salida (OUT) se pone a 0 y permanece así hasta que el contador llegue a 0. Entonces sube a 1 y permanece alto hasta que se escriba una nueva cuenta o un nuevo modo 0 en el contador. Si la entrada GATE se pone a 0 se deshabilita la cuenta. 2. Modo 1: en este modo la señal de salida OUT pasa a nivel alto despés de escribir la palabra de control, pasando a nivel bajo en el pulso de reloj siguiente a un trigger. La señal OUT permanece baja hasta que el contador llegue a cero, entonces subirá a 1 y permanecerá añta hasta que se produzca un nuevo disparo. 3. Modo 2: este modo funciona como un contador divisor por N. La salida OUT pasará a nivel alto después de de escribir la palabra de control. Cuando la cuenta inicial se ha decrementado hasta 1, OUT pasa a nivel 0 durante un pulso de reloj. Después OUT vuelve a nivel 1 de nuevo, el contador recarga la cuenta inicial y se repite el proceso. Este modo es periódico; es decir, se repite la misma secuencia indefinidamente. Para una cuenta inicial de N, la secuencia se repite cada N ciclos de reloj. 4. Modo 3: modo de onda cuadrada. Es usado típicamente para generar ondas cuadradas. Es similar al modo 2 excepto que el ciclo está dividido en dos partes iguales, una a nivel 0 y la otra a nivel 1. La salida OUT pasa a nivel alto después de escribir la palabra de control. Cuando termina la mitad de la cuenta inicial, OUT baja durante lo que queda de cuenta. Este modo es periódico, se repite indefinidamente. Una cuenta inicial de N da como resultado una onda cuadrada con un período de N ciclos CLK. Si la cuenta inicial es par, la salida OUT estará N/2 pulsos 0 y N/2 pulsos en 1. Para cuentas impares, OUT sube a 1 durante (N + 1)/2 cuentas y es cero durante (N – 1)/2. El proceso se repite indefinidamente. 5. Modo 4: En este modo la salida OUT pasará a nivel alto después de escribir la palabra de control. Cuando el valor de la cuenta inicial termina, OUT pasará a nivel 0 durante un pulso de CLK, después del cual volverá a nivel 1. La secuencia de cuentas disparada por la escritura de la cuenta inicial. 6. Modo 5: la salida OUT pasará a nivel alto después de escribir la palabra de control. La cuenta es disparada por flanco de subida de la señal de entrada GATE. Cuando la cuenta inicial ha terminado, OUT pasa a nivel 0 durante un pulso de CLK y después vuelve a 1. Después de escribir una palabra de control y un valor de cuenta inicial, el contador no se cargará hasta que se produzca el primer pulso de CLK. Este primer pulso de CLK no decrementa el valor de la cuenta inicial. La secuencia de programación es sencilla. Primero se escribe la palabra de control para cada contador y después la cuenta inicial. Sea cual sea la operación que se vaya a realizar debe hacerse de acuerdo a un algoritmo específico. Si se van a realizar lecturas de una señal analógica hay que seleccionar programar primero la ganancia y los canales, luego la fuente de arrancada del convertidor A / D; si se va a arrancar por software hay que dar la orden `` manualmente ´´ si es por pulso del temporizador hay que programar al 8254 y si es por pulso externo no se hace nada, sólo dejar que el hardware haga su trabajo. En este capítulo sólo se ha tratado la programación de la tarjeta, el algoritmo siempre es el mismo sea cual sea la PC que se va a utilizar o el sistema operativo que tenga instalado. Lo que varía es la manera de llegar hasta ella, que está en dependencia del sistema operativo. En nuestro caso se trata de Microsoft Windows 2000; todo lo relativo a la manera de acceder a la tarjeta en este sistema será tratado en el capítulo siguiente. Capítulo 3. Interacción entre el sistema operativo y la tarjeta AX5411. Capitulo 3: Interacción entre el sistema operativo y la tarjeta AX5411. Los periféricos que se conectan a la motherboard de una PC son vistos por ella como direcciones de entrada / salida o como direcciones de memoria. Las tarjetas como la AX5411 y las tarjetas de red, video etc. son ejemplos de esto. Los sistemas operativos atienden a los distintos periféricos de distintas maneras, en el caso que nos ocupa, Windows 2000, tiene todo un subsistema de entrada / salida, que va a ser descrito en este capitulo. A diferencia de lo que popularmente se cree los sistemas operativos no son programas monolíticos sino que están compuestos de varios subsistemas (cada uno de ellos formados, a su vez, de todo un conjunto de programas, subrutinas, DLLs, drives, etc.), entre ellos el de I/O que es el que tenemos que conocer mejor para la tarea especifica que nos ocupa. El subsistema de I/O esta compuesto de varios componentes que no pueden ignorarse para lograr lo que nos proponemos sino que hay que aprender a usarlos y entrar en la cadena insertando en ella el eslabón que Windows 2000 nos permite programar. En este capitulo se van a definir los conceptos fundamentales que hay que conocer del sistema operativo y se van a explicar la tarea especifica de cada uno de los componentes del subsistema de I/O y del sistema operativo en general, finalmente se va a describir como funciona todo el subsistema para que el lector pueda formarse una idea completa de la manera de confeccionar los programas para controlar el hardware que se conecta en los distintos puertos o buses de una PC. 3.1 Modo Kernel vs. Modo Usuario. ¿Qué es esto de modo Kernel y modo Usuario? ¿Qué tiene que ver esto con este asunto? Estas son preguntas que, seguramente, están surgiendo ahora en las mentes del lector. La mejor manera de responderlas es hacerlo con un ejemplo. Abra el menú inicio en su barra de tareas y mire en su submenú Programas y vera los programas que usted ha instalado en su PC. También mire a la derecha de la barra de tarea y verá unos pequeños iconos que representan el control de volumen, quizás al Winamp etc. Todos ellos son aplicaciones, el Microsoft Word, Power Point, Excel etc. Las aplicaciones corren en modo usuario. Ahora escriba algo en el Word, unas pocas letras solamente y salve el documento. Se le ha abierto el cuadro de salvar, indíquele cualquier dirección y oprima el botón Salvar, ha salvado su documento y si va a la dirección que le ha indicado vera el icono del Word con el nombre con que usted lo salvó. Salvar significa que su documento ha sido guardado en el disco duro de su PC, o en un disco de 3 ½. ¿Alguna vez se ha preguntado como lo hizo? Pues simplemente el Word ha llamado un driver que se ha encargado de salvar su documento, los drivers corren en modo Kernel. Y… ¿por qué no puede en Word hacerlo directamente? Porque Word no puede salvar nada directamente, ni ninguna otra aplicación. Todas tienen que llamar al driver correspondiente. Las aplicaciones corren en el llamado anillo 3 de Windows, que es el de menos privilegio; desde el anillo 3 no se puede acceder a los puertos de la PC, no se puede acceder al hardware en general, de modo que haciendo una aplicación en cualquier lenguaje de programación (Delphi, C++, cualquiera) no podemos mandarle una instrucción de salida o de entrada a los puertos porque el producto final será una aplicación y desde ahí el sistema operativo no nos va a permitir esa operación. En cambio los device drivers o manipuladores de dispositivos corren en el llamado anillo 0 de Windows, que es el de mayor nivel de privilegio y desde el cual sí se puede tener acceso al hardware. Incluso, para que el lector tenga una idea de hasta donde llega esto le diré que más o menos la mitad de la RAM de su PC la usa en sistema para guardar los datos que necesita y a ella las aplicaciones no pueden acceder, es una porción de la RAM de modo Kernel, lo que usted escribe en el Word antes de salvar no se almacena allí. Ahora bien, se había dicho que todas las aplicaciones tienen que llamar al driver correspondiente pero esa llamada no es directa, o sea la aplicación no puede llamar directamente al driver sino que la llamada tiene que pasar a través de todo el subsistema de I/O, dentro del subsistema hay un programa llamado Administrador de I/O (I/O manager) que es el encargado de recibir la llamada, determinar a que driver se esta llamando y enviarle la llamada en forma de IRP. ¿Qué es una IRP? IRP son las siglas en ingles de Paquete de Petición de Entrada/Salida (I/O Request Packet) y es un tipo de dato que crea el I/O manager. El lector podrá encontrar más detalles en las páginas siguientes. 3.2 Componentes de Windows 2000. Es de vital importancia entender los conceptos que se van a manejar a continuación para todo aquel que desee adentrarse en el mundo de la programación de drivers. Ya se explicó que es modo Kernel y qué modo usuario, ese era el primer paso ahora vamos a seguir con mostrar a grandes rasgos la estructura del sistema operativo Windows 2000, para una vez vista poder hablar del subsistema de entrada / salida, que es en definitiva lo más importante ahora. Es importante familiarizarse con los conceptos que se van a explicar, de modo que si en su momento no entendió algo vuelva a repasarlo pero no pase a las páginas siguientes sin haber entendido, aunque sea más o menos ninguno de los conceptos que se explicarán. 3.2.1 La API Win32. API significa Application Programming Interface. y es la interfase primaria de programación en la familia de sistemas operativos Microsoft Windows, incluyendo a Windows 2000, Windows 95, Windows 98, Windows Millenium Edition y Windows CE. Para ir al grano: las funciones API se usan para llamar desde las aplicaciones los diferentes servicios del sistema operativo, ya que las aplicaciones no pueden hacerlo directamente. La API Win32 no va ser descrita completamente en este trabajo, o sea no voy a explicar el comportamiento interno y la implementación de las funciones API Win32. Si quiere profundizar sobre este tema le recomiendo que lea el libro Programming Applications for Microsoft Windows, de Jeffrey Richter (cuarta edición, Microsoft Press, 1999). Cada sistema operativo implementa un subconjunto diferente de Win32. Windows 2000 es un superconjunto de todas las implementaciones de Win32. Si desea conocer las especificidades de qué servicios son implementados y en qué plataformas le invito a que consulte la documentación disponible en el sitio 7 www.msdn.microsoft.com Para el propósito de este trabajo API Win32 se refiere al conjunto base que cubre áreas como procesos, servicios, hilos, administración de memoria, seguridad, entrada / salida etc. 7 La información de esta documentación está detallada en el fichero \Program Files\Microsoft Platform SDK\Lib\Win32api.csv instalado como parte de de la plataforma SDK, la cual viene con el MSDN Profesional o puede bajarse gratis de www.msdn.microsoft.com Aunque Windows 2000 fue diseñado para soportar múltiples interfases de programación la API Win32 es la primaria, la preferida. La Win32 tiene esta posición porque, de los tres ambientes de subsistemas (Win32, POSIX y OS/2), es la que brinda el mayor acceso a los servicios de Windows 2000. Las API se usan para llamar estos servicios porque ninguna aplicación puede llamarlos directamente. La API Win32, originalmente no iba a ser la interfase de programación original de Windows NT. Como el proyecto de Windows NT comenzó como para sustituir la API OS/2, la interfase primaria de Windows NT iba a ser la API OS/2 Presentation Manager. Pero luego de un año de trabajo, Windows 3.0 entró al mercado y tuvo éxito. Como resultado, Microsoft cambió la dirección e hizo de Windows NT el futuro reemplazo para la familia de productos . Fue en esta coyuntura que se hizo patente la necesidad de especificar la API Win32, antes de esto ésta sólo existía en una versión de 16 bits.[4] La API Win32 introdujo muchas funciones que no estaban disponibles en Windows 3.1, Microsoft decidió hacer una nueva API compatible con los nombres de las funciones de 16 bits. 3.2.2 Servicios, Funciones y Rutinas. Son varios los términos que en las documentaciones para programación y usuarios de Windows 2000 tienen distintos significados en distintos contextos. Por ejemplo, la palabra servicio puede referirse a una rutina llamable del sistema operativo, a un driver, o a un proceso del servidor. Para evitar confusiones, la siguiente lista muestra lo que significan distintos términos que se van a usar a lo largo de este trabajo. • Funciones API Win32. Son subrutinas llamables y documentadas en la API Win32. Por ejemplo CreateProcess, CreateFile y GetMessage . • Servicios del sistema (o servicios ejecutivos del sistema). Son funciones nativas en el sistema operativo Windows 2000 que se pueden llamar desde modo usuario. Por ejemplo, NtCreateProcess, que es la función del ejecutivo del sistema que llama la función API CreateProcess para crear un nuevo proceso. • Funciones del Kernel. Subrutinas de la parte de modo Kernel de Windows 2000. Por ejemplo, ExAllocatePool que es la rutina que los drivers llaman par asignar memoria. • Servicios Win32. Procesos iniciados por el Administrador de Servicios de Windows 2000. Por ejemplo el servicio Task Scheduler es un proceso de modo usuario que soporta el comando at (el cual es similar a los comandos at o cron de UNÍX). • DLL (Dynamic Link Library). Un conjunto de subrutinas enlazadas entre ellas como un fichero binario que puede cargarse dinámicamente por aplicaciones que usen esas subrutinas. Por ejemplo, Msvcrt.dll y Kernel32.dll (una de las del subsistema Win32). Las aplicaciones y componentes de modo usuario de Windows 2000 usan continuamente DLL. La ventaja de usar DLL es que las aplicaciones pueden compartir las DLL, o sea, cuando dos aplicaciones llaman a la misma DLL a la misma vez no tiene que reservarse la misma cantidad de memoria dos veces, lo cual es un desperdicio. 3.2.3 Procesos, Hilos y Trabajos. Aunque programas y procesos parecen lo mismo vistos desde la superficie, son fundamentalmente diferentes. Un programa es una secuencia estática de instrucciones, mientras que un proceso es un contenedor de un conjunto de recursos usados por los hilos que ejecutan la instancia del programa. En el mayor nivel de abstracción: un proceso de Windows 2000 contiene lo siguiente: 1 Un espacio virtual de direcciones privado, lo cual es un conjunto de direcciones de memoria que el proceso puede usar. 2 Un programa ejecutable, el cual define el código inicial y datos que son mapeados al espacio virtual de direcciones del proceso. 3 Una lista de handles abiertos a varios recursos del sistema, como semáforos, puertos de comunicación, y ficheros, que son accesibles a todos los hilos en el proceso. 4 Un contexto de seguridad llamado un access token que identifica al usuario, grupos de seguridad y privilegios asociados al proceso. 5 Un identificador único llamado el ID del proceso. 6 Y, al menos un hilo en ejecución. Un hilo es una entidad en un proceso que Windows 2000 . Sin ellos, el proceso del programa no puede ejecutarse. Un hilo incluye los siguientes componentes esenciales: 7 El contenido de los registros de la CPU que representan el estado del procesador. 8 Dos pilas, una para mientras el hilo se ejecuta en modo Kernel y otra para cuando se ejecuta en modo usuario. 9 Un área de almacenamiento privada llamada TLS (thread – local storage) para el uso por subsistemas, bibliotecas de tiempo de corrida y DLL. 10 Un identificador único llamado ID del hilo. 11 Los hilos, a veces, tienen su propio contexto de seguridad que es a menudo usado por aplicaciones multihilo. Los registros, las pilas y las áreas de almacenamiento privadas se conocen como el contexto del hilo. Ya que esta información es distinta en cada arquitectura de máquina en que Windows 2000 corre, esta estructura es específica para cada arquitectura. De hecho, la estructura del contexto devuelta por la función API Win32 GetThreadContext es la única estructura de datos en la API Win32 que es específica de cada arquitectura. Aunque los hilos tienen su propio contexto de ejecución, cada hilo en un proceso comparte el espacio virtual de direcciones del proceso, lo cual significa que los hilos de un mismo proceso pueden leer o escribir en la memoria de unos y otros. Los hilos no pueden referirse al espacio de memoria de los hilos de otro proceso, a menos que los otros procesos hagan disponible su espacio de direcciones compartiéndolo. Además de un espacio de direcciones privado y uno o varios hilos los procesos tienen una identificación de seguridad y una lista de handles8 abiertos a objectos tales como ficheros, espacios de memoria compartida, uno o más objetos de sincronización como mutexes, eventos, o semáforos como se ilustra en la figura: 8 Los handles se explicarán más adelante. Figura 3.1 Cada proceso tiene su propio contexto de seguridad, que es almacenado en un objeto llamado access token , que contiene la identificación y credenciales del proceso. El descriptor de direcciones virtuales (VAD) son estructuras de datos que el administrador de memoria usa para mantener la huella de las direcciones virtuales que el proceso está usando. Windows 2000 introduce una extensión del modelo de procesos llamado trabajos. La función principal de un trabajo es permitir que un grupo de procesos sea administrado y manipulado como una unidad. También guarda información básica para todos los procesos asociados con un trabajo y para todos los procesos que estuvieron asociados al trabajo, pero que ya terminaron. 3.2.4 Memoria Virtual. Windows 2000 implementa un sistema de memoria virtual basado en direcciones de 32 bits, lo cual se traduce en 4 GB de memoria virtual. En la mayoría de los sistemas de Windows 2000 la mitad inferior de este espacio (desde x00000000 hasta x7FFFFFFF) para el usuario, y la mitad superior (desde x80000000 hasta xFFFFFFFF) para el sistema. La figura siguiente muestra lo dicho: Figura 3.2 Espacios de memoria implementados por Windows 2000 Otras versiones de Windows 2000 como Windows 2000 Advanced Server y Windows 2000 Datacenter Server tienen una opción que le brinda a los procesos del modo usuario 3 GB de memoria. Sin embargo, 3 GB aún no es suficiente para cuando se va trabajar con bases de datos muy grandes. Windows 2000 tiene un nuevo mecanismo conocido como AWE9, el cual permite a una aplicación de 32 bits asignar más de 64 GB de memoria virtual y luego mapear vistas, o ventanas en su espacio de memoria de 2 GB. Aunque el AWE da una solución al problema de la memoria el lector seguramente se habrá dado cuenta de que con el tiempo las aplicaciones tienen a ocupar más espacio en el disco duro y la almacenar más datos en la memoria, por lo tanto la solución a largo (o mediano) plazo es el espacio de direcciones de 64 bits.[4] Recordemos que el espacio de memoria virtual de los procesos es un espacio de direcciones disponibles para los hilos de los procesos. La memoria virtual brinda una vista lógica de la memoria, que puede no corresponder con la realidad física. En tiempo de corrida el administrador de la memoria, junto con el hardware, traduce o mapea las direcciones virtuales en direcciones físicas, donde los datos son almacenados realmente. Controlando los mapeos y protegiendo su espacio de 9 Address Windowing Extensions. direcciones el sistema operativo se asegura de que los espacios virtuales de direcciones de los procesos individuales no se solapen y no sobrescriban el espacio del sistema. La figura ilustra el mapeo de tras espacios de direcciones virtuales contiguos a direcciones físicas. 3.2.5 Objetos y Handles. En Windows 2000 un objeto es una instancia de tiempo de corrida a un tipo de objeto definido estáticamente. Un tipo objeto comprende un tipo de dato definido por el sistema, que tiene funciones que operan en las instancias del objeto, y un conjunto de atributos. Si usted a hecho aplicaciones de Win32, usted habrá encontrado procesos, hilos, ficheros y eventos, todos estos son objetos, por poner un ejemplo. Estos objetos se basan en objetos de bajo nivel que Windows 2000 crea y administra. En Windows 2000 un proceso cualquiera es una instancia del objeto proceso, un hilo, una instancia del objeto hilo y así todos los componentes del sistema. Un atributo de un atributo de un objeto es un campo de datos que define parcialmente el estado del objeto. Por ejemplo, en un objeto proceso un atributo es el ID del proceso. Los métodos del objeto son, son los medios para manipular al objeto, que usualmente es cambiar los valores de sus atributos. Por ejemplo, el método open en un proceso podría aceptar un identificador para el proceso como entrada y devolver un puntero al objeto. Figura 3.3 Mapeo de memoria virtud a memoria f’isica en Windows 2000. La diferencia fundamental entre un objeto y cualquier otro tipo de estructura de dato es que la estructura interna de un objeto está oculta, para obtener datos del objeto o entrarlos en él hay que llamar un servicio del objeto. No se puede leer o cambiar los datos que hay dentro del objeto. Pero, a pesar de el lector pueda, quizás, pensar que los objetos son muy complicados por gusto, los objetos brindan los medios más convenientes de lograr las tres importantes tareas del sistema operativo, que son: 4 Brindar nombres entendibles para la persona de los recursos del sistema. 5 Compartir recursos y datos entre los procesos. 6 Proteger los recursos de entradas no autorizadas. No todos los datos en Windows 2000 son objetos, sólo aquellos que necesitan ser compartidos, protegidos, nombrados o hacer visibles para los programas de modo usuario. 3.2.6 El Registro. Si usted ha trabajado bastante en Windows 2000 seguramente ha oído hablar del registro. No se puede hablar mucho de las interioridades de Windows 2000 sin hablar del registro. Él es la base de datos del sistema, donde se almacena la información necesaria para arrancar y configurar el sistema, configuraciones de software, información de la seguridad y la información de la configuración de cada usuario. Aunque la mayoría de los administradores y usuarios de Windows 2000 nunca necesitan ver dentro del registro, de todas maneras es una poderosa fuente de información sobre las interioridades de Windows 2000 porque contiene muchas configuraciones que afectan el desempeño del sistema. Así que, si se decide a cambiar directamente las configuraciones del registro tenga extrema cautela porque si se equivoca puede tener consecuencias fatales. Para más información sobre las claves del registro le recomiendo el libro Inside Windows 2000, capítulo 5. 3.2.7 Vista, a grandes rasgos de la Arquitectura del Sistema Operativo Windows 2000. Ahora, es importante dar una idea de la arquitectura del sistema operativo, es más fácil con una figura. Tenga en cuenta que este diagrama es muy básico, no lo muestra todo. En la figura, primero observe la línea que divide los modos usuario y Kernel. Los cuadros de arriba representan los procesos de modo usuario y los de abajo servicios de modo Kernel. Los cuatro tipos básicos de procesos de modo usuario son: 1 System support proceses. Son, por ejemplo loguearse, etc, pero estos aún no son servicios de Windows 2000. 2 Aplicaciones. Las cuales pueden ser de cinco tipos: Win32, Windows3.1, MSDOS, POSIX o OS/2 1.2. 3 Subsistema de ambientes (Environment Subsystem), que expone los servicios nativos de Windows 2000 a las aplicaciones de modo usuario a través de funciones. 4 Servicios a procesos, Figura 3.4 Vista previa de la arquitectura de Windows 2000. Vea que en la figura hay un recuadro que dice ``Subsystem DLLs´´ debajo de ``Service proceses`` y de ``User Applications`` y es que en Windows 2000 las aplicaciones no llaman directamente a los servicios nativos del sistema, la petición tiene que ir a través de una o varias DLLs de subsistema. El papel que juegan estas DLLs es traducir una función documentada en una llamada a un servicio de Windows 2000, esta traducción puede o no involucrar enviar un mensaje al proceso del subsistema que está sirviendo la aplicación. Los componentes de modo Kernel en Windows 2000 incluyen los siguientes: 1 El Ejecutivo de Windows 2000 contiene los servicios básicos del sistema operativo, tales como administración de memoria, seguridad, administración de hilos y procesos, I/O, y comunicación interprocesos. 2 El Kernel de Windows 2000 consiste de funciones del sistema operativo de bajo nivel, tales como despacho de interrupciones y excepciones, sincronización multiprocesos. También brinda un grupo de rutinas y objetos básicos que los demás componentes ejecutivos usan para implementar constructores de más alto nivel. 3 Los manipuladores de dispositivos (device drivers), que incluye los drivers para manipular hardware y los que traducen las llamadas a funciones de I/O del usuario en dispositivos de hardware específicos. 4 La Hardware Abstraction Layer (HAL) 10 , que es una capa de código que ayuda al sistema a aislar al Kernel, Device Drivers,y al resto de los componentes ejecutivos de Windows 2000 de las diferencias entre las diferentes plataformas de hardware en que puede correr el sistema (diferencias entre las motherboards). 5 El Sistema de Ventanas y Gráficos (Windowing and Graphics System) que implementa la interfase gráfica del usuario (GUI11). La siguiente tabla muestra los ficheros del núcleo del sistema operativo Windows 2000. Nombre Componentes Ntoskrnl.exe Ejecutivo y Kernel Ntkmlpa.exe Ejecutivo y Kernel con soporte para Physical Address Extensión PAE, el cual permite direccionar más de 64 GB de memoria física. Hal.dll Hardware Abstaction Layer. Win32k.sys Parte de modo Kernel del subsistema Win32. Ntdll.dll Kernel32.dll, User32.dll, Gdi32.dll Funciones del soporte interno. Advapi32.dll, DLLs del núcleo del subsistema Win32. Tabla 3.1: Ficheros de los componentes del núcleo de Windows 2000. Antes de continuar le recomiendo al lector que observe con detenimiento la figura siguiente. En ella se muestra en detalle la arquitectura de Windows 2000. En ella usted podrá ver los componentes que se van a tratar a continuación, los del subsistema de entrada / salida. En este trabajo no se va explicar todo el sistema porque ello nos alejaría del tema principal, pero el subsistema de I/O sí será tratado con detenimiento en este mismo capítulo. 10 11 A lo largo de todo el trabajo me referiré a la Hardware Abstraction Layer como HAL. Graphical User Interface. Figura 3.5 Arquitectura de Windows 2000. 3.3 Componentes del Subsistema de Entrada / Salida. Bueno, por fin vamos a entrar en algo más interesante, ¿está listo? Yo creo que sí. Pues bien, el subsistema de I/O de Windows 2000 consiste de varios componentes ejecutivos como, por ejemplo los device drivers, los cuales se muestran en la figura siguiente. Figura 3.6 Componentes del subsistema de entrada / salida de Windows 2000. 1 El Administrador de I/O (I/O manager) conecta las aplicaciones y los componentes del sistema a los dispositivos físicos, virtuales y lógicos, y define la infraestructura que soporta los dispositivos. 2 Un device driver típicamente provee una interfase para un tipo particular de dispositivo. Los drivers reciben comandos enlutados a él por el I/O manager para los dispositivos que maneja, e informa al I/O manager cuando se han cumplido esos comandos u ordenes. Los device drivers también usan al I/O manager para enviar comandos a otros device drivers cuando la atención al hardware necesita varios drivers. Un ejemplo de esto se vera mas tarde. 3 El Administrador de PnP trabaja en cooperación con el I/O manager y con un tipo de drivers llamados bus drivers para guiar la localización de recursos de hardware así como para detectar y responder por la llegada o remoción de los recursos de hardware. El Administrador de PnP y los bus drivers son responsables de cargar un device driver cuando un dispositivo de hardware es detectado. 4 El Administrador de energía (Power Manager) también trabaja en cooperación con el I/O manager para guiar al sistema así como a los dispositivos individuales a trabes de las transiciones entre estados de encendido. 5 El registro sirve como una base de datos que almacena la descripción de los dispositivos de hardware conectados al sistema, así como la inicialización de los drivers y la configuración de ellos. 6 Los ficheros INF, que son llamados con la extensión .inf son los ficheros de la instalación de los drivers. Los archivos .inf son vínculos entre un dispositivo de hardware particular y un driver que asume el control del dispositivo. Ellos son hechos con instrucciones que describen al dispositivo al cual corresponden, las localizaciones fuente y 7 La Capa de Abstracción de Hardware (Hardware Abstraction Layer o HAL) aísla los drivers de las especificidades del procesador y del controlador de interrupciones proveyendo funciones API que ´´ esconden ´´ las diferencias entre las distintas plataformas. La mayoría de las operaciones no involucran a todos estos componentes. En las páginas siguientes vamos a explicar la función de estos componentes con más detalle. 3.4 El Administrador de Entrada / Salida (I/O Manager). El Administrador de I/O define un modelo dentro del cual las peticiones de I/O se cumplen. Es un componente de modo Kernel, o sea, que funciona en modo Kernel, para el usuario es inaccesible. Veamos que hace este componente. Había dicho que cuando una aplicación llama a un driver lo hace a través del administrador de I/O y que este crea una IRP y la envía al driver correspondiente. Pues eso precisamente lo que hace. El I/O manager crea una IRP, la cual representa una operación de entrada / salida (porque todas no son iguales), pasándole un apuntador a la IRP del driver correspondiente y recibiendo a la IRP cuando la solicitud ha sido procesada por el driver. El driver, a su vez recibe a la IRP y puede procesarla inmediatamente, pero también puede colocarla un una cola hasta que este libre. Además de crear IRPs, el administrador de I/O provee códigos que son comunes a diferentes drivers y que el driver llama para procesar las IRPs. De esa forma los drivers se hacen más compactos y simples. Ejemplo de esto es una función que provee el administrador que hace que un driver sea capaz de llamar a otro. El Administrador de I/O también administra los buffers necesarios para la comunicación entre las aplicaciones y los drivers, entre los anillos 3 y 0. 3.5 Los Device Drivers. Tal vez el lector pueda pensar que hay un solo tipo de driver pero no es así. Los drivers son en esencia lo mismo, es cierto, pero hay diferencias entre ellos dadas por la función que deben realizar. Algunos drivers manejan tarjetas conectadas al bus ISA, otros PCI, IEEE1394, USB etc. Otros simplemente no controlan hardware en lo absoluto. Sin embargo todos tienen en común que son programas de modo Kernel. Como un comentario interesante diré que en Windows 2000, XP, 2003 Server etc estos tienen extensión .sys y en Windows 95 y 98 .VxD. A continuación voy a tratar de explicar las especificidades de cada uno: 1 Drivers para ficheros del sistema. Aceptan IRPs a ficheros (files) y las satisfacen almacenando o leyendo datos de localizaciones de memoria del sistema. 2 Drivers de Windows 2000. Son drivers que integran con el Administrador de Energía (Power Manager), y el PnP Manager cuando es necesario. En este grupo se incluyen drivers para almacenamiento de datos, drivers para adaptadores etc. 3 Legacy drivers. Son drivers hechos para Windows NT pero que pueden correr en Windows 2000. Se diferencian de otros drivers de Windows 2000 en que no soportan administración de energía ni trabajan con el administrador de PnP de Windows 2000. Si el driver controla un dispositivo de hardware podría limitar las capacidades de administración de energía y de PnP del sistema. 4 Display drivers. 5 WDM drivers. Son drivers que usan el Windows Driver Model (WDM). El WDM incluye soporte para al administrador de energía y de PnP y WMI de Windows 2000. WDM esta implementado en Windows 2000, Windows 98, y Windows Millenium, de modo que los drivers WDM son compatibles entre esos sistemas operativos. Hay tres tipos de drivers WDM: Bus drivers: Manejan un bus lógico o físico. Ejemplo de estos buses son ISA, PCI, USB, IEEE 1394. Un bus driver es responsable de detectar e informar al administrador de PnP de los dispositivos conectados al bus que el controla así como de administrar las configuraciones de la energía del bus. Función drivers: administran un tipo particular de dispositivo. Los bus drivers presentan dispositivos a los function drivers a través del administrador de PnP. Los function drivers son los drivers que exportan la interfase operacional de los dispositivos al sistema operativo. En general, son los drivers con más conocimiento sobre la operación del dispositivo.[4] En WDM, ningún driver es responsable de controlar todos los aspectos de un dispositivo en particular. El bus driver es responsable de detectar los cambios en el bus. 3.6 Estructura de un driver. Para poder entender el por qué la estructuras del los drivers es así hay que tener presente que es el Administrador de I/O el que administra la ejecución de los drivers. Los drivers consisten de un conjunto de subrutinas que son llamadas para procesar las varias etapas de una petición de I/O. La figura siguiente ilustra la función de estas subrutinas. Figura 3.7 Estructura de un device driver. 1 La subrutina de inicialización la ejecuta el I/O manager cuando carga el driver en el sistema operativo. Esta subrutina llena en el sistema estructuras de datos para registrar el resto de las subrutinas del driver con el I/O manager y realiza todas las inicializaciones globales que sean necesarias. 2 Todos los drivers que soportan Plug and Play (PnP) tienen una rutina Add Device. A través de ella el administrador de PnP envía al driver una notificación cada vez que ha detectado un dispositivo del cual el driver es responsable. En ella típicamente el drive crea un Objeto Dispositivo (Device Object)12 el cual representa al dispositivo, los Device Objects se describirán más adelante. 3 Las subrutinas de despacho son las más importantes de todas entre las que un device driver provee. Ejemplos de ellas son Device Control, Open, Close, Read, Write. Cuando se llama una de ellas el I/O manager crea una IRP con una Major Function13 correspondiente a una subrutina de despacho. 4 La Start I/O: cuando los drivers reciben IRPs de varias aplicaciones y, por tanto, probablemente reciba una antes de haber terminado de procesar la 12 13 A partir de aquí me voy a referir a los Objetos dispositivos como Device Objects. Uno de los campos de una IRP. Se profundizara mas adelante. anterior, las coloca en una cola, para procesarla una a una. Cuando sucede esto los device drivers tienen una subrutina Start I/O que es la que procesa la IRP, las subrutinas de despacho simplemente reciben las IRPs y las ponen en cola para que sean procesadas posteriormente por la Start I/O. Puede darse el caso de que hayan mas de una Start I/O, una sola, o no haya ninguna. 5 Una subrutina de servicio a interrupción (ISR)14 que atienden las interrupciones asociadas al dispositivo que controla el driver. Cuando se produce una interrupción el Despachador de Interrupciones del Kernel transfiere el control a esta rutina. En Windows 2000 las ISR corren en DIRQL15 por tanto en ellas se debe programar o menos posible para lograr que sean pequeñas y por tanto su ejecución sea rápida y no bloqueen a las interrupciones de menor de menor nivel. Las ISR normalmente solo limpian el vector de interrupciones y ponen en cola a una DPC que corre a un nivel menor y son las que en definitiva hacen la atención a la interrupción. 6 DPCs. Las DPCs realizan la mayor parte de la atención a interrupciones. Corren a un nivel menor y, por tanto, no bloquean las otras rutinas innecesariamente. Las siguientes rutinas, aunque no vienen en la figura, aparecen muchas veces en los device drivers por lo que no pueden ser ignoradas. 7 Una, o varias rutinas de terminación de I/O. Estas rutinas son necesarias, por ejemplo en el caso de drivers que trabajan en capas (layered drivers), en este caso un device driver tiene esta subrutina para ser notificado por otro driver, que trabaja asociado a el, de que ha terminado de procesar la IRP. 8 Subrutina de cancelación de la IRP (Cancel I/O Routine). Si una operación de I/O debe ser cancelada el driver define una o mas subrutinas de cancelacion de IRP. 9 La subrutina de descarga (Unload Routine), mediante la cual el driver libera todos los recursos del sistema que se reservo durante la subrutina de inicialización. Un driver puede ser cargado y descargado mientras el sistema esta corriendo. 14 15 Interrupt Service Rutine. Device Interrupt Request Level. 10 na subrutina de notificación de shut down. Esta subrutina prepara al driver para limpiarse durante el apagado del sistema. 11 na subrutina de notificación de errores. Esta subrutina se usa para que cuando se han detectado errores inesperados, por ejemplo que un disco haya fallado, el driver pueda notificar al I/O manager. 3.7 El Administrador de Plug and Play (PnP). El Administrador de PnP es el principal componente del sistema involucrado en la tarea de reconocer y adaptar al sistema a los cambios en la configuración del hardware. Es el Administrador de PnP el que habilita a una PC a reconocer dispositivos conectados a ella, por ejemplo: una impresora. El Administrador de PnP reconoce automáticamente los dispositivos conectados, este es un proceso que incluye la enumeración de los dispositivos durante la arrancada del sistema. También detecta la adición o retirada de ellos mientras el sistema corre. Otra función que cumple el administrador de PnP es la asignación de recursos de hardware. Ello consiste en reunir los requerimientos de cada uno de los dispositivos asociados al sistema (interrupciones, rangos de memoria, registros de I/O, o recursos específicos de cada bus) y, en un proceso llamado arbitración de recursos asignarlos a cada uno de los dispositivos para que cada uno pueda satisfacer sus requerimientos para una correcta operación. Puede suceder que un dispositivo de hardware se conecte al sistema después de que el sistema haya despertado, en ese caso el administrador de PnP debe ser capaz de reasignar los recursos y acomodar los dispositivos para que cada uno pueda funcionar correctamente. El administrador de PnP también es responsable de detectar los drivers adecuados para cada dispositivo basado en la identificación de dispositivo, cuando ha detectado un driver capaz de manejar al dispositivo instruye al administrador de I/O para que este lo cargue. Si no encuentra un driver correcto, el administrador de PnP de modo Kernel se comunica con el administrador de PnP de modo usuario para que, con la ayuda del usuario encontrar un driver adecuado y cargarlo. Los niveles de Administrador de PnP que Windows 2000 brinda dependen de los dispositivos e hardware y de los drivers cargados. Un dispositivo que puede no soportar PnP pudiera ser una tarjeta de sonido ISA ya que no tiene detección automática. Como el sistema operativo no sabe como es físicamente la tarjeta ciertas facilidades como hibernación estarán deshabilitadas. Para soportar PnP un device driver debe implementar una subrutina Add Device y una subrutina de despacho de PnP. Los bus drivers deben soportar diferentes tipos de PnP, mas que los functions o filter drivers. Por ejemplo, cuando el Administrador de PnP esta guiando la enumeración de los de los dispositivos durante la arrancada del sistema (que se describirá en detalle mas adelante) el le pregunta a los bus drivers por una descripción de los dispositivos conectados a sus respectivos buses. Esta descripción incluye datos, que son únicos de cada dispositivo y que los identifican, así como los recursos necesarios para el dispositivo. El Administrador de PnP toma esta información y carga cualquier function o filter driver que sea necesario para el bus driver y que haya sido instalado para el dispositivo especifico. Entonces llama a la subrutina Add-Device de cada driver responsable de cada dispositivo. Los function y filter drivers son preparados para administrar sus dispositivos en sus subrutinas Add-Device pero no entrar en contacto con el dispositivo de hardware. Ellos esperan por el Administrador de PnP para enviar un comando Start-Device para el dispositivo. El comando Start-Device incluye la asignación de recursos que el Administrador de PnP determina durante la arbitración de recursos. Cuando un driver recibe un comando Start-Device puede configurar a su dispositivo para usar sus recursos específicos. Después de que el dispositivo ha arrancado el Administrador de PnP puede enviar comandos de PnP adicionales, incluso aquellos relacionados con la remoción del dispositivo o la reasignación de recursos. Por ejemplo, cuando el usuario ejecuta el Remove/Eject utility para decirle a Windows 2000 que remueva una tarjeta PCMCIA, el Administrador de PnP envía una notificación query remove a cualquier aplicación que haya registrado para notificaciones al dispositivo. Las aplicaciones típicamente registran para notificaciones en esos handles. Si ninguna aplicación veta la notificación el Administrador de PnP envia la notificación al driver que administra al dispositivo. En ese momento el driver puede denegar la remoción o asegurarse de que no haya IRPs pendientes. Si no obstáculos para la remoción en Administrador de PnP envía un comando Remove al driver. Cuando el Administrador de PnP necesita reasignar los recursos de hardware primero pregunta al driver si puede suspender actividad extensa temporalmente en el dispositivo enviándole un orden de query-stop. Si el driver acepta no se produce corrupción de los datos, o puede denegar la petición entonces termina las IRPs pendientes y no procesa mas ninguna. El driver típicamente pone en cola de modo que la asi de modo que la asignación de recursos es transparente para las aplicaciones que continuamente están accediendo al dispositivo. Las ordenes esencialmente guían a un dispositivo a través de varios estados de operación que forman una tabla de transiciones bien definida la cual se muestra a continuación: . Figura 3.8 Transiciones entre estados En la figura se muestra un estado que no ha sido comentado, se trata de surpriseremoval. Esta orden resulta cuando el usuario retira un dispositivo sin advertencia alguna, tambien cuando el usuario retira una tarjeta PCMCIA sin usar el Remove/Eject , o cuando simplemente el dispositivo falla. Esta orden le dice al driver que cese inmediatamente toda interacción con el dispositivo y cancele todas las IRPs pendientes porque este ya no esta conectado al sistema. 3.8 El Administrador de Energía (Power Manager). El Administrador de Energía es uno de los componentes de Windows 2000 mas importantes. De la misma manera que el Plug and Play de Windows 2000 necesita soporte del hardware, sus capacidades de administración de la energía necesitan hardware que cumpla con las especificaciones de Configuración Avanzada e Interfase de Energía (Advanced Configuration and Power Interface, ACPI)16. Como resultado de estos requerimientos el BIOS de la computadora (Basic Input Output System), que es el codigo que corre cuando es encendida, tiene que estar conforme tambien con la norma ACPI. La mayoria de las computadoras con CPU x86 fabricadas desde 1998 son compatibles con ACPI17. La norma ACPI define varios niveles de consumo de energia para un sistema y para dispositivos. Los seis niveles son descritos en la tabla siguiente. Estos estados son conocidos desde S0 (completamente encendido, o trabajando), hasta S5 (completamente apagado, o durmiendo). Cada estado tiene las siguientes características: 4 Consumo de energía. 5 Resumen del software. 6 Latencia del hardware, Estado S0 Consumo de Resumen del Latencia del energía. software hardware Máximo. No aplicable Ninguno Menos que S0, Sistema Menos mas que S2 despierta segundos. Menos que S1, stema despierta 2 (completamente encendido) S1(durmiendo) S2 (durmiendo) mas de S3 S3 (durmiendo) S4 (hibernando) 16 que o 2 mas segundos Menos que S2, Sistema mas de S4 despierta Igual que S2 Sistema reinicia Largo de hibernación y indefinido e Ir a www.teleport.com/acpi-/spec.htm Algunas computadoras, especialmente aquellas de hace unos años no cumplian con la norma ACPI. Sin embargo si cumplian con la norma APM. Windows 2000 brinda un soporte limitado para los sistemas APM. 17 resume cuando S5 Largo (completamente indefinido e apagado) Tabla 3.2 Estados de Consumo de Energia. Los estados de S1 a S4 son estados en que el sistema esta ´´durmiendo´´, en los cuales la computadora parece apagada debido al bajo consumo de energia. Sin embargo retiene suficiente información, lo mismo en la RAM que en el disco, para moverse hasta el estado S0. Para los estados de S0 a S3, se requiere cierta cantidad e energia para preservar el contenido de la memoria de modo que cuando se produce la transición a S0, el Administrador de Energia continua corriendo alli donde se quedo antes de la suspensión. Cuando el sistema se mueve a S4, el Administrador de Energia salva el contenido de la memoria a un fichero de hibernación llamado Hiberfile.sys, el cual es lo suficientemente grande para guardar el contenido sin comprimir de la memoria. Después de salvar el contenido de la memoria el Administrador de Energia apaga la computadora. Si el fichero de hibernación contiene el estado del sistema, Ntldr lee el contenido del fichero a la memoria. La computadora nunca hace transiciones directas entre los estados S1 y S4, debe moverse al estado S0 primero. Como se ilustra en la figura siguiente, cuando el sistema desde cualquier estado S1 a S5 al estado S0 se dice que esta despertando, y cuando la transición es del estado S0 a cualquier estado de S1 a S5 esta durmiendo. Aunque la computadora puede estar en cualquiera de los seis estados mencionados la norma ACPI define para los dispositivos cuatro estados, D0 a D3. El estado D0 es completamente encendido y el estado D3 es completamente apagado.La norma ACPI deja que cada uno de los drivers defina los estados D1 y D2, pero el estado D1 debe consumir mas energia que el D2. Microsoft, en colaboración con OEMs, h definido una serie de especificaciones de administración e referencia (disponible en www.microsoft.com/hwdev/specs/pmref) que especifica los estados de energia que se requieren para todos los dispositivos de una clase particular. Para algunos dispositivos no hay estados intermedios entre D0 y D3. La política de administración en Windows 2000 esta compartida entre la administración por parte del sistema y los drivers individuales. El Administrador de Energia es el elemento principal en la administración de la energia en todo el sistema, aunque los drivers pueden administrar el consumo de energía de sus dispositivos. El Administrador de Energía decide que estado es necesario en cada momento, cuando se requiere ``dormir´´ y cuando una hibernación. El instruye a los drivers capaces de manejar el consumo de energía de sus dispositivos para hacer las transiciones de energía apropiadas. Para decidir cuando es necesaria una transición de estado, el Administrador de Energía toma en cuenta una serie de factores, tales como, 1. El nivel de actividad del sistema. 2. El estado de carga de las baterías. 3. Las peticiones de shut down, hibernación o dormir de las aplicaciones. 4. Las acciones del usuario, como, por ejemplo, si oprime el botón power. 5. Las configuraciones del Panel de Control. Cuando el Administrador de PnP realiza la enumeración de los dispositivos, parte de la información que recibe de los dispositivos es sus capacidades de manejar su energia. Un driver reporta cuando en su dispositivo no están definidos los estados D1 y D2, la latencia, el tiempo requerido para moverse de los estados del D1 y D3 al D0. Los bus drivers también devuelven una tabla que implementa un mapeo entre los diferentes estados del sistema y los estados que el dispositivo soporta. La tabla lista el menor estado posible del dispositivo para cada estado del sistema y refleja el estado de varios planos de energía cuando la máquina duerme o hiberna. Por ejemplo, un bus que soporta los cuatro estados de energía debe devolver una tabla como la mostrada a continuación. Estado del sistema Estado del dispositivo S0 D0 S1 D2 S2 D2 S3 D2 S4 D3 S5 D3 Tabla 3.3 Analogía entre los estados de consumo de energía del sistema y de u dispositivo particular. La mayoría de los drivers mantienen sus dispositivos en D3 (completamente apagados) cuando el sistema deja el estado S0 para evitar el consumo excesivo de energía cuando la máquina no esta en uso. Y, algunos dispositivos, como las tarjetas de red, tienen la capacidad de despertar al sistema, de llevarlo al estado S0. Los dispositivos que tienen esta particularidad lo reportan al Administrador de PnP durante la enumeración de los dispositivos. 3.9 Estructura de los datos de Entrada / Salida. Hay estructuras de datos asociadas a las peticiones de I/O: ficheros objeto (file objects), objetos drivers (driver objects), objetos dispositivo (device objects) y IRPs. Cada una de estas estructuras esta definida en el fichero heather18 del DDK Ntddk.h asi como en la documentación del DDK de Windows 2000. 3.9.1 Ficheros Objeto (File Objects). Los ficheros objeto son los constructores de modo Kernel de handles para dispositivos y drivers. Los ficheros objeto son recursos del sistema que dos o más procesos de modo usuario pueden compartir, pueden tener un nombre, están protegidos por seguridad basada en objetos y soportan sincronización. Aunque la mayoría de los recursos compartidos en Windows 2000 están basados en la memoria, la mayoría de aquellos que el subsistema de I/O administra representan dispositivos físicos o están localizados en dispositivos físicos. A pesar de esta diferencia, los recursos compartidos del subsistema de I/O, como los de otros componentes del ejecutivo de Windows 2000 son tratados como objetos. Los ficheros objeto brindan una representación basada en memoria en la cual se puede leer y escribir. La tabla siguiente muestra algunos de los atributos de los ficheros objeto. 18 Un tipo de fichero del C++ con extensión .h Atributo Propósito Nombre del fichero Identifica el fichero físico al cual el fichero objeto se refiere. Desplazamiento del bytee Identifica la localización actual en el fichero (válido actual sólo para I/O sincrónica). Modo de compartición. Indica si otras aplicaciones pueden abrir el fichero para leer, escribir o borrar operaciones mientras la aplicación actual lo está usando. Banderas del modo Indica si el la operación de I/O será sincrónica o no, abierto escondido o no, secuencial o aleatoria, etc. Apuntador al dispositivo Indica el tipo de dispositivo en el cual reside. objeto Apuntador al Volumee Indica el volumen o partición en el cual el fichero Parameter Block (VPB) reside. Apuntador a la sección Indica la estructura raíz que describe un fichero de punteros objeto. mapeado. Apuntador Identifica qué partes del fichero están compartidas al private cache map por el Cache Manager y donde residen en la cache. Cuando una aplicación abre un fichero o simple dispositivo el I/O manager devuelve un andel al fichero objeto. La siguiente figura ilustra lo que ocurre cuando un fichero es abierto. Figura 3.9 Proceso de apertura de un fichero en Windows 2000. En este ejemplo: 1. Un programa en C llama a una biblioteca de tiempo de corrida fopen , la cual, a su vez 2. Llama a la función de Win32 CreateFile. La DLL del subsistema (en este caso Kernel32.dll) a su vez... 3. Llama a la función NtCreateFile en Ntdll.dll. La rutina en Ntdll.dll contiene la instrucción apropiada para producir el cambio a modo Kernel, al despachador de servicios , el cual a su vez llama a ... 4. La rutina Ntoskrnl.exe. Como otros objetos ejecutivos los ficheros objeto están protegidos por un descriptor de seguridad que contiene la lista de control de acceso (ACL). El I/O Manager consulta al subsistema de seguridad para determinar si el ACL del fichero le permite al proceso acceder al fichero de la forma en que el hilo esta solicitando. Si lo permite (5 y 6) el object manager garantiza el acceso y asocia los derechos de acceso garantizados con el handle que devuelve. Ya que un fichero objeto es una representación basada en memoria de un recurso compartible y no un recurso en sí, es diferente de otros objetos ejecutivos. Un fichero objeto contiene solo datos que son únicos a un handle. Cada vez que un hilo abre un handle a un fichero se crea un nuevo fichero objeto con un nuevo conjunto de atributos. Por ejemplo el desplazamiento del byte actual es un atributo referido a la localización, en el fichero, en la cual la próxima lectura o escritura, con ese handle, va a ocurrir. Un fichero objeto es también único para cada proceso, excepto cuando un proceso duplica un handle de otro proceso (usando la función DuplicateHandle), o cuando un proceso hereda un handle de otro proceso. En ese caso dois procesos tienen handles separados referidos al mismo fichero objeto. 3.9.2 Driver Objects y Objetos Dispositivos (Device Objects). Cuando un hilo abre un fichero objeto, I/O Manager tiene que determinar del nombre del fichero objeto cuál driver (o drivers) debe llamar para procesar la petición. Además el I/O Manager debe ser capaz de encontrar esta información inmediatamente que un hilo use el mismo handle. Los siguientes objetos del sistema satisfacen estas necesidades: 4 El objeto driver (driver object) representa a un driver en particular en el sistema. El I/O Manager obtiene las direcciones de las subrutinas de despacho (entry points) de cada uno de los drivers del objeto driver. 5 El objeto dispositivo (device object) representa un dispositivo lógico o físico en el sistema y describe sus características, así como el alineamiento que requiere para los buffers y la localización de su cola de dispositivos para retener las IRPs que llegan. El I/O Manager crea un objeto driver cada vez que se carga un driver en el sistema, entonces llama la subrutina de inicialización del driver (Driver Entry). Después de cargado, el driver puede crear un objeto dispositivo19 para representar al dispositivo. Sin embargo la mayoría de los drivers de Windows 2000 y WDM crean dispositivos con sus subrutinas Add-Device cuando en Administrador de PnP les informa de la presencia de un dispositivo por el cual deben responder. Los legacy drivers, por otra parte, normalmente crean dispositivos cuando el I/O Manager invoca sus subrutinas de inicialización. El I/O Manager descarga el driver cuando su último device object ha sido borrado y no quedan referencias al dispositivo. 19 A partir de aquí me voy a referir al objeto dispositivo como device object y al objeto driver como driver object. Cuando un driver crea un device object, el driver puede, opcionalmente, asignarle al dispositivo un nombre. El nombre coloca al device object en el espacio de nombres del object manager, y el driver puede, explícitamente definir un nombre o dejar que el I/O Manager autogenere uno. Por convenio los device objects se colocan en el directorio \Device, el cual es inaccesible para las aplicaciones incluso usando API Win32.20 Si un driver necesita hacer que alguna aplicación pueda abrir el device object crea un enlace simbólico en el directorio \?? Los legacy drivers y los drivers que no son orientados al hardware (tales como los drivers de los ficheros del sistema) típicamente crean el enlace simbólico con un nombre bien definido, por ejemplo \Device\Hardware2. Ya que un nombre bien definido no funciona bien en un entorno en el cual el hardware aparece y desaparece dinámicamente, los drivers que soportan Plug and Play exponen una o más interfases llamando la función IoRegisterDeviceInterface, especificando el GUID (Globally Unique Identifier) que representa el tipo de funcionalidad expuesta. Los GUID son números de 128 bits que el usuario puede generar usando una herramienta incluida en el DDK y en la plataforma SDK, llamada Guidgen. Dado que con 128 bits se puede generar una buena cantidad de números es estadísticamente casi imposible que se creen dos GUID iguales para distintos drivers, se puede confiar en que el GUID para cada device object es único. La función IoRegisterDeviceInterface determina el enlace simbólico que está asociado con la instancia al dispositivo; sin embargo, el driver debe llamar a la función IoSetDeviceInterfaceState para habilitar la interfase al dispositivo antes de que el I/O Manager cree el enlace. Los drivers normalmente hacen esto cuando el Administrador de PnP inicia al dispositivo enviándole un comando Start-Device. Una aplicación que desea abrir un device object representado con un GUID puede llamar funciones del setup de PnP de modo usuario, como SetupDiEnumDeviceInterfaces para enumerar las interfases presentes para un GUID y obtener los nombres de los enlaces simbólicos que pueden usarse para abrir los device objects. Para cada dispositivo reportado por IoSetDeviceInterfaceState la aplicación ejecuta la función SetupDiGetDeviceInterfaceDetail para obtener 20 Algunos drivers colocan device objects en otros directorios. Por ejemplo, el Local Disck Manager de Windows 2000 crea device objects que representan particiones del disco en el directorio \Device\HarddisckDm Volumes. información adicional sobre el dispositivo, como el nombre autogenerado. Después de obtener en nombre del dispositivo la aplicación puede ejecutar la función API Win32 CreateFile para abrir el dispositivo y obtener el handle. Cuando se ha abierto el fichero, el nombre incluye el nombre del device object en el cual reside el fichero. Por ejemplo, el nombre \Device\Floppy0\Myfile.dat se refiere al fichero Myfile.dat en el disco floppy. La subcadena \Device\Floppy0 es el nombre del device object interno de Windows 2000 que representa a la torre de A. Cuando se abre Myfile.dat, el I/O Manager crea un fichero objeto que almacena un apuntador al device object Floppy0 y devuelve un handle al llamador. Después de esto, cuando el llamador usa el handle el I/O Manager puede encontrar al device object Floppy0 directamente. Tenga en cuanta que los nombres internos de los dispositivos no pueden usarse en las funciones API Win32 que se llaman en las aplicaciones, el nombre debe aparecer en un directorio especial en el espacio de nombres del object manager , \?? Este directorio contiene enlaces simbólicos a los nombres de los objetos de Windows 2000. Los device drivers son los responsables de crear los enlaces simbólicos en este directorio para que sus dispositivos puedan ser accesibles a través de las funciones API Win32 llamadas en las aplicaciones. Si usted quiere examinar o cambiar estos enlaces simbólicos por programación con la función de Win32 QueryDosDevice y DefineDosDevice. Como se muestra en la figura, un device object apunta a su driver object, que es como el I/O Manager conoce qué subrutina del driver llamar cuando recibe una IRP. Usa el device object para hallar al driver object. Entonces indexa en el driver object usando el código de la IRP, que representa el Entry Point . Un driver object, a menudo, tiene varios device objects asociados. La lista de device objects asociados con un driver object representan a los dispositivos físicos que el driver controla. Por ejemplo, cada partición en el disco duro tiene un device object separado que contiene información específica de ella. Sin embargo el driver se usa para acceder a todas las particiones. Cuando se desinstala un driver en el sistema el I/O Manager usa la cola de device objects asociados con él para determinar los dispositivos que van a ser afectados. Figura 3.10 Device objects y driver objects. El uso de objetos para almacenar información sobre los drivers es muy beneficioso, porque, de esa forma el I/O Manager no necesita saber detalles sobre cada uno de los drivers. El I/O Manager simplemente usa un puntero para encontrar al driver. 3.9.3 Los Paquetes de Solicitud de Entrada / Salida, (I/O Request Packet, IRP). En las IRPs el subsistema de I/O almacena la información que necesita para procesar una solicitud de I/O. Cuando un hilo llama un servicio de entrada / salida el I/O Manager crea una IRP para representar la operación y su evolución a través del sistema. La figura siguiente muestra un ejemplo de petición de I/O que demuestra la relación entre una IRP y un file, device y driver objects. Aunque este ejemplo muestra una petición de I/O a un device driver de una sola capa, la mayoría de las operaciones no son así sino que involucran a uno o varios device drivers de varias capas. Este caso se va a explicar más adelante. Las IRP consisten de dos partes: una fija (también conocida como el cuerpo de la IRP) y una o más localizaciones en la pila (stack locations)21. La parte fija contiene información, como el tamaño y el tipo de la solicitud, si es sincrónica o asincrónica, un puntero a un buffer cuando el método es buffered, información de estado que cambia a medida que la solicitud es procesada. La localización del stack contiene un código función (que consiste en código mayor y menor), parámetros específicos de la IRP y un puntero al fichero objeto llamador. El código mayor (mayor code)22 identifica a cuál de las subrutinas de despacho del driver está invocando el I/O Manager cuando pasa la IRP al driver. El código menor23 (minor code) es opcional, a veces sirve como modificador del mayor code . Los comandos del Administrador de Energía y del Administrador de PnP siempre tienen minor code. La mayoría de los drivers especifican subrutinas de despacho para manipular solo un subconjunto de mayor codes posibles. Cuando una aplicación o un device driver indirectamente (porque el que crea las IRP es el I/O Manager) usando los servicios del sistema NtWriteFile, NtReadFile o NtDeviceIoControl (las funciones API Win32 correspondientes son: WriteFile, ReadFile y DeviceIoControl), el I/O Manager determina si necesita participar en la administración de los buffers de entrada y salida del llamador. El I/O Manager realiza tres tipos de administración de buffers: 4 Buffered I/O. El I/O Manager asigna buffers de igual tamaño. Para operaciones de escritura el I/O Manager copia el contenido de buffer del llamador en el buffer cuando crea la IRP. Para operaciones de lectura el I/O Manager copia los datos del buffer del sistema al buffer del llamador (aplicación de modo usuario) cuando la IRP es completada y libera el buffer del sistema. 5 Direct I/O. Cuando el I/O Manager crea la IRP, cierra el buffer de modo usuario en la memoria, y cuando ha terminado de procesar la IRP lo vuelve a abrir. El I/O Manager guarda una descripción de la memoria en la forma de un memory descriptor list, (MDL). El MDL especifica la memoria física que ocupa el buffer. Los dispositivos que realizan acceso directo a memoria (DMA) solo necesitan una descripción física de los buffers, por tanto un MDL es suficiente para la operación de estos dispositivos. 21 A partir de aquí me voy a referir a la pila como stack. A partir de aquí me voy a referir al código mayor como mayor code 23 A partir de aquí me voy a referir al código menor como minor code. 22 Sin embargo, si un driver necesita acceder al contenido de esos buffers puede mapear el contenido de esos buffers en el espacio de memoria del sistema. 6 Neither I/O. En este caso el I/O Manager no realiza ningún tipo de administración de los buffers. Esta es dejada al device driver, el cual puede escoger realizar manualmente estos pasos que el I/O Manager realiza con los métodos de administración de buffers. Para cada tipo de método de administración el I/O Manager coloca en la IRP referencias a la localización de los buffers de entrada y salida. El tipo de administración que haga el I/O Manager depende del que solicita el driver para cada tipo de operación. El driver registra el tipo de administración de buffers que necesita para cada operación en el device object que representa al dispositivo. Los drivers, por lo general, escogen I/O buffered cuando la cantidad de datos a transferir es menor de una página de la memoria (4 KB) y direct cuando la cantidad es mayor que 4 KB. Los drivers de los ficheros del sistema normalmente usan neither I/O porque no se incurre en ningún método cuando pueden copiarse los datos de la cache del sistema al buffer del usuario. Y, por otra parte, la mayoría de los drivers no usan neither I/O un puntero al llamador solo es válido mientras un hilo del proceso del llamador se está ejecutando. Si un driver tiene que transferir datos desde o a un dispositivo en una ISR o una DPC debe asegurarse primero de que los datos del llamador sean accesibles desde cualquier proceso, lo cual significa que el buffer debe tener una dirección virtual del sistema. 3.10 Procesamiento de la I/O. Ahora que ya hemos visto la estructura y los tipos de drivers y las estructuras de los tipos de datos ya podemos ver el procesamiento de la I/O en su conjunto. La solicitud de I/O pasa a través de varias etapas de procesamiento. Estas etapas dependen de si la solicitud está destinada a drivers en capas o no, de si la llamada es sincrónica o asincrónica etc. 3.10.1 Tipos de I/O. Sincrónica y Asincrónica. Las aplicaciones tienen varias opciones para las solicitudes de I/O. Por ejemplo, pueden especificar I/O sincrónica o asincrónica, I/O que mapea los datos del dispositivo en el espacio de memoria de la aplicación para acceso a través del espacio de direcciones de la aplicación en lugar de por APIs, y I/O que transfiere datos entre un dispositivo y un buffer discontinuo de una aplicación en una sola petición. Existe otro mecanismo de I/O que es la I/O rápida (fast I/O), que habilita al sistema a ir directamente al fichero que se va a abrir. Aquí solo voy a mencionar este método, para más información sobre la I/O rápida le recomiendo al lector que lea el libro Inside Windows 2000. La mayoría de las operaciones que las aplicaciones hacen son sincrónicas; esto es que la aplicación espera mientras el dispositivo realiza la transferencia de datos y devuelve un código de estado cuando la I/O ha terminado. Entonces el programa puede continuar y acceder al dato transferido inmediatamente. La I/O asincrónica permite a una aplicación hacer una solicitud y continuar ejecutándose mientras se realiza la transferencia. Para usar este tipo de I/O hay que especificar la bandera FILE_FLAG_OVERLAPPED en la llamada a la función API Win32 CreateFile. Por supuesto, después de realizar una I/O asincrónica los hilos deben ser cuidadosos de no acceder a los datos de la operación hasta que el device driver haya terminado la transferencia. El hilo debe sincronizar su ejecución con la terminación de la transferencia monitoreando el handle del objeto de sincronización. Independientemente del tipo de solicitud de I/O, internamente, las operaciones representadas por IRPs se realizan de forma asincrónica; esto es, que una vez que la solicitud ha sido iniciada el device driver regresa al sistema de I/O. La figura siguiente muestra el flujo de control de una operación de lectura. Note que si se produce una espera, la cual depende de la bandera overlapped, se hace en modo Kernel por la función NtReadFile. Se puede probar el estado de una I/O asincrónica pendiente con la función API Win32 HasOverlappedIoCompletion. 3.10.2 Solicitud de I/O en un driver simple (sin capas). En este epígrafe se trata sobre la solicitud de I/O sincrónica a un solo device driver. La manipulación de la solicitud de I/O a un driver de este tipo consiste de siete pasos. 1 La solicitud pasa a través de la DLL del subsistema. 2 La DLL llama al servicio del I/O Manager NtWriteFile. 3 El I/O Manager crea una IRP que describe la solicitud y la envía al device driver llamando su función IoCallDriver. 4 El driver transfiere los datos de la IRP al dispositivo y comienza la operación de I/O. 5 El driver señala la terminación interrumpiendo la CPU. Aunque no necesariamente tiene que ocurrir una, es posible que no ocurra. 6 Cuando el dispositivo termina la operación e interrumpe a la CPU, el device driver atiende la interrupción. 7 El driver llama la función del I/O Manager IoCompleteRequest para informarle que ha terminado de procesar la IRP, y entonces el I/O Manager termina la solicitud. Ahora veamos un poco más de cerca como es el proceso servir la interrupción y la terminación de la I/O. Estos siete pasos se muestran en la figura siguiente. 3.10.3 Atendiendo la interrupción. Después de que el dispositivo termina la transferencia de los datos interrumpe la CPU y el Kernel de Windows 2000, el I/O Manager, y el device driver entran en acción. Cuando ocurre una interrupción de un device driver el procesador le transfiere el control al Kernel, le cual direcciona en su tabla de despacho de interrupciones la ISR correspondiente a esa interrupción. Normalmente, en Windows 2000, las ISR manipulan las interrupciones en dos etapas. Cuando se invoca una ISR normalmente está ejecutándose hasta que limpia la interrupción y ‘’captura’’ el estado del dispositivo. Entonces pone en cola una DPC y termina su ejecución. Después esa DPC se llama y procesa la interrupción. Cuando termina llama al I/O Manager para completar la I/O y la IRP. Figura 3.11 Procesamiento de la I/O Después de que la DPC se ha ejecutado quedan algunas cosas por hacer antes de que pueda considerarse que la solicitud de I/O ha sido terminada. La tercera etapa en el procesamiento de la I/O es llamada terminación de la I/O (I/O Completion) y se inicia cuando el driver llama a IoCompletionRequest para informarle al I/O Manager que ha terminado. Los pasos que comprende la terminación varían con los diferentes tipos de I/O. Por ejemplo, todos los servicios de I/O guardan los resultados de la operación de I/O en un I/O Status Block , que es una estructura de datos que brinda el llamador. Similarmente, algunos servicios que realizan I/O buffered necesitan del subsistema de I/O para devolver datos al hilo llamador. Figura 3.12Procesamientode la I/O. En los dos caso, el subsistema de I/O debe copiar algunos datos que son almacenados en la memoria del sistema en el espacio virtual de direcciones del llamador. Si la IRP se completa sincrónicamente, el espacio de direcciones del llamador es accesible, pero si la IRP se completa asincrónicamente, el I/O Manager debe demorar la terminación hasta que pueda acceder al espacio de direcciones del llamador, el I/O Manager tiene que transferir datos ‘‘ en el contexto de del hilo del llamador ’’(esto es, mientras el hilo del llamador se está ejecutando, lo que significa que el proceso del llamador es el proceso actual y que su espacio de direcciones está activo en el procesador). El I/O Manager hace esto poniendo en cola una llamada a un procedimiento asincrónico (APC) de modo Kernel para el hilo. La APC se ejecuta en el contexto de un hilo particular, así como una DPC se ejecuta en el contexto de un hilo arbitrario, o sea que la DPC no puede tocar el espacio de direcciones del proceso de modo usuario. Las DPC tienen una prioridad de interrupción por software mayor que las APC. La próxima vez que un hilo comienza ejecutándose a un bajo nivel de IRQL la APC pendiente es entregada. El Kernel transfiere el control a l APC del I/O Manager la cual copia los datos y devuelve el estado al espacio de direcciones del llamador, libera la IRP y pone al fichero handle del llamador al estado señalado. La I/O es considerada completa ahora. El llamador original o cualquier otro hilo que está esperando en el fichero handle (u otro objeto) es liberado de su estado de espera y preparado para la ejecución. La figura ilustra la segunda etapa de la terminación de la I/O. Una nota final sobre la terminación de la I/O: las funciones asincrónicas ReadFileEx y WriteFileEx le permiten al llamador brindar una APC como parámetro. Si el llamador lo permite el I/O Manager pone en cola esta APC en la cola de APCs del hilo del llamador como el último paso de la terminación de la I/O. Esto le permite al llamador crear una subrutina que será llamada cada vez que termina una I/O o es cancelada. Las APCs de modo usuario se ejecutan en el contexto del hilo que hace la solicitud y son liberadas solo cuando el hilo entra en estado de espera (como cuando de llama las funciones Win32 SleepEx, WaitForSingleObjectEx, o WaitForMultipleObjectsEx). 3.10.4 Solicitud de I / O en drivers en capas. En los epígrafes anteriores se explicó cómo ocurre la solicitud de I/O en un solo driver. Ahora se va a mostrar cómo ocurre esto cuando la solicitud va dirigida a un driver pero éste tiene que dirigirse a otros device drivers, o sea cuando en el proceso intervienen varios drivers que se comparten la responsabilidad. La figura muestra un ejemplo de una I/O asincrónica que pasa a través de varios drivers. Se trata de un disco controlado por un fichero del sistema. Una vez más el I/O Manager recibe la petición y crea una IRP para representarla. Pero esta vez le envía la IRP a un file driver. El file driver ejerce un gran control sobre la operación en ese punto. En dependencia del tipo de petición que genera el llamador, el file driver puede enviar la IRP al driver del disco o crear IRPs adicionales que y enviarlas por separado al driver del disco. Si la IRP que el file driver recibe se traduce en una simple petición a un dispositivo probablemente la envíe simplemente al dispositivo. Por ejemplo, si la aplicación hace una petición de lectura en los primeros 512 bytes de un fichero almacenado en el disco floppy, el fichero FAT del sistema podría, simplemente llamar al driver de la torre de floppy, solicitándole leer un sector del disco que comience en la localización de inicio del fichero. Figura 3.13 Ejemplo de I/O en drivers en capas. Para acomodar el uso de la IRP por múltiples drivers en una solicitud a drivers en capas ésta contiene una serie de localizaciones de pila de IRP (IRP Stack Locations), ésta no tiene nada que ver con la pila usada por los hilos para almacenar parámetros y devolver direcciones. Estas áreas de datos, una por cada driver que es llamado, contienen la información que el driver necesita para realizar su parte de la solicitud que le corresponde por ejemplo, parámetros, códigos e información del contexto del driver. Como muestra la figura anterior las localizaciones de la pila adicionales son llenadas a medida que la solicitud pasa de un driver al siguiente. Tal vez en este momento usted piense que la IRP es como una pila en la cual los datos son almacenados y retirados a lo largo de su vida. Sin embargo, la IRP no está asociada con ningún proceso en particular, y el tamaño que tiene asignado no crece ni se encoge. Después de que el driver del disco termina la transferencia, el disco interrumpe y la I/O termina, como se muestra en la figura 3.14 Como una alternativa a reusar las IRPs, el file driver puede establecer un grupo de IRPs asociadas que trabajan en paralelo en una simple solicitud de I/O. Por ejemplo, si los datos a ser leídos del fichero están dispersos por todo el disco, el file driver puede crear varias IRPs, cada una de las cuales lee alguna porción de la solicitud de sectores distintos. Esta cola se ilustra en la figura 3.15 El driver entrega las IRPs asociadas al device driver el cual las pone en cola hacia el dispositivo. Son procesadas una a una y el file driver mantiene la huella del dato retornado. Cuando todas las IRPs asociadas terminan el subsistema de I/O termina la IRP original y regresa al llamador. Todos los file drivers de Windows 2000 que administran ficheros en discos son parte de una pila de drivers que están en la capa más profunda del árbol de capas. Figura 3.14Terminacion de la I/O. Figura 3.15 Cola de IRPs asociadas. 3.11 Sincronización. Los drivers deben sincronizar su acceso a los datos globales de drivers y registros de hardware por dos razones: 1 La ejecución de un driver puede ser apropiada para hilos de más alta prioridad o puede ser interrumpido por interrupciones. 2 En sistemas multiprocesador, Windows 2000 puede correr el código de los drivers en más de un procesador simultáneamente. Sin sincronización los datos pueden corromperse, por ejemplo, porque el código de los device drivers que corre a un nivel pasivo de IRQL cuando el llamador inicia una operación de I/O puede ser interrumpido por una interrupción de un dispositivo causando que la ISR del driver se ejecute mientras su propio device driver está corriendo. Si el device driver modificó datos que su ISR también modifica, como registros o datos estáticos, el dato puede corromperse cuando la ISR se ejecuta. La figura 3.16 ilustra este problema. Figura 3.16 Poniendo en cola IRPs asociadas en drivers en capas. Para evitar este problema los device drivers de Windows 2000 sincronizan su acceso a cualquier dato que comparte con su ISR. Antes de intentar actualizar datos compartidos, el device driver debe cerrar cualquier otro hilo para prevenir que actualicen el mismo dato. El Kernel de Windows 2000 brinda rutinas de sincronización especiales que los device drivers deben llamar para cuando acceden a los mismos datos que su ISR. Estas rutinas de sincronización no permiten que la ISR se ejecute mientras el dato compartido está siendo accesado por el device driver. En un sistema con una sola CPU estas rutinas aumentan de IRQL a un nivel especificado antes de actualizar la estructura. En un sistema multiprocesador, sin embargo, ya que los device drivers se pueden ejecutar en dos o más procesadores a la vez esta técnica no es suficiente para bloquear otros accesos. Por tanto, se usa otro mecanismo, el spinlock, para cerrar la estructura para el acceso exclusivo de una CPU particular.24 24 Ver Inside Windows 2000, Capítulo 3. En este trabajo no se va a profundizar en este tema ya que se saldría de nuestros objetivos, sin embargo se va mencionar para el conocimiento del lector. Usted solo debe comprender que aunque las ISR requieren una atención especial, cualquier dato que el device driver use está sujeto a ser accesado por el mismo device driver corriendo en otro procesador. Es de vital importancia para el device driver sincronizar el uso de cualquier dato global o compartido (o cualquier acceso al dispositivo físico en sí). Si la ISR usa ese dato, el device driver debe usar las rutinas de sincronización del kernel o usar el spinlock. 3.12 Conclusiones sobre el Subsistema de I/O de Windows 2000. El subsistema de I/O de Windows 2000 define el modelo de procesamiento de la I/O y las funciones que son comunes o son necesarias para más de un device driver. Su principal responsabilidad es crear las IRPs que representan las solicitudes y monitorearlas a través de los varios drivers por los que debe pasar hasta terminar. El I/O Manager localiza los drivers y los dispositivos usando los objetos del sistema de I/O, incluyendo drivers y device objects. Internamente, el subsistema de I/O opera asincrónicamente para lograr alta fiabilidad y brinda varios modos de realizar la solicitud asincrónica y sincrónica. Los device drivers incluyen, no solo los drivers que manipulan hardware sino también file drivers y filter drivers. Todos los drivers tienen la misma estructura y se comunican unos con otros y con el I/O Manager usando mecanismos comunes. Ya que los drivers tienen una estructura para el sistema operativo, pueden ser colocados en capas, unos arriba y otros abajo para lograr modularidad y reducir la duplicación entre los drivers. También, todos los device drivers de Windows 2000 deben ser diseñados para trabajar correctamente en sistemas multiprocesador. Finalmente, el papel del Administrador de PnP es trabajar con los device drivers para detectar dinámicamente los dispositivos de hardware y construir un árbol interno que guíe la enumeración de los dispositivos de hardware y la instalación de los drivers. El Administrador de Energía (Power Manager) trabaja con los device drivers para mover los dispositivos a través de los estados de consumo energético. 3.13 Especificidades del sistema. Herramientas para hacer el driver. En los epígrafes anteriores se habló de forma general de los componentes del sistema operativo Windows 2000, del subsistema de I/O, de los tipos de datos que intervienen en el proceso de solicitud de I/O y del procesamiento de ésta. Se dio una idea general de cómo transcurre éste proceso con ejemplos clásicos, pero que no satisfacen la lógica curiosidad de cómo es que ocurre todo este proceso en el caso de la tarjeta AX5411 y sus similares. La lectura hasta este punto quizás haya sido un poco difícil, pero es imprescindible familiarizarse con el sistema operativo Windows 2000 si se pretende hacer un driver que maneje nuestra tarjeta de adquisición de datos, ya que en una PC el sistema operativo administra todo el sistema y no es posible ignorarlo. En este epígrafe ya se va a hablar más específicamente de nuestro caso particular y de las herramientas que se pueden usar para programar el driver necesario. Cada driver tiene sus particularidades, que dependen de la función que va a realizar. Por ejemplo, el driver del display no es igual que el de la torre de CD. El caso que nos ocupa no es una excepción. Vamos a hablar un poco sobre las herramientas necesarias. Cualquier software de programación en un superlenguaje (Delphi, C++, Visual Basic etc) genera ejecutables, DLLs etc, pero generar con ellos un driver que corra en modo Kernel no es sencillo. Para lograr esto existe una herramienta muy fácil de usar, el Numega Driver Studio. Este es un paquete de softwares muy útil, que comprende el DriverWorks, el Driver Networks, el VToolsD, el SoftIce etc. Qué son cada uno de éstos. El Driver Woks es el que nos permite hacer un driver de modo Kernel, es con éste con el que se puede hacer el driver que necesitamos, luego voy a hablas más profundamente sobre él, ahora voy a seguir describiendo a los demás. El SoftIce es otro software que debemos usar; es un debugger, o sea, un simulador. En él podemos ver el comportamiento del driver, los registros de la CPU etc. Es muy importante usarlo para estar seguros del buen funcionamiento del driver antes de probarlo con el hardware. El VToosD se usa para generar las VxD. Y el Driver Netwoks se usa cuando los drivers tendrán que correr en una red de computadoras. Como ve, el Numega Driver Studio es todo un cajón de herramientas en las manos de un programador. También debe usted instalar en su PC el DDK de Windows 2000. ¿Qué es el DDK de Windows 2000? DDK son las siglas en inglés de Driver Development Kit y es un paquete de documentaciones, bibliotecas, simuladores y otras herramientas que el Numega Driver Studio utiliza para generar los códigos de un driver. Y, por último instale el Visual Studio 6.0 en su PC. Abra el DriverWorks en el menú Programas \ Numega Driver Studio \ Driver Woks \ Driver Wizard. Cuando lo abra verá que lo va guiando en la configuración del código de un driver. Finalmente, cuando llegue al final y oprima el botón Finish se le cerrará el Diver Woks y se abrirá el Visual C++ con código generados automáticamente por el Driver Woks, El ambiente de programación es el del Visual C++. Cuando haga esta prueba se encontrará en su código unas marcas así TODO con sugerencias esto significa to do y las sugerencias no son obligatorias. En esas marcas es donde usted escribirá el código específico de su driver. Note que una de las funciones miembro del driver es la subrutina StartIo descrita cuando se trató de la estructura de los device drivers[5]; en el caso específico de nuestro driver no era necesaria porque la interfase al driver es a través del enlace simbólico, que sólo será utilizado por la aplicación que se hizo para usar la tarjeta. Por tanto, solo se harán solicitudes de I/O desde esa aplicación y, por lo tanto no hay riesgo de que el driver reciba dos IRPs a la misma vez. En cambio la función miembro DeviceControl, que es la que recibe a la que está dirigida la IRP, ya que la llamada se hace siempre con la función API Win32 DeviceIoControl chequea el código de control que trae la IRP y si no es el correcto devuelve el código de error STATUS_INVALID_PARAMETER. Esto se hace para evitar posibles errores. Cada uno de los programas que integran el Numega Driver Studio tiene un pdf que es el manual, le recomiendo que estudie el manual del Driver Works (Using Driver Works). En ese manual se describen las clases donde están implementadas las funciones más importantes, muy especialmente le aconsejo que estudie las clases KIORange, KMemory, KInterrupt, KDmaChannel y KDmaAdapter. El NuMega Driver Studio es la herramienta ideal para hacer drivers para Windows 2000 (y para otros sistemas operativos también) ya que es muy fácil de usar. Pero, insisto en que es imposible hacer un driver para ningún sistema operativo si no se conoce cómo funciona. Es de suma importancia estudiar la arquitectura y el funcionamiento del sistema para poder hacer un driver que maneje un hardware específico. Ahora bien, ha llegado el momento de hacer algunas aclaraciones sobre nuestro caso. Había dicho, de forma general, que las IRPs que llegan a un driver son puestas en cola ya que el device object no puede procesarlas todas a la misma vez, sino una a una; esa es la opción más general, ya que, imagínese por ejemplo el driver de la tarjeta de red cuántas IRPs puede recibir a la misma vez, pueden ser varias. Pero en nuestro no es necesario ya que nuestro driver solo recibirá IRPs de una solo aplicación. O sea, que solo la aplicación CALLAX5411.exe hará la llamada a la función API Win32 CreateFile para abrir un handle al driver (que se llama Driax5411.sys). Podemos tener una confianza total en esto último ya que para abrir el handle hay que pasarle a CreateFile como primer parámetro el enlace simbólico del driver, que es único. Por tanto, e insisto en esto una vez más, ninguna otra aplicación podrá abrir un handle al driver que maneja a la tarjeta AX5411. Por otra parte es posible que un driver no permita que se abran varios handles a la vez para interactuar con él y ese es nuestro caso: solo se podrá abrir un handle a la vez. Lograr esto es una de las cosas más fáciles de todo el proceso de hacer el driver, y se hace al principio: cuando está el DriverWorks abierto seleccione la opción unique y con eso habrá garantizado plena exclusividad. ¿Recuerda el segundo capítulo, cuando expliqué cómo programar la tarjeta? Pues el que envía los datos a los registros necesarios es el driver (Driax5411.sys) y luego coloca los resultados en un buffer, cuya dirección de memoria, en forma de apuntador, guarda uno de los campos de la IRP, cuando es devuelta al I/O Manager, y que finalmente la aplicación (CALLAX5411.exe) puede acceder. Con esto se ha terminado la explicación de cómo se hace para conectar la tarjeta AX5411 a una PC y se usa para adquirir los datos que se deseen. Capítulo 4. Conceptos finales y resultados de pruebas. Capítulo 4: Conceptos finales y resultados de las pruebas. Todo sistema, sea cual sea su naturaleza y propósito debe ser probado antes de poder concluir que funciona bien. Nuestro caso no es una excepción. Pero tenemos una característica que nos distingue: y es que nuestro sistema consiste de un hardware y un software, ya que los drivers que se adquirieron junto con la tarjeta no corren en Windows 2000. Por tanto hay que probar la tarjeta para saber si funciona bien, probar que el driver y la aplicación se comunican (para esto es suficiente con obtener un handle válido) y probar los tres: tarjeta, driver y aplicación. La primera prueba fue la del hardware. 1.1 Pruebas al hardware. ¿Por qué la primera prueba es la del hardware, y por qué hay que probarlo por separado? Es un paso lógico, la tarjeta nunca ha sido usada por lo que no tenemos la certeza de que funcione: Debemos cerciorarnos primero de que el hardware esté bien porque si hacemos una primera prueba a todo junto y hay algún problema nos será más difícil saber donde está. En cambio si probamos la tarjeta y nos aseguramos de que está bien descartamos que haya problemas de hardware. Para hacer esta prueba conectamos la tarjeta al bus ISA de una máquina y usamos el LabView para enviarle datos a los registros relacionados con la I/O digital de la tarjeta. Enviamos el número 00000001 a la salida y medimos con un multímetro, cerciorándonos de que en el bit correspondiente había +5V. Luego conectamos las salidas a las entradas y enviamos el mismo número y leímos, también esta fue exitosa. Por último comenzamos a rotar el número y siempre pudimos leerlo por las entradas. Con esto ya tuvimos la seguridad de que las entradas y salidas digitales de la tarjeta estaban en buen estado. 1.2 Comunicación entre el driver (Driax5411.sys) y la aplicación (CALLAX5411.exe). Como ya el lector conoce, para lograr que una aplicación y un device driver se comuniquen en el código de la primera debe estar presente la llamada a las funciones API Win32 CreateFile para obtener el handle, y DeviceIoControl, WriteFile o ReadFile para interactuar con las subrutinas de despacho correspondientes. Para hacer la prueba hay que instalar el driver primero. Esta es una tarea fácil, aunque no es como instalar una aplicación que va a correr en el anillo 3 de Windows. Para hacerlo hay que arreglar el fichero .inf que el NuMega Driver Studio genera junto con el esqueleto del código fuente del driver. Este .inf que se genera lleva el mismo nombre que usted le define a su proyecto y es un .inf muy general, por lo que hay que colocarle los códigos específicos de su driver. Sin este fichero es imposible instalar el driver porque el sistema no tendría información sobre el hardware. Nuestro .inf se llama Driax5411.inf . Una vez que lo haya arreglado utilice para instalar el driver el Add / Remove Hardware Wizard que se encuentra en el Panel de Control de la PC, o la herramienta EzDriverInstaller.exe que le brinda NuMega y que está disponible en C:\Program Files\NuMega\Driver Studio\Tools\EzDriverInstaller. El próximo paso a seguir, una vez que se ha instalado el driver es cerciorarse de que los recursos asignados a su dispositivo no entran en conflicto con otro. Para hacer esto de click derecho sobre Mi PC y seleccione Manage, le saldrá la lista completa de los componentes de su PC, seleccione la opción Driver Manager, ahí verá usted todos los dispositivos de hardware que conforman su sistema y sus drivers. Busque el dispositivo que dice AX5411DEVICE, allí es donde aparece el driver. Si este no entra en conflicto con otros podrá verlo. El recurso más importante en este caso son las direcciones de entrada / salida, es de una gran importancia que estas no entren en conflicto con otros drivers porque de lo contrario no se podrá usar nuestro driver. Cada driver (aquellos que tienen que usar I/O) tiene un espacio de direcciones de I/O que es reservado para él, los otros no pueden usarlo. Para estar más seguros de que el driver realmente está instalado se puede abrir la herramienta Simbolic Link Viewer que nos brinda el NuMega Driver Studio, con ella se puede ver los enlaces simbólicos de todos los drivers del sistema. Para estar plenamente seguros de que CALLAX5411.exe y Driax5411.sys se comunican es suficiente con asegurarnos de que se obtiene un handle válido. Esto puede saberse llamando la función GetLastError después de CreateFile, la primera devuelve el código del último error que ha ocurrido. Un ejemplo de esto puede ser el siguiente: var coderror : integer; handleax5411 : Thandle; ipsecurityattributes : Psecurityattributes; begin ipsecurityattributes := nil; handleax5411:= createfile(´\\.\Driax5411Device0´,0,0,ipsecurityattributes,OPEN_EXISTING,FILE_ ATTRIBUTE_NORMAL,0); coderror:= getlasterror(); if coderror = ERROR_BAD_NETPATH then showmessage(´No se puede abrir el handle´); if coderror = NO_ERROR then showmessage(´El handle se ha creado exitosamente´); end; En el anterior código si el handle se abre bien nos mostrará un mensaje que dirá ‘‘ El handle se ha creado exitosamente ’’; si eso ocurre es porque se ha encontrado el enlace simbólico. En caso contrario no habrá un handle válido. En nuestro caso pudimos advertir que la aplicación y el driver se comunican porque obtuvimos el handle válido. Con esto ya podemos estar seguros de que el driver está bien instalado. Aunque es suficiente con la explicación anterior no está de más explicar con detalles el código que se acaba de ver. En la declaración de variables hay una que seguramente llamará su atención: handle de tipo Thandle, pues precisamente Thandle es el tipo definido en el Object Pascal para los handles. La variable ipsecurityattributes de tipo Psecurityattributes es muy importante ya que es uno de los parámetros de la función CreateFile; el tipo Psecurityattributes es un apuntador a una estructura de datos que contienen los atributos de seguridad del driver. Y la variable coderror, de tipo entera, por medio de la cual se puede obtener el código de error que necesitamos. La función comienza con la llamada a la función CreateFile pasándole todos los parámetros necesarios. El primero de ellos puede parecer un poco extraño a primera vista pero no lo es: este parámetro es el más importante porque es el enlace simbólico al dispositivo que se quiere abrir. El ‘‘ prefijo ’’ \\ .\ significa que éste es un intento de abrir un handle a un device driver. Para más detalles sobre la función CreateFile remítase a los anexos o visite el sitio www.msdn.com . Si el driver está realmente instalado en el sistema el resultado de la llamada a esta funcion será un handle válido al dispositivo, de lo contrario el sistema generará un código de error que puede conocer llamando a la función API Win32 GetLastError. Esto es justamente lo que se hace en este ejemplo, se llama la función guardándose el resultado en la variable coderror. A continuación se realizan varias condiciones ( if ) para realizar distintas acciones en dependencia del código de error que se recibe. Si se recibe el código ERROR_BAD_NETPATH se muestra el mensaje ‘‘ No se puede abrir el handle ’’, este error significa que no se encontró el camino al driver. Y si se recibe el código NO_ERROR significa que el handle se abrió exitosamente sin que ocurriera ningún error. El hecho de que en el código se muestren los errores con palabras no significa que éstos sean palabras, son constantes, por ejemplo NO_ERROR es 0. Todos estas constantes están definidas en el fichero WINERROR.H que se encuentra en el DDK de Windows 2000. 1.3 Prueba del funcionamiento del sistema. Una de las funciones miembro del device object es DeviceControl. Esta es con la que nos comunicamos cuando llamamos la función API Win32 DeviceIoControl desde nuestro programa del anillo 3. Dentro de ella se realizan distintas acciones en dependencia del código de control que se reciba. Switch (I.IoctlCode()) { case SIMPLE_LECTURA: { status = SIMPLE_LECTURA_HANDLER(Kirp I); break; } case SALIDA_DIGITAL: { status = SALIDA_DIGITAL_HANDLER(Kirp I); break; } case ENTRADA_DIGITAL: { status = ENTRADA_DIGITAL_HANDLER(Kirp I); break; } case INTERRUPCION_AL_FINAL: { status = INTERRUPCION_AL_FINAL_HANDLER(Kirp I); break; } case INTERRUPCION_DMA: { status = INTERRUPCION_DMA_HANDLER(Kirp I); break; } case SALIDA_ANALOGICA: { status = SALIDA_ANALOGICA_HANDLER(Kirp I); break; } case CAMBIAR_FRECUENCIA: { status = CAMBIAR_FRECUENCIA_HANDLER(Kirp I); break; } default: status = STATUS_INVALID_PARAMETER; } return status; En este código pueden observarse las distintas funciones que se llaman en dependencia del código de control que se recibe. El código de control lo trae la IRP en el campo I.IoctlCode(). Los códigos de control se pueden generar, durante el proceso de creación de un nuevo proyecto en el DriverWorks se puede hacer esto. Por supuesto usar o no códigos de control es opcional, pero es mejor usarlos ya que éstos definen el tipo de interacción entre el driver y la aplicación (buffered, indirect, outdirect y neither)[2], el tipo de acceso etc además de ser una herramienta para escoger lo que se quiere hacer. Las funciones que se llaman son las que procesan la IRP. Ellas realizan las siguientes funciones. 1. SIMPLE_LECTURA_HANDLER : realiza una sola medición por uno o varios canales, pero de ninguna manera hace un ciclo; o sea, si la medición solicitada es por varios canales mide en cada uno de ellos y envía los datos a la aplicación. 2. SALIDA_DIGITAL_HANDLER : envía un número a la salida digital de la tarjeta. 3. ENTRADA_DIGITAL_HANDLER: lee el puerto de entrada de la tarjeta. 4. INTERRUPCIÓN_AL_FINAL_HANDLER : realiza varias lecturas en las entradas analógicas, al final de cada una de ellas se produce una interrupción. La ISR es la que envía los datos a la aplicación. Antes de llamarse hay que programar el contador – temporizador con la frecuencia de muestreo deseada. 5. INTERRUPCION_DMA_HANDLER : es igual que la anterior pero en ella los datos son mandados a la memoria via DMA y al final de este proceso es que se produce la interrupción. Luego es que se pueden mostrar en la pantalla. No es recomendable para realizar mediciones en tiempo real. 6. SALIDA_ANALÓGICA_HANDLER : manipula el subsistema de conversión digital – analógico. 7. CAMBIAR_FRECUENCIA_HANDLER: con esta función se puede reprogramar el contador – temporizador 8254 de la tarjeta. Las funciones relacionadas con la I/O digital y con la conversión A – D (con excepción de INTERRUPCION_DMA_HANDLER) fueron probadas luego de ajustarlas, las otras por razones de tiempo no fue posible probarlas antes de terminar este trabajo, aunque se continúa trabajando en ellas. Conclusiones: 1. Se ha logrado demostrar que la tarjeta está en buen estado y que es viable usarla para el muestreo de las señales de voltaje y corriente del arco de la soldadura eléctrica. 2. Se logró hacer un driver para Windows 2000 capaz de manejar la tarjeta. 3. Se obtuvo experiencia en la programación de drivers que corren en modo Kernel. 4. Se obtuvo un marco teórico sobre este tema. Recomendaciones: 1. Hacer una aplicación con un diseño gráfico atractivo que llama funciones que controlen la tarjeta. 2. Hacer una DLL que contenga procedimientos y funciones en las que se realicen las llamadas a las funciones API Win32 CreateFile y DeviceIoControl para comunicarse con el driver y controlar la tarjeta. La nueva aplicación deberá llamar estas funciones. 3. Hacer un dispositivo que adapte las señales de altas corrientes del arco de la soldadura para que pueda ser leída por la tarjeta AX5411. Referencias Bibliográficas. 1. Sitio de la Oficina de Patentes de los Estados Unidos de América. www.uspto.gov 2. Sitio Espacenet. www.espacenet.com 3. Sitio de la empresa AXIOM Tecnologies Co. www.axiomtek.com 4. David Solomon, Mark E. Russinovich. ‘‘ Inside Microsoft Windows 2000’’. Microsoft Press. 2000. 5. Manual de NuMega Driver Studio. ‘‘Using DriverWorks’’ . Copyright © 1996 – 2001 Compuware Corporation. Bibliografía. 1. David Solomon, Mark E. Russinovich. ‘‘ Inside Microsoft Windows 2000 ’’. Microsoft Press. 2000. 2. AXIOM Tecnologies Co. Manual de Usuario de la Tarjeta AX5411. 3. ‘‘ Los Microprocesadores Intel, Arquitectura, Programación e Interfases ’’. 4. Manual de NuMega Driver Studio. ‘‘Using DriverWorks’’ . Copyright © 1996 – 2001 Compuware Corporation. 5. ‘‘ A Book on C. An introduction to Programming in C ’’. Anexos Algoritmo para la programación de la tarjeta AX5411. Para mejor comprensión este algoritmo se va a presentar en forma de diagrama de flujo. Le advierto al lector que aquí se va a tratar de la programación de la tarjeta en modo general, no de nuestro driver en particular, aunque no hay prácticamente diferencia alguna. Nuestra intención al hacer esto es que el lector pueda tener ina idea más general para en caso de proponerse hacer otro driver tenga una guía más completa. inicio Subsistema de conversión A – D. Subsistema de conversión D–A Final Entrada / Salida Digital. Subsistema de conversión analógico – digital. Programar ganancia y canales N Temporizador? ¿Pulso externo? S Programar temporizador N Interrupción? Programar funciones para arrancada por pulso externo S DMA? S Programar funciones para DMA e interrupción N Programar funciones para interrupcion solamente Programar funciones para arrancada por software N S Leer dato EOC =0?