martes, 29 de noviembre de 2016

Comentarios en el lenguaje de programación C

Cuando hablamos de comentarios en el lenguaje de programación C, hablamos de una serie de anotaciones que inician con los caracteres /* y terminan con */,  los comentarios en un programa nos sirven para dar explicación de ciertas partes de código que necesariamente requieren de una explicación para un mejor entendimiento de los mismos, cuando digo que necesariamente requieren una explicación me refiero a que la mayoría del código debe de ser fácilmente interpretado por cualquier programador sin necesidad de usar comentarios, los comentarios deben de ser evitados la mayor parte del tiempo dentro del código y debemos usarlos dentro de manera ordenada, legible y correcta.

A continuación se muestra el ejemplo de un comentario:

/* Código comentado aquí */

/* Este es otro ejemplo que nos
 * muestra un párrafo que
 * está comentado.              
 */     

La forma de comentar en C++ y en el estándar C99 haciendo uso de "//"  no debería ser usada en el lenguaje de programación C si se desea portabilidad hacia compiladores anteriores a C99, estos caracteres no son permitidos en compiladores que están basados en el estándar C89/C90 y para efectos de portabilidad darían problemas al momento de compilar el código. Aunque esta forma de comentar sea aceptada por algunos compiladores, no es parte del estándar C89/C90 y si queremos asegurar compatibilidad hacia atrás no debemos de usarlos.

Los comentarios deben de usar únicamente el estilo /* . . . */ como anteriormente se comento, solo si se desea potabilidad hacia compiladores basados en el estándar C89/C90 y también si el estilo de programación adoptado por el programador lo requiere. 

Como regla obligatoria general los comentarios no deben de estar anidados, un comentario debe de comenzar con /* y continuar hasta encontrar un */, pero nunca deben de tener estos caracteres en medio del comentario.

Si por algún motivo se tienen que comentar secciones de código, estas secciones no deben de ser comentadas haciendo uso de los caracteres mencionados anteriormente, para comentar secciones de código debemos de usar las directivas condicionales de compilación (#if . . . #endif).

#if 0
/* Código comentado aquí*/
#endif

Debemos de tener en cuenta que en ciertas secciones de nuestro programa vamos a tener comentarios, por tal motivo no podemos comentar código con (/* ... */), por que estaríamos violando la regla de no tener comentarios anidados.

Es bueno que al momento de hacer comentarios sigamos reglas y cierto estilo al escribir, las siguientes reglas me han ayudado a tener un código de fácil mantenimiento, inteligible y mi propio estilo de programación, estás reglas las he tomado en el transcurso del tiempo y están basadas en algunos estándares ya establecidos y posiblemente les sean de ayuda para algunos de ustedes:
  • Nunca usar comentarios anidados.
  • Los bloques de comentarios describiendo estructuras, tipos, etc., deben de comenzar con / en la columna 1, * en la columna 2 en cada una de las siguientes líneas del bloque y terminar con */ en las columnas 2 y 3. (el comando grep '^.\*' agarrará todos los bloques de comentarios dentro del archivo). 
  • Los comentarios hechos dentro de bloques de código, deben de tener la misma alineación que la de código descrito.
  • Para los comentarios de una sola línea, comentarios que usan el carácter //, no compatible con C89/C90, y que se encuentran al final de la línea, siempre use la misma alineación, para que los comentarios estén alineados. 
  • Al inicio de cada programa escriba comentarios de lo que hace el programa.
  • Para las funciones escribir comentarios con información de que la función hace, la explicación de los parámetros (valores, significado y uso) y valor que regresa
  • No contradecir el código con los comentarios, usarlos únicamente para explicar código que podría no ser fácilmente entendido.
  • Defina comentarios para las secciones de código en la cual no se hace nada, especificando que ahí no se hace nada.
Resumiendo acerca del uso de comentarios en el lenguaje de programación en C, tenemos lo siguiente:
  1. Use los caracteres /* y */, para realizar comentarios de una y varias líneas en C, si se requiere que el código sea compatible con los compiladores anteriores y sea portable entre los compiladores de C, ya que está forma de comentar es usada en todos los compiladores de C.
  2. Nunca use comentarios anidados.
  3. Use los caracteres // para realizar comentarios de una sola línea. Tenga en cuenta que estos caracteres no serán compatibles con compiladores anteriores a C99. Si se desea fácil portabilidad no use estos caracteres para realizar comentarios.

miércoles, 16 de noviembre de 2016

Lectura de pulso con prueba Digital

In work . . . 


Esta prueba la realicé debido a que los recursos del equipo que tenía no eran suficientes para llevar a cabo una prueba mixta en la cual podría haber usado los módulos de medición de frecuencia y pulsos que tenía. Mi sistema estaba al límite y y tenía los recursos digitales asignados, me decidí por esta opción que es una buena alternativa para lograr el mismo resultado, debido al ancho de pulso pequeño, esta prueba generará resultados más precisos a pulsos de mayor tamaño.

Una parte muy importante en el desarrollo de sistemas de ICT (In Circuit Test), es el desarrollo de pruebas digitales, en esta ocasión desarrollaremos  una prueba digital que consiste en lo siguiente:

"Leer un pulso de 10uS de ancho que sale de un microcontrolador después de que este es encendido o reiniciado, el pulso sale después de 300 milisegundos."
Las condiciones son las siguientes:

  • El Pin de entrada MCLR/Reset es el número 4.
  • El pin de salida del pulso es número 14.
  • El microcontrolador se alimenta con 3.3V.
  • El tablero se encuentra panelizado y tiene 20 tableros que conforman el panel.
  • El microcrontrolador tiene u2 como designador y es de 20 pines.

En la siguiente figura se muestra una representación de ejemplo de un uC, con su pin de "Reset" y su pin de salida.


En la siguiente figura se muestra una representación de la señal de salida y también de la señal de MCLR/Reset.


La prueba digital está formada de 4 secciones, listadas a continuación:

  • Sección de declaración
  • Sección de tiempo
  • Sección de definición de vectores
  • Sección de ejecución de vectores

Sección de declaración y tiempo

En esta sección es la primera parte del código de una prueba digital, aquí colocamos información referente al tipo de prueba y las características del dispositivo a ser probado, está información le servirá también al IPG Test Consultant para la generación de recursos necesarios para hacer la prueba. Una librería dígital de prueba debe al menos tener esta sección para poder hacer la asignación de recursos a la hora de desarrollar un fixture de In-Circuit, en caso de no hacerlo la asignación de recursos generará nuevos alambres y talvés tarjetas adicionales en caso de no tener recursos suficientes.

En el siguiente código he incluido comentarios para la explicación del mismo, en realidad estos comentarios no son necesarios y pueden ser eliminados del código, todo comentario comienza con el signo de admiración "!".


! Function: Read pulse
! Revision: A
! Author:   César Alvarez    

test digital; PulseID    ! Definición del tipo de prueba y variable para regresar información del pulso
enable loop counter      ! Falla en un loop si no sale después de repetirse ciertas cantidad de veces

sequential               ! Tipo de prueba secuencial

!!!! Inicio de la sección de tiempo

test time 600m           ! 600 mS como timeout de prueba, es necesario para cuando se tienen loops que pueden entrar
                         ! en un ciclo infinito, si la prueba no termina después de 600mS la prueba fallará
vector cycle 650n        ! Vector cycle de 650 nS, definición de tiempo del vector
receive delay 500n       ! Receive delay de 500nS, definición de tiempo de espera para el receive una vez comenzado el vector

!!!! Fin de sección de tiempo

default device "#:u2"    ! dispositivo al cual se le hará la prueba      
set terminators to on    ! Activa las terminaciones diode-clamp en los circuitos de los receivers

!!!! Sección de asignación de nombres de pines
assign PIN_7 to pins *
assign PIN_8 to pins *
assign PIN_9 to pins *

assign ALL_INPUTS to pins 3, 4, 11, 12, 15, 16, 17, 19
assign ALL_OUTPUTS to pins 2, 13, 14

assign PIN_2 to pins 2
assign PIN_3 to pins 3
assign RESET to pins 4   ! Se nombra RESET a pin 4
assign PIN_11 to pins 11
assign PIN_12 to pins 12
assign PIN_13 to pins 13
assign DATA to pins 14   ! Se nombra DATA a pin 14
assign PIN_15 to pins 15
assign PIN_16 to pins 16
assign PIN_17 to pins 17
assign PIN_19 to pins 19

assign PIN_18 to pins *
assign PIN_6 to pins *
assign PIN_1 to pins *
assign PIN_5 to pins *
assign PIN_10 to pins *
assign PIN_20 to pins *
!!!!

family TTL                ! Dispositivo TTL

!!!! Declaración de formato de pines
! Declaración de pines de power
power PIN_7, PIN_8, PIN_9

! Declaración de pines de entrada
inputs ALL_INPUTS, PIN_3, RESET, PIN_11, PIN_12, PIN_15, PIN_16
inputs PIN_17, PIN_19

! Declaración de pines de salida
outputs ALL_OUTPUTS, PIN_2, PIN_13, DATA

! Declaración de pines no digitales
nondigital PIN_18, PIN_6, PIN_1, PIN_5, PIN_10, PIN_20
!!!!

capture DATA pack 16      ! Formato de captura de datos, se explicará más en detalle después

! Definición de referencias para pin de salida 14, todo arriba de 1.5 es considerado 
! nivel lógico alto y todo debajo de 0.9 es considerado nivel lógico bajo
set ref on device "#:u2" pins 14 to rh 1.5, rl .9



Sección de definición de vectores

En esta sección definimos los diferentes vectores que usaremos para probar el dispositivo. Los vectores se pueden definir en cualquier order, un bloque de vectores se ejecutará en un ciclo de vector.

La definición de vectores se hace mediante bloques de vectores y cada block contiene las instrucciones las cuales conforman un vector. Cada bloque comienza y se define con la instrucción "vector [name]" y termina con la instrucción "end vector".


vector Keep
  set RESET to "k"
end vector

vector Resetto1 ! Reset to high level
  initialize to Keep
  set RESET to "1"
end vector

vector Resetto0 ! Reset to low level
  initialize to Keep
  set RESET to "0"
end vector

vector Code_1
  initialize to Keep
  set DATA to "1"
end vector

vector Code_0
  initialize to Keep
  set DATA to "0"
end vector

vector Code_x
  initialize to Keep
  set DATA to "x"
end vector

Sección de ejecución de vectores

Esta es la última sección de la prueba y contiene los vectores que serán ejecutados. Esta sección puede contener bloques de ejecución de vectores o también conocidas como unidades digitales y subrutinas digitales, las subrutinas deben de estar antes que las unidades en caso de que se tengan y por lo menos se debe tener una unidad digital, lo cual es una excepción cuando solo es un "Setup" digital.

Las unidades digitales contienen las instrucciones de los vectores a ejecutar, la unidad se define con la instrucción: "unit [optional name]" y terminan con la instrucción "end unit" y pueden contener ejecución de vectores, llamadas a subrutinas digitales, repeats, loop, homing loops y vectores PCF. 

La sección de ejecución de vectores de nuestro problema se muestra a continuación:


unit "Read Pulse"

  repeat 100 times ! MCLR/Reset a 0 por 100*650nS = 65uS
  execute Resetto0 ! reset the uC
  end repeat

  execute Resetto1 ! MCLR/Reset a nivel lógico alto

  homingloop
  execute Code_1 exit if pass ! Espera hasta encontrar un nivel lógico alto, sale si lo encuentra
  end homingloop              ! de no encontrarlo se termina la prueba una vez pasan los 600mS de test time

  capture
  repeat 20 times  ! Una vez encontrado el pulso, almacena el nivel lógico de DATA por 20 
  execute Code_x   ! ciclos de vectores y deja de capturar los estados lógicos
  end repeat
  end capture

  fetch PulseID    ! Guarda en PulseID la información obtenida

end unit

Lo que hace el código anterior es lo que sigue:

  1. Hace un reset al microcontrolador colocando el pin MCLR/Reset a un nivel lógico de 0 por 65uS. Y lo mantiene en un nivel alto lógico para continuar con la prueba.
  2. En el pin de salida espera a que se encuentre un nivel lógico alto, esto lo hace haciendo uso del homingloop, este es un ciclo infinito en el cual si no se encuentra la condición esperada, marcará un error cuando se llegue el tiempo definido con la instrucción test time, por eso es necesario definir está instrucción en la prueba. Hay que tener en cuenta que el homingloop tendrá que ejecutar un vector para poder verificar que se ha encontrado un nivel lógico alto y aproximadamente otro vector para salir y comenzar la ejecución de la captura de pulsos. Estos pulsos tienen que eliminarse del total de los vectores que determinan el ancho del pulso y ser considerados en los cálculos.
  3. La opción capture guarda los estados lógicos de un conjunto de vectores y los guarda en la RAM del capture, esta puede ser serial o paralela, en nuestro ejemplo usaremos serial. El número de bits que pueden ser capturados depende de la memoria RAM del sistema.

Para poder darnos una idea de como determinar el valor de un pulso de forma digital, mostraremos un ejemple de como representar un pulso de 100uS con un contador que incrementa cada 1uS, supongamos si la entrada cambia al nivel lógico bajo el contador se reiniciará a cero y cuando esté en nivel lógico alto incrementará cada 1uS en uno.

Entonces si el pulso tardar 100uS en nivel lógico alto el resultado del contardor será 100 y el valor del pulso será de 100uS, si el contador cuenta 97, el valor del pulso será 97uS y así de esta forma podemos determinar con una resolución de 1uS el valor del pulso que deseamos encontrar.

Esta misma analogía es la que será usada para la medición del pulso de 10uS que queremos leer, pero en este caso los incrementos del contador serán de 650nS.

La siguiente figura nos dará una mejor idea de como capture toma la información y también como debemos interpretarla para poder decidir si nuestro pulso se encuentra dentro de las tolerancias requeridas.


Si dividimos 10uS entre la duración del ciclo de vector 650nS nos daremos cuenta de que aproximadamente 15 ciclos de vectores sumados nos representarían un pulso de este tamaño.

La información se almacena en la RAM de la siguiente forma como bits consecutivos:

Pulso de 100 uS ideal, se representa:   1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  0  0  0  0  0

Solamente 20 bits son los que coloqué en la representación del pulso ya que el capture se hace por ciclos.

Si vemos la siguiente instrucción: 

capture DATA pack 16

El número del final (16) representa como se agrupará la información que toma el capture en la variable en la cual se almacenará, en este caso dice que se agrupara en conjuntos de 16 bits, entonces si tomamos los primeros 16 bits tendremos la siguiente representación hexadecimal:
Pulso -> 0xFFFE, en decimal 65534

Por tal motivo solamente usamos una variable para poder extraer el valor del pulso, ahora supongamos que queremos agrupar la información que extraemos en grupos de 8 bits, la instrucción que usariamos sería la siguiente:

capture DATA pack 8

Nuestro resultado del pulso lo tendríamos que almacenar en un array, de la siguiente forma, antes tendríamos que declarar la prueba digital y el array en el cual se guardará la información de la siguiente forma:

test digital; PulseID(*)

Haciendo esto nuestro resultado quedaría agrupado en el array de la siguiente forma:

PulseID(0) = 0xFF
PulseID(1) = 0xFE
PulseID(2) = 0x00

En el caso de que sea de 1 se tendría lo siguiente:

capture DATA pack 1

PulseID(0) = 1
PulseID(1) = 1
PulseID(2) = 1
PulseID(3) = 1
      .
      .
PulseID(15) = 1
PulseID(16) = 0
PulseID(17) = 0
PulseID(18) = 0
PulseID(19) = 0

Entonces el resultado dependerá de como lo agrupemos y como nosotros lo queramos interpretar, también esto influirá en la cantidad de memoria que ocupará la variable en la cual se está almacenando el resultado.

En el transcurso de unos días agregaré el código usado en el testplan para hacer la prueba a nivel array y la interpretación de los resultados, gracias de antemano por su paciencia, espero les sea de ayuda y espero sus comentarios.

In work . . . 

viernes, 11 de octubre de 2013

LG P990 Root y Actualización de Android

Hacer "Root" y actualizar tú telefono LG P990 al sistema android 4.2.2

Hola, saludos a todos, esta es la primer publicación en mi blog, espero les guste y les sea de utilidad para todos aquellos que tienen un celular LG P990 y desean actualizarlo al sistema android 4.2.2.

Muchos habrán escuchado acerca de hacer tú telefono celular android "root", pero . . . hacer esto con tú celular te dará alguna ventaja sobre el que no es "root". Si bien el simple echo de tener el sistema operativo android en tú telefono celular te da muchas ventajas sobre otros celulares que no lo tienen, como por ejemplo: puedes instalar diferentes aplicaciones, juegos, etc. Pero al hacer "root" tú telefono te dará la oportunidad de hacer todavía muchas cosas más con el, algunos ejemplos son: incrementar la velocidad de tú celular, instalar sistemas operativos personalizados, etc.

Hacer "root" tú telefono es generar en este privilegios de administrador, una vez hecho esto con tú telefono tendrás privilegios de administrador sobre el y no estarás límitado a sus diferentes características, tendrás acceso a las modificaciones de programa en el nivel más bajo, ten en cuenta que esto invalida la garantía de tú dispositivo y hay muy poca posibilidad de que puedas completamente dañar tú telefono por siempre.

Una vez que obtengas privilegios de administrador, no solamente tendrás las aplicaciones normales que puedes obtener, tendrás acceso a una cantidad más de aplicaciones, podrás hacer cosas que los manufacturadores o google quieren que tú no hagas. 

Una de las quejas más comunes de los usuarios de Android es acerca de la actualizaciones del sistema operativo de los telefonos, hay veces que dependiendo del manufacturador, o deja de ofrecer el servicio de actualización a un nuevo software o tarda una eternidad para sacar la actualización de tú dispositivo. Los desarrolladores de Android afrecen nuevos sistemas operativos meses antes que se tenga la actualización de tú telefono, al tener tú dispositivo root podrás fácilmente instalar estos sistemas operativos. Una vez que tú telefono tiene privilegios de administrador, es solo cuestión de encontrar el sistema operativo que quieres y que esté optimizado para tú dispositivo en específico e instalarlo, más adelante veremos que es en realidad muy fácil instalarlo.

También cuando comienzas a tener problemas de descarga de batería o cuando se hace lento, hay diversas aplicaciones que una vez con permisos de administrador podrás instalar sistemas que te permitirán optimizar de diversas formas tú telefono, variar la velocidad del procesador del mismo y seleccionar reglas de uso para cuando duermes, vas al trabajo, etc.

Una vez que tú celular tenga privilegios de administrador y lo uses durante un tiempo de daras cuenta de la infinidad de cosas que puedes hacer.

Crea privilegios de administrador (root) en tú celular LG P990


A continuación colocaré los pasos necesarios para crear privilegios de administrador en tú celular LG P990, ten en cuenta que esto invalidará la garantía de tú celular.


  1. Descarga los controladores (drivers) de tú telefono para tener acceso ADB (Android Debug Bridge) a tú telefono,  estos los puedes encontrar directamente en la página de LG o también deberían de venir incluidos al momento de comprar tú celular. Un ejemplo de donde podrías descargar tus controladores lo puedes encontrar haciendo clic aquí.
  2. Instala los drivers de acuerdo al sistema operativo que tengas instalado (windows XP/Vista/7/8).
  3. Conecta tú telefono y habilita "USB Debugging" (Settings-Applications-Development)
  4. Instala y ejecuta SuperOneClick, lo puedes encontrar aquí.
  5. Haz clic en "Root" y espera hasta que termine el programa de configurar tú telefono.
Después de hacer estó ya tendras privilegios de administrador en tú telefono. Para comprobar que tú telefono tiene acceso de administrador, puedes descargar la aplicación "Root Checker" desde Google Play y verificarlo.

Instalar el nuevo ROM en tú celular
  • Primeramente asegurate que tú celular se encuentre cargado minimo a un 70% para que el proceso no se vea interrumpido, también asegurate que tú batería se encuentre en buenas condiciones y no se descargue de forma anormal.
  • Te recomiendo que hagas un respaldo de cosas importantes de tú celular, tales como contactos, mensajes, etc.
  • Instala CWM recovery "ROM Manager" para grabar cualquier ROM a tú celular. Lo puedes descargar desde Google Play y tú telefono tiene que tener privilegios de administrador. Puedes visitar el sitio en el siguiente enlace: http://www.clockworkmod.com/.
  • En este punto el telefono debe de estar "root", con una considerable cantidad de carga, el respaldo de los datos debe de estar realizado y el programa "ROM Manager" debe de estar instalado. Procederemos con la descarga del ROM que deseamos instalar en nuestro celular. Existen varios ROMs los cuales podemos usar y los cuales podemos encontrar en internet, pero en esta guía usaremos el ROM localizado en la página oficial de desarrollo, esta puede ser encontrada aquí.
  • También será necesario instalar las applicaciones de google de forma separada, para eso descargamos el ROM de estas aplicaciones haciendo clic aquí.
  • Haz una copia a la memoria externa de tú celular de los dos ROMs descargados, el rom del Android que instalaras y el rom de las aplicaciones de Google.
  • Desconecta el telefono de tú computadora y reinicialo en modo de recuperación, esto lo puedes hacer presionando y manteniendo presionada las teclas "Disminuir Volumen + Encendido/Apagado" al mismo tiempo mientras lo enciendes hasta que se habra el modo de recuperación.
  • Primero haz un respaldo usando "backup" en "backup and restore". Esto hará un respaldo en tú memoria externa que puedes usar después para restaurar el sistema.
  • Seleccione "wipe data/factory reset & wipe cache partition" para limpiar los datos y cache de la memoria del telefono.
  • Una vez terminada la limpieza, es necesario seleccionar "install from sdcard" y "choose zip from sdcard". Seleccione el zip del ROM del sistema descargado, confirme con "Yes".
  • Esto tomará unos cuantos minutos, al final volverás a ver el menú de nuevo.
  • Repita el procedimiento desde "install from sdcard" pero ahora para las aplicaciones de Google.
  • Después de la instalación de los dos ROMs, seleccione "go back" y "reboot system now", para reiniciar el sistema e iniciar con el nuevo ROM instalado.
  •  
Advertencia: el material presentado es para ser usado bajo tú própio riesgo y puede dañar tú dispositivo, pero si sigues las instrucciones al pie de la letra no tendrás muchos problemas. Si no estas de acuerdo con lo mencionado no sigas las instrucciones mencionadas en este articulo.

Si no te gusta el ROM nuevo puedes regresar al que tenías anteriormente instalado haciendo uso del ROM de respaldo que generaste en los pasos anteriores.

Muchas gracias a todos por sus opiniones y dudas, estaré al pendiente en caso de que necesiten algo más.