Posts in category ecamino

Cambiar TAGS de un fichero por información

Esto que voy a contar de forma breve tiene relación con el escrito titulado "¿tres capas?"1 en el cual expongo una forma de realizar interfaces de usuario de forma sencilla mediante la utilización de html y cgi.

En un momento dado relato que el cgi escrito en C/C++ deberá pasear el documento html que se quiere presentar al usuario y que se cambiarán ciertos TAGS presentes en dicha página por datos que decide la capa de negocio o parte inteligente de la aplicación.

Esto, en general, se hace parseando el documento de la forma en que se describió en el ártículo anterior, pero hay una forma mucho más rápida y sencilla la cual paso a describir ahora.

Sencillamente en el documento que será presentado se añade un %s en cada punto donde se quiera añadir algo de forma dinámica. Para que quede claro, se escribe el documento html a mano o como queramos y donde nos interese añadir algo se introduce un %s.

Supongo que cualquiera que sepa algo de C/C++ ya ve por donde me estoy encaminando. Efectivamente, cuando se va a presentar el documento y ya lo hemos leido del disco duro y lo tenemos en forma de string, sin parsear ni hacer nada complicado se puede sustituir el %s por lo que queramos con un sencillo "sprintf()" y lo mejor es que podemos poner tantos %s como queramos.

Os recomiendo man sprintf, pero en general se utiliza mucho y seguro que lo conocéis. En cualquier caso y por encima, el sprintf es exactamente igual que un printf() pero en vez de utilizar la salida estándar, lo que hace es copiar el string en la memoria que se haya reservado a tal efecto, sustitiyendo, en este caso, todos los %s por lo que se ponga a partir del tercer parámetro.

Ejemplo clarificador:

sprintf(ptr_memoria,"HOLA %s ADIOS","PEPE");

Como resultado, tendríamos un string llamado ptr_memoria con la información "HOLA PEPE ADIOS"

Si queremos sustituir un valor numérico podríamos poner %d y un número directamente. Sigo recomendando un man sprintf a quien no lo conozca adecuadamente.

Bueno, lo contado es algo muy sencillo y desde luego es muy probable que este método lo utilice mucha gente, pero puede ser que no a todo el mundo se le ocurra que poner un %s directamente en los documentos nos facilite el trabajo tanto.

Voy a poner una clase de C++ que hace exactamente esto, por si alguien quiere utilizarla o le da una idea. No está muy comentada, pero es bastante autoexplicativa.

Las funciones open_file, read_file, close_file son una encapsulación de funciones de C para el manejo de ficheros y realizán exactamente lo que su nombre indica.

La función CambiarTag puede cambiar hasta 6 %s que se pasan en un array de strings, con eso me vale a mi de sobra y el que quiera más parámetros o que se realice de forma iterativa que lo piense un poco.

Recordar que hay que liberar la memoria que se devuelve en esta función en donde se llame.

#include "GeneradorHtml.h"
#include "../comunes/file_control.h"
#include <string.h>
#include <stdio.h>
#define MAX_ELEMENTOS 6
GeneradorHtml::GeneradorHtml(char *lruta)
{
  char *ptr_ayuda;
  open_file(lruta,"r");
  read_file(&ptr_ayuda);
  texto_html = new char[strlen(ptr_ayuda)] ;
  strcpy(texto_html,ptr_ayuda);
  close_file();
}
GeneradorHtml::~GeneradorHtml()
{
  delete texto_html;
}
//Hay que liberar en donde se utilice la memoria que se devuelve.
char* GeneradorHtml::CambiarTag(char lnuevo_elemento[][100])
{
  int llen_elementos = 0;
  int llen_html =  strlen(texto_html);
  int llen_total = 0;
  char *lnuevo_html = 0;
  int i;//iterador
  for(i = 0; i<MAX_ELEMENTOS; i++)
  {
    if(lnuevo_elemento[i] == 0)
      break;
    llen_elementos = llen_elementos + strlen(lnuevo_elemento[i]);
  }
  //espacio necesario para albergar todo el texto html cambiando las partes necesarias.
  llen_total = llen_elementos + llen_html;
  lnuevo_html = new char[llen_total+100];
  switch(i)
  {
    case 0:
      strcpy(lnuevo_html,texto_html);
    break;
    case 1:
      sprintf(lnuevo_html,texto_html,lnuevo_elemento[0]);
      //sprintf(lnuevo_html,texto_html,"HOLA");
    break;
    case 2:
      sprintf(lnuevo_html,texto_html,lnuevo_elemento[0],lnuevo_elemento[1]);
    break;
    case 3:
      sprintf(lnuevo_html,texto_html,lnuevo_elemento[0],lnuevo_elemento[1],lnuevo_elemento[2]);
    break;
    case 4:
      sprintf(lnuevo_html,texto_html,lnuevo_elemento[0],lnuevo_elemento[1],lnuevo_elemento[2],lnuevo_elemento[3]);
    break;
   case 5:
      sprintf(lnuevo_html,texto_html,lnuevo_elemento[0],lnuevo_elemento[1],lnuevo_elemento[2],lnuevo_elemento[3],lnuevo_elemento[4]);
    break;
    case MAX_ELEMENTOS:
      sprintf(lnuevo_html,texto_html,lnuevo_elemento[0],lnuevo_elemento[1],lnuevo_elemento[2],lnuevo_elemento[3],lnuevo_elemento[4],lnuevo_e
    break;
  }
  return lnuevo_html;
}

¿Tres capas?

Lo primero que quiero decir es que la idea de escribir este texto surgió de un conversación con un desarrollador de entornos web que programa en C# (sharp). También diré que las ideas que trataré de exponer no son propias, a parte de que deben estar en muchos libros, a mi me lo explico un buen amigo.

El caso es que dicho desarrollador me enseñaba con orgullo las cosas que hacía, lo bonitas que le quedaban y la magnífica herramienta de desarrollo de que disponía.

Bien Yo, que no soy desarrollador de páginas web y que me dedico a los entornos empotrados probablemente sea el menos indicado para hablar de este tema, pero para esto está la web, para decir lo que quieras y en este caso sin ser un experto, tampoco creo que vaya a decir algo sin sentido.

Dicho programador me enseñaba como loco lo fácil que era crear una aplicación y lo mucho que le ayudaba la herramienta, y la verdad es que tenía razón, una vez que aprendes a manejar la herramienta, cosa que no parecia inmediata realmete parecia todo muy fácil.

Cuando me enseñaba el código que se generaba me di cuenta que se mezclaba la capa de presentación con la capa de negocio, vamos para entendernos bien, el html y la algoritmia de todo tipo se mezclaba.

Traté de hacerle entender que hacer las cosas así no erá una buena dinámica, pero en seguida me di cuenta de que recibía frases prepotentes del tipo, tu dedicaté a tu mi..da de C que yo he estudiado para esto y sobre todo, me dedico a esto. Lo cual me lleva a pensar que no le enseñaron bien, o que no es un buen profesional o que yo mejor me dedique a mi mi..da de C.

Después de una dura lucha al final lo único que pareció hacerle pensar un poco es que si habóa que cambiar la forma de la página desde el punto de vista de presentación de la interfaz, se podría hacer si todo estuviera bien separado sin compilar código y sin que el desarrollador estuviera presente. Por ejemplo lo podría cambiar un diseñador gráfico sin ayuda de ningún tipo. Pero fué sólo un espejismo,pensar debió pensar pero al final decidió que no le interesaba lo que le contaba.

Yo creo que podría haber mostrado más interes, la gente cree que lo sabe todo y es mejor ser más humilde y tratar de aprender de las buenas ideas, no porque sean mias, es que además están en los libros.

En resumen, no le convencí y yo me sigo dedicando a mi m...a de C.

Bueno voy a contar como hago últimamente las aplicaciones que necesitan una interfaz de usuario. Simplemente es algo que me sirve a mi, y no tiene porque gustarle a nadie más, pero me parece útil y sobre todo extremadamente sencillo ya que en general la parte de la interfaz gráfica suele ser tediosa y complicada, sobre todo en lo que se refiere al manejo de eventos.

Lo que hago es hacerlo todo en un entorno web. Me da igual si se va a ejecutar en local, me simplifica muchísimo el trabajo y dependiendo del nivel que se tenga en entornos web puede quedar aplicaciones muy vistosas. Dejo claro que NO es mi caso. Es decir creo las interfaces necesarias con html y algo de javascrip si es imprescindible. La parte inteligente en C o C++.

Esté método tiene ciertas ventajas, que creo son importantísimas, y supongo que también tiene desventajas, quizás una de ellas es que puedan ser un poco más lentas, y que se necesita un servidor http.

Por supuesto si quieres hacer un juego con gráficos o cosas así este no es el método adecuado, pero sí para realizar las típicas aplicaciones con formularios para rellenar.

Las ventajas claras son:

  1. Tu aplicación de un plumazo se convieten en distribuidas. Cualquier persona puede acceder a ellas desde donde quiera, en forma local, red privada, o incluso internet.
  1. Es ideal para aplicacione donde varias personas tengan que utilizar la misma aplicacion. Pones en un servidor tu aplicación y todo el mundo la ejecuta desde donde quiera y a la vez.
  1. Yo diría que casi cualquiera sabe algo de html, y si no se puede utilizar un editor de html de los de arratrar y soltar. Un libro de javascrips para alguna cosa un poco más complicada y listo.
  1. Si lo haces bien tienes separada totalmente la capa presentación, la lógica y la capa de persistencia o administración de datos.

Mi forma de trabajar es, creo la página html a mano o con un editor. Donde quiero colocar información que se consigue con la parte lógica del programa pongo un tag del tipo info1, info2 ... de tal forma que antes de servir la página se parsea y se cambia los tags por la información deseada.

Es decir, aunque la página html tiene entidad propia, no la sirvo directamente desde el servidor, la sirve la capa de negocio que lee del disco el fichero con la información html y la presenta. Antes de presentarla la parsea por si tiene que cambiar algo.

Es decir, la única interación entre las capas o nexo de unión son esos pequeños tags que se sustituyen en el momento de presentar la página. Una vez creado el sistema se puede cambiar el aspecto de la página si recompilar nada.

La lógica de negocio la realizo en C o C++, por lo que estoy creando un CGI. Este tipo de aplicaciones ya no se utilizan mucho porque tienen ciertas desventajas con respecto a, por ejemplo, un servlet o una JSP. De entrada son más peligrosas con los recursos, OJO, ya que si no programas bien puedes tirar un servidor, pero como son mis aplicaciones y me fío de mi mismo, lo hago así, por comodidad ya que son los lenguajes que manejo a diario.

Otro inconveniente es la forma en que el servidor replica la aplicación en memoria cuando hay varios usuarios utilizándola a la vez, siendo menos eficiente en el caso de los CGI ya que lanzan tantas aplicaciones como usuarios la utilicen, tal cosa se solventa de forma más ligera, mediante hilos en otro tipo de aplicaciones como las servlets. Pero vuelvo a lo mismo, en general sólo yo utilizo las aplicaciones y en cualquier caso los PC actuales pueden soportar muchas aplicaciones en memoria sin problemas.

En resumen, un poco de html, un poco de mi...a de C básico y un apache y montas un buen chiringo.

Por cierto, como siempre digo, ¿Alguien sabe en qué está escrito el kernel de linux? SÍ, EN ESA MI..DA DE C.

Comment by chous on 2006-12-21 11:43:29

Lo que has escrito es casi un WTF1 :).

Lamentablemente los desarrolladores web están sobrevalorados. Son profesionales cuya competencia fundamental es conocer los menús del Eclipse o del Visual Studio .Net, sin cuestionarse el código que generan (en el caso de que sean conscientes). Y lo digo teniendo en cuenta que me dedico a hacer aplicaciones web :).

El caso es que es a donde se tiende: tanto la guerra de IDEs (en Java Eclipse vs IntelliJ vs NetBeans), como lenguajes de programación (a partir de Java 5 ya la fase de generación está incrustada en el propio código), tal como pasó con los editores WYSIWYG HTML, siguen empeñados en hacer al hombre más tonto (menos capaz de entender situaciones y por tanto de resolver problemas), y a la máquina más lista.

Respecto a la parte técnica de tu exposición, en mi opinión lo más cercano a una separación exhaustiva y rigurosa entre la capa de presentación y las demás es lo que propone StringTemplate. Ni JSP, ni JSF. Pero claro, es menos user-friendly y por tanto no tiene éxito.

Al final uno se ve obligado a tomar una decisión: ser mejor haciendo lo que hace o que lo que uno hace le dé menos trabajo.

La moderación agotadora.

El problema de ser una persona reposada en sus razonamientos, sin grandes extremismos y con una actitud de ... digamos ... no odiarlo todo, es que acabas siendo el abogado del diablo en casi todas las ocasiones.

Da igual el que tema que se esté debatiendo, para cualquier interlocutor que tenga una postura sobre el tema a debatir suele parapetarse en uno de los extremos posibles, sin que en ningún momento se les pueda atraer hacia opiniones diferentes a la suya.

Por cierto que las ideas podr­an ser tanto razonadas como aprendidas, pero en mi opinión priman claramente los conceptos aprendidos ya que incluso los que parecen más despiertos tienen ideas de otros más despiertos aún. Es más, mientras más poderosa sea la mente del que influye más radical se mostrará alguién influenciado, y por supuesto las declaraciones desprendidas, serán dadas como propias.

Considero agotador tanta discrepancia, todo el mundo "sabe de todo" y su opinión siempre es la más válida y no sólo eso, además es siempre una opinión colgada del extremo más alejado posible sobre la opinión del otro.

Parece que sólo hay rojos, o fachas, Catalanes y Españoles, Pinguinos o ventanas, hardware o software, palms o Pockets PC, reproductores RIO o iPods, vinilos o CD (.. sí, sí los hay que afirman que los vinilos tienen un no sé qué...). Vamos la lista es interminable.

En fí­n que no sé muy bien por qué escribo esto, quizás vaya de virtuoso ya que según el refrán la virtud está en el centro. De cualquier manera lo que sí quiero constatar es que he aprendido a callar en muchas ocasiones. Pocas veces merece la pena decir algo, no vas a convencer a nadie y peor que el intento infructuoso es que dependiendo de la opinión del contertulio hay que decirle unas cosas u otras. Cuando te gustan dos cosas tienes que luchar con los dos extremos a los que sólo una de las dos cosas le satisface.

Cuántas veces me he encontrado hablando maravillas de los Pingũinos y de las ventanas e intentanto una lucha horrible y agotadora que no lleva nunca a ningún sitio. Es como querer que uno del Barcelona se haga del Madrid o viceversa o como si un bisexual tratara de convencer a los heterosexuales que tener relaciones con uno del mismo sexo es bueno.

Como último apunte diré que llevado al extremo esto es lo que pasa en el mundo, es lo que hace que la gente se esté matando y haciendo barbaridades impensables para la época en que vivimos. Es incluso comprensible, dado lo salvaje del ser humano, que cuando el hombre estaba aprendiendo a ser hombre se despacharan a gusto. Pero ahora en pleno siglo XXI cas­ nos despachamos igual, no sólo por cosas materiales, lo cual es íncreible pero comprensible dada la avaricia demostrada por la historia, sino también por conceptos filosóficos del tipo religioso o cultural, lo cual señores más que increíble es un tremendo despropósito y una demostración de maldad.

Me despido sin más, esperando no haber aburrido mucho, a su vez espero que estas palabras resuenen en la conciencia de algún adicto a lo extremo, aunque ... en realidad no hay salida para el ser humano.

Empotrar Linux. Primera parte.

Hace mucho tiempo que pienso que, en general, la gente no tiene una idea clara de cómo empotrar Linux en una placa de propósito general y poder aprovechar toda la potencia de un sistema Linux en un entorno reducido y estoy seguro que es un tema muy interesante para muchos.

Hay varios problemas que planean sobre esta inquietud. La primera pregunta que todo el mundo se plantea es, ¿Dónde va a ser almacenado el sistema operativo? ¿El kernel? ¿El boot? .....

En definitiva estas dudas se resumen en dos, que serían:

  1. ¿Cómo arranca, en general, cualquier chipset formado por un procesador, memoria, dispositivo de almacenaiento y entradas/salidas de proposito general?
  2. El sistema operativo llamado Linux que vamos a empotrar, ¿Qué es? ¿Qué elementos lo forman?

La respuesta a la pregunta planteada no es sencilla de desarrollar pero trataremos de realizar un resumen suficiente para hacerse una idea.

El lector que pretenda entererarse con detalle y de una forma completamente exhaustiva sobre este tema que nos ocupa le recomiendo que se compre un buen libro y que no siga leyendo. Si por el contrario se busca una idea general, es posible quedar m¡s o menos satisfecho con lo siguiente.

Básicamente la BIOS1, al recibir un reset realiza una serie de comprobaciones del hardware y cuando decide que todo es correcto va a una dirección que coincide con el primer sector de un dispositivo de almacenamiento (configurable en la BIOS) donde se va ha ejecutar un peque±o programa MBR (Master Boot Record) que está ocupando tan solo el tama±o de el primer sector del dispositivo. Es decir, es muy pequeño, para hacerse una idea en un disco duro serán 512 Bytes, desde ese pequeño programa se puede llamar a otros de mayor tamaño, pero eso es otra historia.

Este programa es el boot de arranque, fundamental para todo este entorno y que para concretar diremos sería el famoso LILO2 o GRUB3 para arquitecturas típicas de PC y por ejemplo el uBoot para uClinux (Linux para dispositivos sin MMU4). Por cierto, si se me permite, no desprecies la potencia de un dispositivo de estas características, por ejemplo un Coldfire.

Una vez que se ha ejecutado el boot, éste llama al kernel5 de linux, cuya imagen no ocupa mucho. Podéi­s mirarlo en vuestro PC (/boot) y quizás os sorprendáis, 1,2 MB más o menos. El kernel es una especie de interfaz entre todas las aplicaciones que corren en el PC y el hardware. Es decir los drivers etc.

Normalmente se le dice al boot la ruta donde se encuentra la imagen kernel, por ejemplo /boot/vmlinuz..... Por otro lado nos encontramos con que necesitamos un rootdir o root file system, que es t­picamente lo que nos encontramos al hacer un ls en el raiz /. La información de dónde se encontrará el rootdir también se encuentra en el boot y esta información será el dispositivo de almacenamiento donde se encuentre el árbol de directorios. Por ejemplo (hda0).

Recomiendo hechar un vistazo al menú de arranque:

cat /boot/grub/menu.lst

En este punto comentaremos que dado el memoria disponible en entornos empotrados es muy escasa tendremos que intentar que el rootdir ocupe lo menos posible, es m¡s aunque la imagen del kernel no ocupa mucho también debemos de preocuparnos de reducirlo al máximo. Un simple make menuconfig, e intentamos reducir a lo m­ínimo posible los módulos innecesarios.

De lo contado hasta ahora, se extrae que montar un linux es algo bastante sencillo en teor­ía, complicándose posteriormente en la práctica.

El resumen ser­a que en algºn dispositivo de almacenamiento grabamos como buenamente se nos ocurra un rootdir, y en el mismo u otro dispositivo de almacenamiento grabamos el kernel de linux. A la BIOS le decimos que arranque de donde tengamos el boot (LILO, GRUB, uBoot)y al boot le indicamos donde est¡ el kernel (ruta) y el rootdir (dispositivo). No parece muy complicado, ¿no?. Bueno por supuesto es una pregunta retórica y en la práctica sá es bastante complicado por los tí­picos problemas de qué es antes el huevo o la gallina; quiero acceder a un disco duro pero los drivers se encuentran en el mismo disco duro ...... quiero flashear mi rootdir pero claro como no hay nada montado no tengo la herramienta de linux que flashea ...

También es complicado conseguir la configuarción del kernel que permite arrancar nuestros dispositivos, etc.

Un método interesante para arrancar que tienen los boot es mediante un tftp6 (trivial ftp) con lo que no es necesario tener nada en nuestro dispositivo, salvo el boot de arranque. La imagen del kernel y la del rootdir estar¡n en cualquier sitio que posea un demonio servidor de tftp. Vamos que lo recomiendo para hacer diversas pruebas r¡pidas de si lo que se est¡ compilando es una piedra que no arranca o nos sirve.

Otro consejo que quiero dar es que si no se tiene un dispositivo externo de flasheo tipo JTAG o BDM se tenga un cuidado extremo en los flasheos que se realicen mediante el propio linux ya que si se flashea algo inadecuado que no arranque nos quedaremos sin la posibilidad de hacer nada y con una placa inservible e insalvable, salvo con el flaseador externo que he comentado.

Para terminar comentaré que con lo contado, más o menos, se puede vislumbrar que es lo mismo tener un potente PC o una placa de propósito general con digamos un H8 o un cold fire a 66Mhz y una peque±a memoria flash como unidad de almacenamiento. Cambiara la potencia y los dispositivos, pero la idea es la misma, BIOS, boot, kernel, rootdir.

Espero poder realizar un segundo articulo con los pasos detallados, uno a uno, de cómo instalar un pequeño sistema en una placa de proposito general sin disco duro y con pocos recursos.

Espero que se entienda el ámbito puramente divulgativo de estas l­neas y sin intención de ser una referencia importante sobre este tema, en ningºn momento. Creo que queda patente en todo momento que son ideas generales, no suficientes para afrontar proyectos de ningún tipo. Simplemente espero que alguien pueda leer este peque±o articulo y decir: No puedo hacer nada con esta información pero si encuentro a alguien que sepa podré hacerle las preguntas adecuadas.