Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: WillyP en 23 de Marzo de 2010, 01:53:41
Título: Asm embebido en C18 explicado
Publicado por: WillyP en 23 de Marzo de 2010, 01:53:41
Como se menciona tanto a C como Asm me pareció mejor dejarlo en este sector general de microcontroladores Pic, si es mejor otro subforo algún moderador lo moverá hacia allí.
Esta explicación se limita solamente al compilador C18 bajo entorno MPLAB IDE y no abarca las diferencias que puedan existir para otros compiladores C.
Empecemos con una breve síntesis:
Embeber código Asm en C es muy diferente a escribir instrucciones Asm “in line” del tipo: _asm ….. _endasm Las directivas anteriores para el compilador son limitadas y no se permite todo el repertorio de instrucciones que ofrece el microcontrolador. En cambio Asm embebido, mezclado o enfrascado en un compilador C equivale a poder integrar un código escrito en Asm, un programa completo en Asm, rutinas específicas en Asm, etc y llamadas desde C como a una función. Como ejemplo se podría desarrollar 99% Asm con 1% C sobre un compilador C, a la inversa o en cualquier porcentaje que decidiera el desarrollador. Es interesante tenerlo presente y aunque no es nada nuevo, tal vez no es del todo aplicado o conocido y lo más importante es la simpleza de su implementación siguiendo solamente las directivas especificas que requiere el compilador C. De esto se trata.
¿Ventajas? Las siguientes:
1- Las ventajas sólo las puede encontrar el desarrollador según el proyecto, en mi caso no hay código en C18 que no tenga su cuota de rutinas con código Asm, pero es una decisión de cada programador.
2- Una rutina en Asm puede ser en muchos casos más reducida, compacta y optimizada ya que la escribe directamente el desarrollador y no el analizador o intérprete de lenguaje del compilador.
3- El C18 no hace uso del 100% del repertorio de instrucciones del microcontrolador, podríamos decir que un porcentaje de instrucciones quedan marginadas. Un claro ejemplo son:
CPFSEQ CPFSGT CPFSLT
Las anteriores instrucciones fueron incorporadas en los 18Fxxxx, especiales para comparaciones, y el C18 (por lo menos hasta la versión 3.32) no las utiliza en ningún momento.
4- Para los programadores en Asm que comienzan en C es una forma de seguir con Asm e ir incorporando rutinas en C a medida que avanzan con el lenguaje o las librerías especializadas del C en sus proyectos Asm (desde asm pueden ser llamadas funciones en C)
5- Para los programadores 100% C y quieren ir incursionado en Asm o utilizar librerías en Asm enlatadas en C.
6- Fin del eterno dilema: todo “C” o todo “Asm”. La tercera opción es que pueden trabajar juntos y de maravilla. ;-)
Requisitos: MPLAB IDE y tener instalado C18
Seleccionar C18 Toolsuite y crear un proyecto, salvando una plantilla con extensión .c y otra con extensión .asm
; Acá se pueden agregar definiciones, configuraciones como ; se hace habitualmente en ensamblador ; ...... ; ...... ; ......
; Variables:
; Las variables globales declaradas desde C pueden ser utilizadas desde las ; Rutinas Asm siempre y cuando sean declaradas en la cabecera del archivo Asm o ; bien desde un archivo .inc como externas:
; Ejemplo de variables char declaradas en C y utilizadas en Asm:
; Previo a rutinas de código Asm, debe declararse la directiva para el ; compilador:
UDATA_ACS CODE
; La directiva CODE puede ampliarse si es necesario con el direccionamiento de memoria ; donde deberían iniciarse las secciones de código, para los programadores en Asm sería ; el reemplazo de la conocida directiva ORG 0xXX
SECTOR_1 CODE 0x0800
; SECTOR_1 puede ser cualquier nombre que identifique una dirección de memoria donde ; comenzará a ensamblarse el código, en este ejemplo a partir de la dirección 0x800. ; Para que no se genere error al compilar debe ser una dirección diferente a cualquiera ; que haya sido previamente declarada en C que direccionen un mismo sector de memoria.
; Rutinas:
; RUTINA_1 o cualquier otro nombre, es la clásica etiqueta de Asm que hace ; referencia a una sección de código. Desde C18 es vista como una llamada a ; una función. Se finaliza con un RETURN y debe estar siempre presente la ; directiva GLOBAL <Nombre de rutina> en este caso GLOBAL RUTINA_1.
RUTINA_1:
RCALL Algoritmo ; ...... ; ......
RETURN
GLOBAL RUTINA_1
; El código asm que sigue a RUTINA_1 puede llamar a otras rutinas dentro de Asm ; como se hace habitualmente con CALL o RCALL. Puede ser una rutina o bien un ; programa completo en asm.
; También desde el código ASM pueden ser llamadas Funciones de C, ejecutarse, retornar ; y continuar la rutina en ASM, para esto hay que declarar previamente (en la cabecera ; del archivo asm o creando un archivo .inc) la directiva "extern" a la función que luego será ; invocada desde alguna rutina asm.
; En la cabecera del archivo Asm de esta forma:
; EXTERN <Nombre de la función de C>
; desde una rutina:
; CALL <Nombre de la función de C>
; Ejemplo:
EXTERN Funcion_C
; Esta rutina "Algoritmo" es llamada solamente por RUTINA_1 ; dentro de Asm por lo tanto no necesita la directiva GLOBAL ; pero hace una llamada a una función escrita en C y retorna. ; La función en C está declarada como externa y es tomada desde ; el archivo Asm como otra etiqueta más dentro del programa.
Algoritmo:
CALL Funcion_C ; ...... ; ......
RETURN
; RUTINA_2 y RUTINA_3 son ejemplos de rutinas que pueden ser llamadas ; por una o distintas funciones desde C
RUTINA_2:
; ...... ; ......
RETURN
GLOBAL RUTINA_2
RUTINA_3:
; ...... ; ......
RETURN
GLOBAL RUTINA_3
; Como todo programa en ASM no se debe olvidar finalizarlo con end
; Las rutinas o programas en Asm pueden seguir utilizando también las directivas EQU, ; CBLOCK ... ENDC, etc, siempre teniendo precaución de no cambiar algún dato utilizado ; por alguna variable de C
; Para mayor información consultar "Mixing C and Assembly" del manual MPLAB® C18 ; C COMPILER USER’S GUIDE.
Adjunto el archivo C18 de lo explicado anteriormente para compilar. No tiene código, puesto que se trata de un ejemplo explicativo, es sólo para despejar alguna duda desde la práctica. Luego de compilar se debe hacer correr con el MPLAB SIM activado y comprobar como interactúan las llamadas entre C y ASM.
Saludos Willy.-
Título: Re: Asm embebido en C18 explicado
Publicado por: bmfranky en 23 de Marzo de 2010, 05:17:59
Una fantástica explicación , WillyP. Es una gran forma de reutilizar mis rutinas asm, en los programas que inicio ahora en C.
Título: Re: Asm embebido en C18 explicado
Publicado por: LABmouse en 16 de Enero de 2011, 20:02:05
Hola WillyP, Muchas gracias por la explicación.
En este momento me enfrento a mezclar C18 con ASM, pero necesito declarar asm en una que otra linea del archivo main.c.
Pretendo hacer esto:
Código: ASM
_asm BCF PORTA,0 _endasm
Pero me marca error sin saber como solucionarlo.
en cambio si intento esto:
Código: ASM
_asm goto initio _endasm
Si funciona bien.. :?
Saben como declarar una linea asm de vez en cuando?
Título: Re: Asm embebido en C18 explicado
Publicado por: Suky en 16 de Enero de 2011, 20:25:24
Prueba implementadolo según datasheet:
Código: ASM
_asm BCF PORTA,0,0 _endasm
Título: Re: Asm embebido en C18 explicado
Publicado por: LABmouse en 16 de Enero de 2011, 20:58:57
Hola amigo Suky, Gracias!!!
Precisamente busque en el datasheet y encontre que
Código: ASM
_asm bcf PORTA,0,1 _endasm
el ultimo digito es llamado segun datasheet "a"
RAM access bit: a = 0: RAM location in Access RAM (BSR register is ignored) a = 1: RAM bank is specified by BSR register
Cual debería usar para obtener el mejor resultado?..Pareciera según los ejemplos que encontré, que siempre usan 1.
Cual me recomiendan?¿? Bueno pues compare con esta instruccion en C:
Código: C
PORTAbits.RA0=0;
revise el código generado y encontré que al colocar en asm 0 en el bit "a", simplemente no trabaja. Cuando se coloca 0, tanto la que yo escribo en ASM como la generada del código en C son totalmente iguales..
SALUDOS!!
Título: Re: Asm embebido en C18 explicado
Publicado por: Suky en 16 de Enero de 2011, 21:33:01
El registro BSR es para seleccionar el Banco. No me he puesto a estudiar el asm de los 18F, pero generalmente veo que el disassembly utiliza ACCESS, o sea 0 :rolleyes:
Saludos!
Título: Re: Asm embebido en C18 explicado
Publicado por: bmfranky en 29 de Julio de 2011, 16:23:39
Hola chicos, aunque el tema es ya viejo, como no había leído la respuesta, les expongo mi teoría al respecto... Jo que técnico.
Si ponemos el bsr a 1, el mismo compilador es el que rastrea los requerimientos del banco y selecciona la dirección correcta.
de otra forma, el compilador inserta directamente el código y si en ese momento habíamos accedido al banco 3 por ejemplo, intenta encontrar la dirección relativa al port A en este caso, pero no es correcta así que , no surte efecto la operación.
bsr dirección física dirección relativa en la operación
por ejemplo pongamos que la dirección del port a es 1111 01101101 111101101101 = F6D
pero hemos dicho que estamos en el banco 3 y no lo cambiamos 0011 01101101 001101101101 = 36D
solución, en vez de poner a uno el pin que queríamos de el puerto A, hemos alterado un bit de una dirección errónea, que a saber que contenía, por ejemplo un contador, que no desbordara a tiempo y perderemos el flujo de programa.
Bueno, esta es mi teoria, si es una burrada, perdonad. pero supongo que sera un bug al incorporar el asembler, porque la forma correcta seria la primera ya que los puertos están en el access bank. a=0;