Autor Tema: De ASM a JALv2  (Leído 3761 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado vixctor

  • PIC16
  • ***
  • Mensajes: 109
Re: De ASM a JALv2
« Respuesta #15 en: 24 de Marzo de 2015, 23:45:01 »
No es lo mismo la memoria RAM de una computadora que la memoria RAM de un microcontrolador...

Para empezar, la memoria de una computadora es dinámica, pues cada bit está formado por un capacitor que guarda una pequeña carga electrica (la carga se interpreta como un 1 y la descarga o no carga como un 0)
Debido al diminuto tamaño del capacitor, su carga se pierde en poco tiempo debido a las fugas inherentes al dielectrico del capacitor (SiO2, Gate simple o dual), por esa razón, una memoria dinámica necesita constantemente ser refrescada, para volver a cargar cada uno de sus capacitores, por esa razón se la llama dinamica...

Ahora bien, la enorme ventaja de la memoria dinámica es el bajo costo de implementación, y la alta densidad de memoria que presenta como sus principales ventajas, al estar formada por nanocapacitores...
La desventaja es que necesita constantemente refresco y es mas delicada ya que las celdas de memoria se pueden dañar por descargas electrostaticas, picos de voltaje etc. (el dieléctrico es del orden de los nanómetros)

En un microcontrolador, la memoria es ESTATICA, ya que cada bit esta formado por un Flip Flop que permite cambiar su estado logico de 0 a 1
Al estar formada por compuertas lógicas, no requiere de refresco constante y es muy robusta, esa es su principal ventaja, su principal desventaja es el costo de implementar cada registro y su poca densidad de memoria...

En un PIC, CADA registro esta formado por un registro de N Flip Flops (Depende de la familia) estáticos, por esa razón su tamaño es limitado al orden de los pocos Kilo Bytes...

Si todos los registros en el PIC están hechos de la misma manera, y WREG es uno de ellos, podemos decir que WREG o cualquier registro ya sea SFR o GPR tiene la misma tasa de probabilidad de tener un fallo eventualmente...

Pero si tomamos a WREG, que es el registro principal y que es escrito y leido MILLONES de MILLONES de veces durante la vida util de un PIC, y WREG tiene la misma tasa de probabilidad de fallos al ser un registro ESTATICO como sus demás hermanos SFRS y GPRS, entonces podemos asumir que SI la memoria RAM (ESTATICA) fuera susceptible a fallos (por uso de RD-WR constantes), entonces WREG sería el registro con mas probabilidades de fallar al ser el registro que mas se LEE y se ESCRIBE todo el tiempo... y entonces un microcontrolador fallaria a los pocos meses (o semanas) de uso...

No es objetivo comparar los componentes (externos) de una computadora versus los internos de un microcontrolador... pues ademas de estar diseñados de manera diferente, en una computadora todo se interconecta a través de la motherboard por medio de zocalos, bases, extrusiones, con componentes hechos por diferentes fabricantes, de diversa calidad y precio además...

Resumiendo: No hay magia o fé al respecto, es ciencia y física pura.  La tecnología de una RAM ESTATICA (hecha con compuertas lógicas formando Flip Flops) hace que aunque la memoria sea escasa, sea MUY robusta, por eso ni siquiera los fabricantes ponen el numero de ciclos de lectura o escritura...

Por otro lado, la tecnología de la memoria RAM DINAMICA, esta basada en capacitores que guardan cargas electricas, de una manera similar, la memoria FLASH o EEPROM (Eraseable Electric Programable Memory) también se basa en la capacidad de almacenar cargas eléctricas pero a muy largo plazo (40 años), sin embargo, tarde o temprano la carga eléctrica de los celdas EEPROM o FLASH termina por perderse, y basta un solo bit, uno solo, para que un programa haga algo diferente a lo que originalmente tenía programado...

La única versión realmente duradera de una memoria ROM vendría siendo la PROM por mascara o la OTP, en donde cada bit es un fusible y solo es posible programarla una sola vez, pues al no haber capacitancias presentes sino fusibles, la vida útil de una PROM es larguísima....

Bueno, en fin, el tema del foro no era en relación a memorias, sino a JALv2, así que no tocaré más el tema, solo que asumir que lo menos probable que falle pueda fallar, (y hacer una advertencia a otros al respecto) es como decir que si tiembla es porque los dioses lo provocan por portarnos mal... (para advertir que se porten bien)...



Desconectado Leon Pic

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3610
    • Impresiones en 3D
Re: De ASM a JALv2
« Respuesta #16 en: 25 de Marzo de 2015, 13:41:47 »
Perfecto. Todo lo que explicaste, lo he aprendido hace ya tiempo. No ha cambiado nada.

Tampoco me has demostrado que las RAM no tienen límite de lectura/escritura. Lo único que indicas que la RAM su límite es muy superior a la ROM tal como lo que comenté antes (cuando dije que es exagerado su límite con respecto a la memoria de programa).

vixtor, no estoy luchando por demostrar quien tiene la razón. No es una pelea. De echo, corregí algo ya que daba una cosa por sentada; cuando en realidad debería decir que puede ser una de las razones. Y te agradezco por eso.



Si mis planes no cambian; hoy termino que las variables. Me falta explicar como se hace para pasar de un word, a un byte; por ejemplo.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1297
Re: De ASM a JALv2
« Respuesta #17 en: 26 de Marzo de 2015, 13:53:17 »
Sigue adelante Leon. Tus explicaciones son muy buenas y claras.
Este es un tutorial de JAL no de discuciones de que si la RAM de que si la ROM. Todo falla, nada es lo que es creado por el hombre es perfecto. Pueden ser miles las razones de falla en un microcontrolador. Yo he trabajdo durante 15 años diseñando circuitos integrados así que entiendo perfectamente lo de las RAM y las ROM, EEPROM, FLASH, etc.
De cualquier manera, si necesitas ayuda con algún ejemplo en la programación yo me apunto. Tambien tengo amplia experiencia programando microcontroladores PIC y no hace mucho comence con AVR (Arduinos) para ser mas especifico.

Saludos,

elreypic.

Desconectado Leon Pic

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3610
    • Impresiones en 3D
Re: De ASM a JALv2
« Respuesta #18 en: 29 de Marzo de 2015, 06:04:44 »
Algo que me faltó aclarar, es que JALv2 no acepta ARRAY de bit. Si hay librerías para hacerlo; pero es un trabajo para el CP del PIC; por lo que su uso debe ser cauto; ya que puede consumir memoria y tener que cambiar de pic, cuando con un poco de ingenio se puede solucionar sin esta opción. No obstante, si es necesario su uso, pueden buscar en la carpeta de librería la librería de array con bit.

Al principio del tutorial, habíamos visto el tamaño de las variables y constantes que podíamos utilizar; pero fue muy superficial su explicación. Hoy veremos más detalladamente las diferentes opciones de tamaño y signos de las variables y constantes.

Los números, están expresados en decimales:

BIT    0 .. 1
BYTE   0 .. 255
SBYTE  -128 .. 127
WORD   0 .. 65.535
SWORD  -32.768 .. 32.767
DWORD  0 .. 4,294,967,296
SDWORD -2,147,483,648 .. 2,147,483,647


Pero el compilador, puede aceptar que lo escribamos de la siguiente manera:

var byte*2 aa -- Esto equivale a word (var word aa)

De la misma manera podemos escribir:

byte*4 que es un dword

sbyte*2 que es un sword

sbyte*4 que es un sdword

Para el bit, es diferente. Poner bit*2 indica que se trabaje con dos bit en una variable. Como una posición de RAM del PIC es de 8 bit (byte) implica que usaremos solo dos bit de una posición de la RAM y serán los dos menos significativos.

Por ejemplo:

var bit*2 cc

El compilador realiza el siguiente trabajo interno

cc = (valor & 0x03)

Lo que realiza es una máscara a la posición de la RAM con la función AND. O sea:

cc = 0b00110101 (53 en decimal)

Como CC es bit*2; el compilador realiza lo siguiente:

    0b00110101
and
    0b00000011
---------------
    0b00000001


cc = 0b01 (0x01) y directamente ese valor será asignado a cc, aunque trabaje con dos bit. Recordemos que, si tenemos una variable/constante declarada como bit, cualquier valor asignado distinto de 0; será asignada como 1:

var bit bb = 25

El compilador, internamente lo cambiará y lo asignará como 1, por lo que bb = 1

Casting

En algún momento de nuestro programa, será necesario pasar una variable a otra; y que ambas variables sean de distintos tamaños.

VAR WORD xx
VAR BYTE yy

Si hacemos lo siguiente:

yy = xx

El compilador nos dará un aviso de advertencia (warning) informando la asginación a un tipo más pequeño y que el trucamiento es posible (warning: assignment to smaller type; truncation possible)
Para eliminar la advertencia debemos proceder de la siguiente manera:

yy = byte(xx)

Pero ¿como lo toma el compilador?
Lo que hace es la eliminación de los 8 bit más significativos de la variable word, para pasarlo al más pequeño. Por ejemplo:

xx = 0x0eff
yy = xx -- yy obtendrá como valor 0xff, eliminando 0x0e

En definitiva, cuando tengan que pasar de una variable más grande a una más chica, se tienen que asegurar que entre en el más pequeño. Es normal usar variables grandes para hacer operaciones matemáticas. En este caso, el resultado de esa operación matemática, tendrá que entrar en la variable más chica, ya que sino perderemos datos valiosos.

Pero esto es solo un caso a la hora de usar casting.
Podemos hacer lo siguiente:

VAR WORD xx
VAR BYTE yy

xx = yy * yy -- Esto no es lo uno realmente quiere.

Recuerde que un operador sólo ve sus dos operandos, no tiene otro contexto. Digamos que el valor de yy es 255.
En este caso xx será asignado un valor de 1: los ocho bits inferiores del resultado. 255 * 255 = 65.025 ( 0b1111111000000001)

xx = word(yy) * word(yy)

En este caso el valor de yy es promovido a una palabra, por lo xx se le asignará 65.025 que es más probable a lo que realmente deseaba hacer.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

Desconectado Leon Pic

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3610
    • Impresiones en 3D
Re: De ASM a JALv2
« Respuesta #19 en: 31 de Marzo de 2015, 09:34:39 »
Y para finalizar este tema; veremos como se pueden ingresar valores a nuestras variables y constantes. Son parecidos que en ASM, así que las mencionaremos por separados.

JALv2

Tipo de valor | Como se escribe.
Decimal         | 12
Hexadecimal     | 0xC
Octal           | 0q14
Binario         | 0b1100
ASCII           | "A"


ASM

Tipo de valor | Como se escribe.
Decimal         | .12
                | d'12'
                | D'12'
Hexadecimal     | 0xC
                | h'c'
                | H'c'
Octal           | 0q14
                | q'14'
                | Q'14'
Binario         | 0b1100
                | b'1100'
                | B'1100'
ASCII           | "A"


Con respecto al código ACSII, en ambos casos, el compilador remplaza dicho valor ingresado, por el correspondiente al código ASCII. Esto nos ahorra el trabajo de buscar el valor que deseamos. Además, el código se hace más legible.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

Desconectado Leon Pic

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3610
    • Impresiones en 3D
Re: De ASM a JALv2
« Respuesta #20 en: 22 de Abril de 2015, 02:45:39 »
PRAGMAs

Los PRAGMAs son directivas para indicarle al compilador, como vamos a trabajar, con qué vamos a trabajar y de que manera vamos a trabajar.
Algún PRAGMA omitido, o mal definido; pueden dar numerosos errores y/o un comportamiento erróneo de nuestro pic. Cuando digo una mala definición, no hablo de un error de sintaxis, sino de habilitar algo, cuando en realidad deberíamos deshabilitarlo.

Especificación del PIC a usar (TARGET CHIP)

ASM

LIST      P=16F877A  ; Utilizaremos el PIC 16F877A

JALv2

PRAGMA TARGET CHIP nombredelpic

Donde nombredelpic se debe reemplazar por el nombre del pic. Por ejemplo:

PRAGMA TARGET CHIP 16F877A -- Utilizaremos el PIC 16F877A

Por supuesto, que debemos reemplezar el nombre del PIC por el que vamos a utilizar. Hay otra manera de hacerlo:

CONST _target_chip = cexpr

CONST _target_chip = 18F4550


No debemos preocuparnos por especificar el tipo de PIC a utilizar porque el compilador no lo utiliza para hacer la compilación.

Especificación del reloj a usar (TARGET CLOCK)

Se debe indicar en Hz la frecuencia del reloj, con que va a trabajar nuestro microcontrolador.

JALv2

PRAGMA TARGET CLOCK cexpr

PRAGMA TARGET CLOCK 20_000_000 -- Utilizaremos una frecuencia de 20Mhz.

PRAGMA TARGET CLOCK 48_000_000 -- Utilizaremos una frecuencia de 48Mhz.

Como notarán, solo es necesario modificar el valor de la frecuencia, por el que vamos a utilizar.
Otra manera de especificarlo es:

CONST _target_clock = cexpr

CONST _target_clock = 48_000_000

Hay que prestar atención en aquellos PIC donde por medio de PLL, se cambian la frecuencia para obtener otra. Por ejemplo los Microcontroladores que tiene USB interno. Al USB se lo hace trabajar con 96Mhz, pero al PIC se lo puede hacer trabajar con 48Mhz aún teniendo un cristal de 20Mhz. En definitiva, hay que especificar 48Mhz y no 20Mhz.

La especificación de la frecuencia es necesaria especificarla, cuando se utilice la función _usec_delay(xx); o de las demoras que están en la librería  delay.jal

Configuración del PIC (TARGET FUSES)

Los microcontroladores, al ser diseñado para uso general, necesitan una configuración para realizar lo que nosotros queramos.

ASM

__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC  (etcétera).

JALv2

PRAGMA TARGET FUSES [cexpr0] cexpr

cexpr0  sólo se utiliza cuando existen varias palabras config en cuyo caso 0 es la primera palabra de configuración, 1 el segundo, y así sucesivamente. Noten que empieza de 0.

Otra manera de hacerlo es la siguiente:

CONST _config = cexpr
CONST _config [cexpr0] = cexpr

Como verán, se debe reemplazar cexpr con el valor correspondiente.
Un concejo. Chequeen la configuración que aparecen en los ejemplos que viene con el programa. Están en la carpeta llamada sample.

Configuración del PIC (TARGET opt tags)

PRAGMA TARGET opt tags

Esta es la opción más utilizada a la hora de realizar la configuración de nuestro PIC.

pragma target WDTPS         P32K        -- watch dog saler setting
pragma target WDT           CONTROL     -- no watchdog
pragma target CCP2MUX       ENABLED      -- CCP2 pin C1
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          EXTERNAL    -- master reset on RE3

(etcétera)

Para saber como configurarlo, además de chequear la ficha técnica (data sheet), podemos chequear el archivo donde están todos los nombres de los registros. Este archivo se incluye en nuestro programa para poder manejar dicho pic. Es el archivo cuyo nombre es igual al pic a utilizar. Al final de este archivo, se pueden ver todas las configuraciones del PIC. Por ejemplo 16F84A.jal; 16F877A.jal 18F4550.jal
« Última modificación: 22 de Abril de 2015, 02:55:42 por Leon Pic »
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

Desconectado Leon Pic

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3610
    • Impresiones en 3D
Re: De ASM a JALv2
« Respuesta #21 en: 22 de Abril de 2015, 22:25:00 »
Interrupción (INTERRUPT)

Sirve para generar el tratamiento de las interrupciones. Al momento, JALv2 no soporta interrupciones de bajo nivel (para aquellos pic que tienen más de un nivel de interrupciones). JALv2 trata a todas las interrupciones como de alto nivel. En los PIC que solo posean un solo nivel de interrupciones, es indistinto.

PRAGMA INTERRUPT { FAST | RAW | NORMAL | }

Según la configuración que elijamos { FAST | RAW | NORMAL | }, nos puede ahorrar trabajo a la hora de hacer el tratamiento de las interrupciones.

NORMAL:

W, STATUS, PCLATH, FSR, TBLPTR y _picstate son salvados dentro del tratamiento de la interrupción (ISR) y restaurados al salir.

PRAGMA INTERRUPT NORMAL

FAST:

_pic_state no es salvado ni restaurado. En este caso, el procedimiento de la interrupción debe ser escrito enteramente en ASM (ASSEMBLER) para evitar que se corrompa el área pic_state.

RAW:

No se salva ningún registro principal ni el _pic_state. Esta opción, solo nos garantiza que se entre en el vector de interrupción.

El tratamiento de la interrupción, debe ser escrito dentro de un procedimiento procedure(). Por ejemplo:

procedure interrupcion() is
pragma interrupt normal
   if (INTCON_TMR0IF) then
      if usb_iniciado == 1 then
         if usb_en_uso == 0 then
            usb_serial_flush()
         end if
      end if
      tmr0=64000
      INTCON_TMR0IF=0
   end if
end procedure

Más adelante, veremos como está compuesto el procedimiento [procedure()]

En ASM, se debe escribir el tratamiento de la interrupción dentro del vector de interrupción, por ejemplo:

ORG 0x04
nop
nop
nop

Donde ORG 0x04 nos indica que lo que sigue, el compilador debe escribirlo a partir de la posición de memoria 0x04 (que en algunos pic, corresponde al vector de interrupción).

ERROR

Este tipo de pragma, se utiliza mucho a la hora de crear librerías y funciones para nuestro PIC. En él, se puede dar un aviso de error de compilación debido a una mala configuración de la librería.

PRAGMA ERROR

Por ejemplo:

Dentro de la librería glcd_common.jal está el siguiente pragma error:

pragma error "GLCD_COLOR_BITS VALUE NOT SUPPORTED"

Si especificamos algo incorrecto, el compilador nos dará el error con el siguiente mensaje: "GLCD_COLOR_BITS VALUE NOT SUPPORTED"


INLINE

PRAGMA INLINE se utiliza dentro de una función function() o procedimiento procedure()

Cuando se llama a una función o a un procedimiento, el compilador lo hace por medio de un CALL y posteriormente sale con un RETURN. Pero su a una función y/o procedimiento es declarado como inline, obligará al compilador que se lo compile a continuación.

En ASM a un procedimiento o una función, se lo conoce como rutina. Las rutinas pueden ser ejecutadas con un CALL o con un GOTO. Pero si lo declaramos como pragma inline, un procedimiento o función, se comportará como una MACRO (en ASM); o sea, se copiará tantas veces como sea llamado. Lo malo de esto, es que podemos quedarnos sin memoria de programa; algo que también nos puede pasar en JALv2.
La estrategia de usar pragma inline es dentro de una función que llama a otra función; que a su vez puede llamar a un procedimiento; justamente nos evitará consumir mucha pila (STACK) del pic. Por cada llamada, se ocupará una posición en la pila (stack) del PIC. En algunos PIC tenemos hasta 8 niveles; por lo que podemos llamar hasta 8 veces a un función procedimiento. Y si usamos interrupción, ya no podrán ser 8, sino 7; porque debemos dejar uno libre para la interrupción.

procedure sumar () is
    a = a + b
end procedure

function restar () is
    pragma inline
    z = z - M
end function



Solo he echo especificación de los PRAGMAs más importantes. Si desean saber más sobre el resto, deben consultar el manual de JALv2. Por ejemplo, están los PRAGMA para cancelar diferentes tipos de advertencias y/o errores, de los cuales no recomiendo desactivar nunca. Las advertencias, son tan importantes como los errores. Una advertencia pasada por alto, puede implicar que nuestro PIC no se comporte como nosotros queramos.
« Última modificación: 26 de Abril de 2015, 07:31:23 por Leon Pic »
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.


 

anything