En mi otro blog:
March 14, 2009
March 12, 2009
March 11, 2009
John Lakos: Large-Scale C++ Software Design
En mi otro blog:
November 16, 2008
Charles Petzolod: Code
El subtítulo del libro es: The Hidden Language of Computer Hardware and Software, que traducido al castellano quedaría como El lenguaje oculto del hardware y del software de los ordenadores. Y eso es lo que es la obra.
En apenas trescientas ochenta y pico páginas Charles Petzold recorre la estructura y el funcionamiento de un ordenador moderno. Y no lo hace nada mal. Yo más bien diría que lo hace de forma inmejorable, ya que combina la rigurosidad más absoluta con la magia de las explicaciones coherentes e incrementales. Como él mismo dice, en este libro no va a encontrar el lector grandes y vistosos gráficos mostrando de forma elemental conceptos que de tan sencillos dejan más duda que comprensión.
Se trata de un libro que pudiéramos llamar hardcore, pero no por eso es menos entendible. La profundidad de las explicaciones se pierde en la maravillosa forma en que están hechas. Personalmente me ha vuelto a mis tiempos de estudiante de electrónica digital y de microprocesadores, haciéndome continuos guiños y recordándome aquellas arduas sesiones de estar primero escribiendo el programa en ensamblador, luego traduciéndolo a código máquina y finalmente tecleándolo con una botonera hexadecimal… para que un brazo de robot girara sobre sí mismo o abriera y cerrara la pinza…
El autor comienza con una explicación sobre qué es un código de comunicación (nos habla de Braille, de Morse, de bombillas apagándose y encendiéndose) y nos construye y explica un aparato de Morse. Entre tanto hemos dado un curso básico de electricidad, viendo cómo circula la corriente, cómo funcionan los relés y alguna que otra cosa más.
Luego nos explica cómo funciona el sistema decimal, el binario, el octal, el hexadecimal, y cuando nos damos cuenta estamos construyendo puertas lógicas (AND, OR, etc.) y hemos asistido a un curso sobre lógica formal.
Casi sin darnos cuenta al rato estamos construyendo un oscilador, un sumador y un restador con relés, y de paso aprendemos el complemento a dos y cómo restar sumando.
Un par de capítulos después nos descubrimos inmersos en básculas Flip-Flop y tipo D… Y cuando levantamos la cabeza de libro hemos construido una memoria de 64Kbytes, un contador y otros varios elementos básicos.
Lo bueno del libro es que fluye de forma continua, se desplaza de lo más sencillo a lo más complejo de forma secuencial y sin aparente aumento de dificultad, para descubrir que estamos estudiando un ordenador casi completo. Hemos visto cómo funciona el código máquina, hemos visto las instrucciones aritméticas, de salto condicional para hacer bucles y lo más importante de todo es que lo entendemos. Apenas nos cuesta comprender cómo están cliqueando los relés dentro de nuestro ordenador (es un decir), y comprendemos cómo arranca y empieza a funcionar. Ciertamente es un libro mágico porque pese a lo riguroso y formal de su contenido es perfectamente entendible.
Adelanta y atrasa, recorre un gran trecho hacia adelante y luego recopila y se recrea en conceptos. De repente nuestro ordenador de 8 bits (porque sin darnos cuenta hemos construido tal aparato) pasa de estar hecho de relés a ser de válvulas (y de paso nos damos una vuelta por los primeros ordenadores, el ENIAC, MULTIVAC, etc). Y un poco más tarde está construido con tecnología TTL o CMOS, y de repente se nos presentan los microprocesadores, pero no sin antes haber recorrido la mente del doctor Atanasof y de Hollerich, pasando por lo que antes era IBM…
En ese momento, si nos ponen en la mano un 8080 y un chip de memoria seríamos capaces de construir nuestro ordenador del igual modo que lo hicieron Wozniak y Waine.
Pero el libro no termina ahí, sino que sigue subiendo de nivel hasta explicarnos por qué necesitamos un sistema operativo. De hecho, siguiendo con la tónica del libro, casi sin darnos cuenta estamos viendo la necesidad de un sistema operativo; es decir, tras tener un aparato programable Petzold nos hace evidente lo evidente.
Números en coma flotante, lenguajes de alto y bajo nivel, entornos gráficos. En lugar de explicárnoslo, el libro nos hace sentir la necesidad de ellos… y entonces nos los explica.
Para finalizar: un libro muy bello, interesante y admirablemente construido. Lástima que no esté traducido al castellano, porque no creo que haya otra obra igual. Aunque por un lado tenemos los libros de electrónica digital y por otros los de informática básica, ninguno enlaza y engloba todos los conceptos e ideas de una forma tan coherente, incremental, lógica y bella.
Sólo hay un punto oscuro en toda la obra: el autor no nos explica la unidad de decodificación y de ejecución del ordenador que nos construye. Ciertamente poner en marcha algo así es un tema arduo y complejo en demasía, pero hubiera sido la guinda que corona el pastel… De todos modos, pese a esa falta, la obra no pierde absolutamente nada de su valor.
March 4, 2008
Cierro el chringuito
Pues eso, que estoy algo cansado de forzarme a escribir una entrada válida para poner aquí (y no es que las que pongo sean de mucha calidad), así que de momento voy a dejar estar un poco el tema.
No es un cierre absoluto, sino más bien cautelar, ya que iré haciendo eco de mis entradas en Geeks y quizás ponga alguna otra cosa, pero no con la frecuencia habitual…
Pues eso, que hasta luego.
March 3, 2008
Singleton con y sin Singleton
Ahora que están de moda los antipatrones, voy a explicar un patrón que es muy famoso pero que no me gusta absolutamente nada, no por el diseño del mismo, sino por los efectos laterales no deseados que genera. Por ello también voy a explicar otra forma de construirlo que me gusta más, aunque adolece de otras limitaciones.
Singleton es un patrón que nos obliga a tener una sola instancia de una clase, es decir, globalmente sólo podremos disponer de un objeto de ese tipo. El truco está en conseguir que, hagamos lo que hagamos, no podamos crear más de una instancia.
En lenguajes como C++ este patrón tiene menos utilidad que en C++/CLI, C# o VB.NET, ya que la forma clásica de hacer algo similar es tener una variable global accesible por todos los módulos, cosa de la que suele encargarse el enlazador de hacer.
Pero los lenguajes .NET adolecen de falta de variables globales; es decir, no puedes tener un objeto global y visible en toda la aplicación. Personalmente no entiendo este purismo tan quisquilloso, ya que los lenguajes .NET no son precisamente orientados a objetos puros, y menos aún con la especificación 3.0 de C#. Y si encima este hecho complica bastante ciertos desarrollos, el absurdo sube de nivel.
Pero es lo que hay.
La solución para tener un objeto global es disponer de una clase estática. Si bien a priori resulta una buena idea, en la práctica no lo es tanto. Independientemente del hecho de que los constructores estáticos en .NET no funcionan muy bien o, en otras palabras, tienen bastante bugs (al menos en la versión 2.0, aunque dudo mucho que lo hayan solucionado en los SP1), tenemos ciertas limitaciones, como la imposibilidad de que se llame a otro constructor estático de forma encadenada…
¿Y por qué comento esto? Pues porque el patrón Singleton utiliza una variable y un constructor estático. Veámoslo en C#:
1: using System;
2: using System.Collections.Generic;
3: using System.Text;
4:
5: class Singleton
6: {
7: public static Singleton Instancia=new Singleton();
8:
9: private Singleton() {}
10:
11: public int Numero;
12: public void DiNumero()
13: {
14: Console.WriteLine(Numero++.ToString());
15: }
16: }
17:
18: class Program
19: {
20: static void Main(string[] args)
21: {
22: Singleton.Instancia.Numero = 33;
23: for (int i = 0; i < 10;i++)
24: Singleton.Instancia.DiNumero();
25: }
26: }
Observamos que el truco está en definir un constructor privado. Al hacerlo, ya no podremos equivocarnos y crear varias instancias de esta clase, y la única forma de acceder al único objeto que pueda haber en toda la aplicación es mediante
1: Singleton.Instancia
Si intentamos crearnos un objeto del tipo Singleton, el compilador protestará y nos dirá que el constructor no está accesible.
Si alguien quiere una explicación más en detalle, se puede pasar por la MSDN o por aquí.
¿Nadie ve el problema?
Pues hay dos. El primero ya lo hemos dicho: tenemos un objeto global al sistema, que es estático y por tanto sigue unas reglas algo diferentes, como la imposibilidad de hacer una llamada a otra variable estática que implemente su propio constructor estático dentro del constructor de nuestro Singleton… O en otras palabras: no podemos tener Singletones anidados, no al menos bajo .NET.
Pero el mayor problema es otro. Cuando se habla de Singleton, se pone un ejemplo con dos líneas de código y listo. Pero una clase de la Vida Real™ no es sencilla. Tendremos varios métodos miembro, así como variables. ¿Cómo las inicializamos? ¿En el constructor? ¡Pero si no tiene constructor al que podamos pasarle valores! ¿Las ponemos públicas? ¿Propiedades?
Una solución es la mostrada aquí:
1: Singleton.Instancia.Numero = 33;
2: for (int i = 0; i < 10;i++)
3: Singleton.Instancia.DiNumero();
Pero a mí al menos eso me parece una guarrería mayor, y más cuando haya varios datos miembro, como suele ser habitual en clases no triviales… La única cosa que podemos hacer es especificar valores por defecto en el constructor estático:
1: private Singleton() { Numero = 50; }
Pero eso sólo alivia el problema, no lo soluciona.
Qué bonito sería que pudiéramos indicar algo como
1: [Pattern(Singleton)]
2: class Singleton
3: {…
Y disponer de la clase como si tal cosa… Pero esa es otra guerra.
Otra aproximación
Veamos ahora una variante, que es la que yo implemento en mis propios programas. Primero el código:
1: using System;
2: using System.Collections.Generic;
3: using System.Text;
4:
5: class MiSingleton
6: {
7: private static int m_cuenta=0;
8:
9: private int m_numero;
10: public MiSingleton(int num)
11: {
12: m_cuenta++;
13: if (m_cuenta > 1)
14: throw new Exception("RFOG Singleton Exception");
15:
16: m_numero = num;
17: }
18: public void DiNumero()
19: {
20: Console.WriteLine(m_numero++.ToString());
21: }
22: }
23: class Program
24: {
25: static void Main(string[] args)
26: {
27: MiSingleton m = new MiSingleton(33);
28: for (int i = 0; i < 10;i++)
29: m.DiNumero();
30:
31: MiSingleton n=new MiSingleton(88);
32: }
33: }
Aquí encontramos otros problemas y otras limitaciones, pero personalmente me gusta más así. Definimos una variable estática, un entero que nos servirá para contar cuántas instancias de esta clase tenemos.
Definimos un constructor público al que podremos pasarle cualquier número de parámetros que queramos, de hecho se trata de una clase normal y corriente que tiene un bloque de código concreto en el constructor:
1: m_cuenta++;
2: if (m_cuenta > 1)
3: throw new Exception("RFOG Singleton Exception");
La segunda vez que intentemos instanciar esta clase obtendremos una excepción. Aquí la limitación está en que nos daremos cuenta de nuestro error en tiempo de ejecución, no de compilación, lo que ciertamente es una desventaja seria pero que pierde fuerza cuando nos enfrentamos a las limitaciones y bugs de los constructores estáticos.
La segunda instanciación dentro del bloque de main() lanzará la excepción. La otra limitación a esto viene de la imposibilidad de tener variables globales y de que tengamos que pasar m siempre que queramos usarlo.
Lo ideal sería tener ambas opciones juntas, pero ciertamente dentro de .NET es imposible.
March 1, 2008
El loco de la colina y las colinas locas (Sobre el SP1 del Vista)
Ya sé que últimamente no abundan los contenidos técnicos por aquí, pero estoy laboralmente muy ocupado y el tiempo libre que tengo lo paso leyendo y relajándome, imagino que de aquí a un mes volveré a estar más libre… Eso o estaré en paro, ya que no me gusta absolutamente nada la dinámica que está tomando mi curro, con salidas a toda España a reparar máquinas de las que no entiendo ni quiero entender y que ya de por sí su comprensión suponen un oficio en sí mismo.
Pero hoy no voy a hablar de mí, sino de Microsoft y sus últimas pifias. Ahora como MVP tengo línea directa, pero a fin de cuentas es como si no la tuviera, ya que por lo menos a mi no me hacen ni p*to caso. Y a veces son cosas muy serias, como las del final de esta entrada.
Visual Studio 2008
Quien tenga una subscripción a la MSDN lo habrá podido descargar más o menos desde noviembre del año pasado, así que debe estar bastante familiarizado con él. En mi caso no le encuentro ninguna pega destacable. Aunque tampoco es que le haya dado mucha caña: una pequeña aplicación en C#, dos tonterías en MFC y sí una espuerta de DLLs en Win32. Y si fallara haciendo DLLs pues ya sería la rehostia…
Estooooo… ¿Digo que no falla? Pues sí que falla, o mejor dicho fallaba. Y no sé cómo lo han actualizado, pero lo han hecho. Si uno crea un proyecto con una DLL nativa, y usa esa DLL nativa en otro proyecto dentro de la misma solución, el linker revienta a la hora de enlazar. Es muy curioso, porque solo revienta justo después de reiniciar Windows, y sólo en Vista. O en otras palabras: la primera compilación parcial tras un reinicio hace que el linker genere un error interno. Curioso, ¿no?
Pues tras informar del error (yo fui el primero, luego comenzó a pasarle a más gente), lo han solucionado. ¿Cómo? Pues no lo sé. El Visual Studio no lo han actualizado, así que ha debido ser una actualización secreta de esas que no te dicen nada o junto a alguna actualización del propio Windows.
Decir que está actualizado es mucho afirmar, más bien el problema queda minimizado y sólo ocurre con muy poca frecuencia, tan poca que apenas es molesto.
Más Visual Studio 2008 y el SDK 6.1
Otra, esta algo más grande. Hay dos nuevos Windows SDK, ambos con la versión 6.1. Uno para Vista SP1 y otro para Windows Server 2008. El que trae el Visual Studio es la versión 6.0A.
¿Los ha instalado alguien? ¿En Vista x64, con o sin SP1? No hace falta que lo hagáis, ya que si bien se instalan perfectamente, cuando utilizamos el nuevo “Windows SDK Configuration Tool” para cambiarle al VS2008 el SDK activo, lo rompe y lo deja incapaz de compilar; en el caso del SDK de Vista, ya no es posible crear aplicaciones en C++/CLI, y en el caso del de Windows Server, nativas. Tras comprobar que la instalación del SDK del Server falló, y un par de cuelgues duros de Vista durante la reinstalación, al final el problema que presenta el SDK del Server es el mismo que el del Vista.
Tampoco vale la pena que utilices dicha herramienta para volver al status anterior: El Visual Studio 2008 ya no te volverá a funcionar a no ser que desinstales los SDK (menos mal).
¿Solución? Ninguna. Silencio administrativo.
Windows Vista SP1
Antes de la salida pública del SP1 los suscriptores a la MSDN también tienen acceso a dicho Service Pack. Ciertamente pagar una suscripción a la MSDN cada vez tiene menos sentido, sobre todo las caras, ya que MS va liberando poco a poco casi todo lo que antes costaba dinero o tenías que ser un Partner para obtenerlo. Como consecuencia de ello, los subscriptores pusieron el grito en el cielo y al poco se permitió la descarga del SP1. Decir que tampoco a los MVP que no fueran betatester del propio SP1 nos dieron acceso a él…
Pues bien, tras estar un par de semanas con él instalado de forma limpia, es decir, instalas el Vista, luego el SP1 y sigues con todo lo demás, ya que los chicos de las altas esferas han decidido que no se pueda crear un CD integrado, mis conclusiones no podrían ser más pésimas. Vamos allá.
Windows Mail. Si antes del SP1 era pésimo, después de él sigue siéndolo. Es decir, los parpadeos continúan, los autismos también, y en general los problemas de que adolece se siguen presentando de igual forma, aunque con un, digamos, 10% menos de frecuencia.
Arranque y apagado. Ninguna mejora. Tarda la misma eternidad en arrancar y parar, y durante el arranque sigues dejando de tener todo funcional hasta pasado un buen rato después del que te muestre el escritorio.
Autismos varios. Es decir, esas congelaciones que se producen en ciertas aplicaciones se vienen produciendo con algo menos de frecuencia, pero siguen pasando.
Otros. Parece ser que sí que han mejorado algo la I/O por prioridades, y ahora copia y mueve archivos mucho más rápido, pero siguen los autismos en cuanto a arrastrar y soltar. El IE se sigue cayendo solo igual que antes, el explorador sigue sin recordar posiciones ni ciertas configuraciones y en general, salvo la copia, la gestión de archivos sigue siendo tan mala que antes, lo que me lleva al siguiente punto.
No se copian ni mueven todos los ficheros
Pues lo dicho. Así que ojito con copiar y luego borrar el original sin comprobar la copia. Me da igual que se deba a los hooks de terceros o a lo que sea. Es completamente inaceptable. Ni siquiera Linux en sus peores días hacía eso.
Antes del SP1 experimenté el problema de dos formas distintas. En la primera, al mover ficheros, en el origen quedaban restos que si bien se habían copiado, no se habían borrado. En la segunda, al borrar ficheros, me pasaba lo mismo, pues supuse que se debía a que alguien bloqueaba el fichero y se olvidaba de liberarlo, ya que la única forma de poderlos borrar era saliendo y volviendo a entrar en la sesión. Como eran ficheros que no se habían visto en ningún momento, el candidato que generaba el problema debía ser el propio Vista.
Después de eso otro MVP comentó que le parecía que le había fallado la copia, pero no estaba seguro de ello.
Y yo me quedé con la mosca detrás de la oreja… Después instalé el SP1, y observé el problema que cuento en la sección siguiente (que ya es el súmmum de todo), por lo que procedí a limpiar la unidad…
¿Imaginan? Pues se quedaron ficheros sin mover. Bien es cierto que eran ficheros ocultos y de sólo lectura, pero otros ocultos y de sólo lectura se movieron, así que ese no era el motivo. Un arrastrar y soltar los copió, pero el problema está ahí.
Y vayamos al apoteósico final.
Particiones sucia
Tengo una partición con la que trabajo todos los días, donde está el código fuente de la empresa, almacenes de correo y demás. El System Restore está deshabilitado globalmente. La unidad es NTFS formateada desde la misma instalación. Pues bien, de 11 GB de datos que hay (datos en disco, teniendo en cuenta el tamaño del cluster), en el disco hay realmente más de 20 GB. Tras borrar todo lo del disco, me seguían quedando esos 10 GB ocupados, o sea, que son basuras que deja el Vista, ya que a nivel de usuario no queda nada. Activando mostrar ficheros ocultos por el sistema operativo, tomo posesión de "System Volume Information" y veo un montón de archivos con nombres de GUIID con tamaños de entre varios cientos de megas y gigas… Y de repente, antes de que me dé tiempo de mirarlos, ¡desaparecen! y la unidad se queda como debería haber estado en un primer momento.
¿Qué se oculta ahí? ¿Por qué desaparecen esos ficheros nada más verlos? ¿Qué son esos restos (el system restore no puede ser ya que está desactivado) que Vista no quiere que tengamos acceso a ellos?
Me hubiera gustado haber recibido una respuesta oficial, creíble y documentada. Pero no fue así. Silencio administrativo.
¿Por qué roba Vista ese espacio en disco?
Podría ser un resto del shadow copy de la copia de seguridad del propio Vista: en ese caso, chapuzas dobles y triples. Nunca los programas de copia de seguridad que han acompañado al sistema operativo han sido buenos, pero llegar hasta ese punto… Es decir, tengo programado el Backup del Vista para que haga copia de esa unidad sobre otra, si son los restos de la preparación del shadow, lo dicho.
Podría ser que aunque se ha desactivado globalmente el System Restore, Vista pasara olímpicamente de nosotros e hiciera copias… en una unidad que nunca lo ha tenido activado. Aquí entraríamos en cuestiones de otro tipo, como las actualizaciones ocultas que se instalan de forma oculta aunque las tengas desactivadas… lo que me parece un punto de soberbia, prepotencia y abuso de poder completamente intolerable…
No se me ocurren otras posibles causas, y las que se me ocurren mejor no mencionarlas (qué casualidad que sólo pase en la única partición en la que hay código fuente…) etc.
El tema es que han pasado unos días y ya tengo otra vez la partición con 5 gigas de basura… Pero esta vez no se me escapan…
Eso será después de que instale XP.
February 8, 2008
Hemos leído: Serial Port Complete 2nd. Ed. (Jan Axelson)
Otro que ha caído como una pera madura de un árbol. Y no es porque no traiga información, que la trae, y mucha, sino porque… porque… aparte de los elementos de diseño hardware, que no me interesan lo más mínimo –para eso están los chatarrillas, como yo los llamo[1]-, no me aportan nada nuevo, sino más bien… se queda muy corto.
Pero veamos qué trae el libro. Los primeros capítulos son un poco rollo, con una serie de explicaciones teóricas sobre nomenclaturas, características y opciones. Los siguientes sí que les pueden resultar interesantes a los diseñadores de hardware, ya que incluso modela ecuaciones mediante código. Habla de largos máximos, de atenuaciones, masas, etc., todo ello cuestiones de diseño que no me incumben y de las que sé lo justo para poder lidiar con los problemas habituales cuando se programa con puertos serie de por medio. Sigue con más explicaciones teóricas sobre los puertos serie de los PC.
Luego trae dos capítulos enormemente interesantes ya que la literatura sobre el tema es bien escasa: RS-485, que es un RS-232 en el que se usan dos hilos diferenciales como soporte físico para el envío y recepción de datos, lo que tiene la ventaja de que al ser una señal diferencial tiene muchas menos pérdidas y en consecuencia permite cables de mayor longitud, y la desventaja de que no se permite enviar y recibir simultáneamente ya que ambos hilos se usan a la vez para la comunicación. Eso no quiere decir que no pueda ser bidireccional, sino que o bien se envía o bien se recibe. Personalmente he usado ampliamente este soporte físico para realizar comunicaciones dentro de una máquina, y lo cierto es que no tengo claro si las ventajas superan a los inconvenientes o al revés. En fin, con estos dos capítulos cualquiera se vería cualificado para diseñar sobre este formato de hardware.
Quiero hacer notar (y esto no viene en el libro), que existen protocolos más modernos y robustos basados en los hilos diferenciales, como el CAN, que usa la Mercedes dentro de sus coches. La ventaja es que resulta enormemente seguro en cuanto a pérdida de datos y que muchos temas de protocolos –como el de lucha para conseguir el control del bus- se llevan a cabo a nivel de hardware, con lo que liberan al programador de tareas bastante complejas y que llevan mucho tiempo desarrollar.
El capítulo 8 desvaría un poco, y seguro está puesto para llenar páginas: habla del Bluetooth, Wifi, etc. como protocolos serie… El primero de ellos lo es, pero el segundo seguro que no.
Dos capítulos dos sobre desarrollo con puertos serie bajo .NET (y a C++ y VB que los zurzan). Nada nuevo bajo el sol y que no esté contemplado más o menos bien leyendo la documentación de la MSDN. Aparte de algún gazapillo perdonable (un System.String se envía en formato UNICODE, no ASCII, sólo por poner un ejemplo, ya que hay alguno más), el texto trae los típicos ejemplos realizados en VB.NET y C#, facilones y evidentes. En el segundo profundiza algo más, explicando los eventos y cómo realizar programación asíncrona, aunque sólo toca la superficie.
Y es que lo que trae es apenas nada en cuanto a desarrollo de software en el que intervenga una o más UARTS, os lo digo yo que llevo buena mili con el tema.
Luego viene un capítulo sobre puertos serie sobre dispositivos, explicando un modelo de Microchip que incorpora una UART, tratando sobre cuestiones de diseño y de programación en C sobre dicho micro. Ciertamente es un capítulo loable, pero dado que cada microprocesador incorpora las UART y sus registros a su manera, tan sólo sirve para dar una ligera idea de lo que uno se puede encontrar cuando programa un procesador.
Y digo flojito porque una obra que se precie de completa debería haber contemplado este tema con mayor profundidad. Debería haber explicado cómo funcionan las UART dentro de un microprocesador grande, con toda la parafernalia de los niveles de interrupción, vectores instalables y prioridades de la UART frente a los timers (por poner un ejemplo). También debería haber cubierto en profundidad los chips UART, pastillas que llevan 4, 8 ó 16 UARTS y que se anexan al bus de datos (y cómo integrarlas dentro del firmware), o cómo montar cores UART dentro de una FPGA o similar…
Sí que trae un capítulo interesante pero de nuevo flojito sobre diseño de protocolos sobre canales serie. De nuevo apenas contempla lo más básico.
Finaliza con mucho rollo sobre convertidores USB-RS232, muchos de los temas apenas son interesantes porque de eso ya se ocupa el fabricante del chip, pero hay que llenar páginas poniendo rollos en lugar de escribir sobre lo que hay que escribir.
El libro no está mal, pero apenas cubre una iniciación tanto en el diseño del hardware como en el desarrollo con estos dispositivos; es perfectamente válido para cualquiera que empiece con el tema, pero desde luego no llega a los talones de cualquier aplicación o diseño de la Vida Real™.
[1] Que nadie se tome a mal el nombre. Dentro de lo que yo llamo nomenclatura simpática, un diseñador de hardware en un chatarrillas, un diseñador gráfico un pintamonas, y un jodío developer un chafateclas, y desde luego no hay ninguna intención peyorativa, sino que simplemente me resultan nombres tan irreverentes como yo mismo soy.
Hemos leído: USB Complete. Third Edition (Jan Axelson)
Esta lectura, más que por devoción, ha sido por obligación, aunque cuando compré el libro lo hice por devoción. Es decir, mi idea era leer algo serio sobre USB para ver cómo funcionaba, y trastear un poco para poder añadir esa especialización a mi currículum… Pero tras haberlo leído mejor no pongo nada, que ya tengo suficientes quebraderos de cabeza.
He dicho que la lectura ha sido por obligación, y es cierto. Hace dos semanas me pidieron que evaluara hacer un driver USB para una placa que estamos haciendo, o más bien que estoy haciendo, pues estoy más o menos a cargo del tema completo, como si hubiera vuelto a mis orígenes… Recuerdo el cambio de color de cara del ingeniero cuando le comenté que tenía que hacer una placa conectada por USB (lo que, ahora que conozco el percal, entiendo perfectamente, ya que el chaval no es ningún gallina en cuanto al diseño de hardware se trata). Comenzamos a planificar el tema, y mientras él buscaba y evaluaba microprocesadores, chips necesarios y todo eso, yo leía afanosamente este libraco (encima estaba sin ordenador, con mi anterior placa base en el cielo –o infierno, vaya usted a saber- de las placas base, y esperando lo que ahora disfruto). Nos cruzamos una buena cantidad de llamadas, vamos lo típico, que si esto vale esto, que si necesito xx MPIS, que si puedo usar BGA, que cambia esto del protocolo de comunicaciones porque no voy a poder atenderte… Hasta que acabé de leer el libro. Entonces hice La Llamada.
YO: ¿Querías un USB puro?
JEFE: Sipi.
YO: 6 meses + fase beta + fase de pruebas sólo para el driver…
JEFE: ¿A cualo?
YO: Lo que oyes.
JEFE: ¿No se puede acortar?
YO: No creo… -Pensando que en un par de meses podría estar, pero porsiaca…
JEFE: Pos vaya…
YO: Peeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeero…
JEFE: ¿Sí? – Con tono esperanzado
YO: Podemos usar esta solución. Cada chip lleva número de serie, el driver te lo da el fabricante, acortamos también el desarrollo de nuestro hardware porque la solución nos da un acceso directo a una UART, hay dos fabricantes, si uno falla tenemos al otro aunque cambiarlo requiere cambios en el hardware…
JEFE: Pos fale…
Y luego hice la otra llamada: -Gallinica, que vamos a usar lo que has propuesto. Vuelta del color a su cara, y todos tan contentos.
Bueno, después de la anécdota, vamos al libro.
No está mal, aunque no es lo que esperaba (más bien el USB no es lo que esperaba, pero bueno). Comienza explicándonos qué es el USB, su velocidad y lo compara con otros protocolos serie, describiendo también los cuatro modos y las cuatro velocidades junto a qué soporta cada clase…
Luego entra de lleno a explicar cómo funciona el protocolo en sí, cómo se forman los comandos y su contenido, de qué tenemos que preocuparnos y de qué no (por ejemplo, todo el tema de códigos de control, CRCs y demás lo hacen los chips directamente).
Y aquí es donde me entró el canguelo… En mi vida laboral he diseñado varios protocolos que han ido por encima de hilos RS232, RS485, Paralelo (no necesariamente de 8 bits), sockets, incluso pines sueltos de un microprocesador, pero nunca he visto algo tan barroco ni tan enrevesado. Es increíble la complicación del protocolo, tan increíble que pienso mal de él. Que si transaction que si token packet, que si pid, que si endpoint, que si data, que si frames, que si latencias… Y luego están los cuatro modos. Y no hablemos de la negociación e identificación cuando se enchufa un dispositivo USB con las quince espuertas de mensajes que se tienen que enviar, y más aún cuando arrancan y soportan ahorro de energía y cosas así. Ahora entiendo por qué hay tanto driver mierdoso… Lo que es mierdoso no es el driver, sino el protocolo.
Digo que pienso mal porque un protocolo diseñado con esta mala leche sólo puede tener alguna de estas explicaciones: O bien los que lo hicieron cobraban por tiempo de discusión, o por complejidad o quisieron cerrarlo tanto que sólo unos pocos fueran capaces de entender y desarrollar el protocolo…
Continuando con el libro, el autor nos cuenta cómo funciona cada modo y las APIs que hay para hacerlo funcionar. También comenta –por encima- cómo hacer un driver. Y da algunos ejemplos sin mucha utilidad para trastear desde Visual Basic y C++. El libro está centrado en explicar el funcionamiento de la clase HID (Human Interface Device), quizás la más común de todas las clases de dispositivos USB aunque también entra en las demás.
El libro termina con las especificaciones eléctricas y con un capítulo sobre algo llamado USB-on-the-GO, que no he leído y que tampoco sé qué es ni me interesa saberlo.
Hemos leído: Multithreading Applications in Win32 (Beveridge y Wiener)
Este libro ha sido una completa decepción ya que sin ser malo –que lo es-, no me ha aportado nada nuevo. Yo esperaba descubrir esplendorosas técnicas más allá de lo habitual… pero o no las hay o los autores no se enteran mucho.
El libro ha envejecido bastante bien, ya que si obviamos los comentarios sobre Windows 3.x, 95 y NT, casi todo lo explicado continua siendo actual y útil… bugs incluídos. Eso no es óbice para que los ejemplos sean pésimos y empleen código bastante malo y desactualizado. Si bien lo último es lógico, lo primero no. Las carencias del código llevan hasta a no liberar objetos del núcleo y del GDI en algunos ejemplos… algo inaceptable dentro del código moderno (y menos aún del anterior, ese olvido terminará degradando Windows 95 hasta que nos fuerce el reinicio).
Los autores presentan una descripción somera sobre multitarea, y luego pasa a contarnos cómo usar un hilo mediante CreateThread() y cómo esperar a que éste acabe de forma incorrecta –ellos mismos lo dicen-. Tras eso nos cuentan cómo utilizar las funciones Wait… (WaitForSingleObject, WaitForMultipleObjects, …) para recibir el evento de finalización.
Luego viene un capítulo clásico que explica las secciones críticas, los mutexes, los semáforos y los eventos (éstos últimos explicados de forma bastante oscura y barroca), sin aportar nada nuevo y enfocados al tema práctico, explicando con qué funciones de Win32 se pueden hacer.
También nos cuenta cómo suspender y activar los hilos, y cómo cambiar su prioridad.
Un tema bastante interesante, pero visto casi de pasada, es la entrada/salida asíncrona. Es decir, la I/O overlapped, las APC y los completion ports. La Overlapped I/O funciona ordenando una lectura/escritura y esperando el evento correspondiente de que se ha producido (así es cómo funciona la E/S dentro del .NET y por eso un programa en C# que lea y escriba frecuentemente se ejecuta incluso más rápido que un programa hecho en C++ siempre que no use esas técnicas, que suele ser lo habitual). Las APC son algo más o menos igual, pero los completion ports son una cucada (y es una de las cosas que había leído que existían pero que no había mirado todavía); Creas un pool de hilos, los asignas mediante unas funciones y e voilà, el sistema se encarga de ir despertando/durmiendo los hilos conforme vayan haciendo falta. Todo un hándicap para la programación de servidores.
Y luego entramos en la segunda parte, los temas avanzados, como el uso de volatile y el concepto de transacción. Continúa un nuevo capítulo sobre el uso de hilos con la CRT, o más bien qué cosas hay que tener en cuenta cuando se usan hilos que llaman a funciones de C estándar.
Otro más sobre C++ y cómo C++ facilita la eliminación de errores potenciales gracias a los constructores/destructores, así como la técnica para que las funciones miembro de una clase puedan ser usadas como funciones de hilo…
Sigue con los hilos bajo MFC, la separación entre hilos con bucle de mensajes e hilos sin él, y las cosas que hay que tener en cuenta cuando un hilo maneja o accede a ventanas…
El GDI y las cosas a tener en cuenta cuando se trabaja con elementos del mismo, que no son seguros en cuanto a hilos y la demostración de que la peor técnica para controlar ventanas MDI es usar un hilo para cada ventana.
El siguiente es un poco risible. Cómo depurar programas que usen hilos; en fin, aparte de lo habitual, el autor recomienda determinación, paciencia y creatividad.
Los dos siguientes, pese a ser poco profundos, resultan interesantes: DLL e hilos dentro de ellas y comunicación entre procesos: ficheros mapeados en memoria, pipes, memoria compartida, mailslots, DDE, OLE… El problema es que cuando podría profundizar, toca todos estos temas de refilón. En fin.
El libro termina desvariando un poco, con un capítulo sobre diseño de aplicaciones, ISAPI y poco más.
Ciertamente es una obra demasiado sencilla dado lo complejo del tema y pese a ser tan monotemática…
