60
LENGUAJE C LENGUAJE C PARA SISTEMAS DEDICADOS PARA SISTEMAS DEDICADOS

LENGUAJE C - edudevices.com.ar · Llamada a la función main zA pesar que main es el punto de entrada al programa, el firmware realiza tareas previas a main. Entre ellas. zCargar

  • Upload
    hadat

  • View
    215

  • Download
    0

Embed Size (px)

Citation preview

LENGUAJE CLENGUAJE CPARA SISTEMAS DEDICADOSPARA SISTEMAS DEDICADOS

FUNDAMENTOSFUNDAMENTOS

Computadora

Se dispone de un S.O.

El S.O. inicia y configura los periféricos.

El S.O. brinda al usuario subrutinas para utilizar los periféricos ( system calls ).

Microcontrolador

No posee un S.O.

El firmware debe iniciar los periféricos.

El usuario debe crear sus propias subrutinas para utilizar los periféricos.

En lenguaje C para sistemas dedicados no podemos hacer:

printf(“Hola Mundo”);

Llamada a la función main

A pesar que main es el punto de entrada al programa, el firmware realiza tareas previas a main. Entre ellas.

Cargar registros de configuración.Limpiar zonas de RAM.Cargar el puntero de pila SP.

Código en ensamblador

ORG $EE00

…configuraciconfiguracióónn de los de los perifperifééricosricos……

….

BRA $

Código en C

ORG $EE00

…código de inicialización…

CALL/JMP main

void main(void){

…código escrito por el usuario…

while(1){}

}

RecursosRecursos

Arquitecturas de memoria

Modelo tiny ( Freescale )

MOV PORTA,PORTB

Modelo small ( Freescale )

LDA PORTASTA var1

Pasaje de parámetros

Al igual que en un computadora, la pila se utiliza para el pasaje de parámetros:

int funcion(char a, int b, float c,….)

Ejemplo de pasaje de parámetros usando la pila

void main(void){

int dunga, donga;

dunga = 3;donga = 5;

dunga = suma(dunga, donga);

donga = resta(dunga, donga);}

int sum(int s1, int s2){

return s1 + s2;}

int resta(int r1, int r2){

return r1 – r2;}

Pasaje de parámetros usando la pila

Desventajas:Llamados anidados a funciones pueden limitar la RAM libre.

Ventajas:Al retornar de la función se libera el espacio de memoria.

Uso del heap

Se hace declarando variables estáticas externas, mas conocidas como VARIABLES GLOBALES.

Ejemplo de pasaje de parámetros usando el heap

iInt dunga, donga;

void main(void){

dunga = 3;donga = 5;suma();resta();

}

int suma(void){

dunga = dunga + donga;}

int resta(void){

dunga = dunga - donga;}

Pasaje de parámetros usando el heap

Ventajas:Pueden anidarse los llamados a funciones sin que crezca la pila enormemente.

Desventajas:La memoria usada en el heap no puede liberarse.

Uso de las funciones recursivas

void factorial(int n){

if(n == 1)return 1;

elsereturn factorial(n-1) *

n;}

factorial(8);

VariablesVariables

Tipos de datos básicos

En PC:char: 1 byteint: 2 ó 4 bytesfloat: 4 bytes

En microcontroladores:char: 1 byteint: 2 bytesfloat: 4 bytes

Variantes de los tipos básicos

Se admiten los modificadores signed y unsigned.También los modificadores short y long.El float puede no estar contemplado en versiones gratuitas de los compiladores.

Operaciones básicas

AritméticasSuma +Resta –Multiplicación *División /Resto %

LógicasAND &OR |XOR ^

No necesariamente existe en ensamblador una instrucción para realizar cierta operación aritmética. Ej: Los PIC 16F no cuentan con instrucciones de

multiplicación.En ese caso el compilador debe

generar un algoritmo en assemblerque ejecute esa operación.

Alternativas al tipo float

En general queremos representar cifras del tipo: 20,3 mVSe trata de un número decimal de punto fijo.Tampoco se dispone de representación en punto fijo.

Solución:Trabajar las mangintudes

multiplicadas x10, x100, …La cifra 20,3 se almacena como

203. Así puede contenerse en un tipo int.

Manejo de bits como variables

Es válida aplicar una asignación a un bit.Son válidas las operaciones lógicas entre bits |, & y ^.Ejemplos:

Freescale:PTAD_PTAD4 = 1;PIC:PORTBbits.RB4 = 0;

Volatile

Código en Cvoid findecuenta(void){

…if(time == 100){

time = 0;…

}}

Posible compilación en ensamblador:

findecuenta:LDA time…CMP #!100BNE …CLR time…

Volatile

Si time no cambia antes del if, la compilación anterior es válida.Si time proviene del módulo timer puede modificarse entre que es cargada y el if.

Solución

Código en C:volatile int time;

void findecuenta(void){

…if(time == 100){

time = 0;…

}}

Compilación en ensamblador:

findecuenta:…

LDA timeCMP #!100BNE …CLR time

Reseña de punteros

Se declaran y usan de la forma convencional:

int *p;char *p;int hola;p= &hola;*p = 3; ( hola = 3 )

Punteros a RAM

int hola;int *p;

p = &hola;*p = 3;

p apunta a una posición en RAM.

Punteros a ROM

char *p;char texto[20] = “Hola mundo”;

p = texto;

p apunta a una posición en ROM (FLASH).

Arquitectura Von Neumann( Freescale )

La RAM y ROM están en un mismo mapa. Pueden accederse por una única clase de punteros.

Arquitectura Harvard ( PIC )

La RAM y ROM están en mapas diferentes. Se deben indicar a que

mapa apunta el puntero.

Punteros en micros Hardvard

Punteros a RAM:

char hola;char *p;p = &hola;

Punteros a ROM:

const char rom texto[20] = “me duermo”;char rom *p;p = texto;

Entrada y salidaEntrada y salida

En la computadora

Acceso al I/O de entrada:a = getch();Acceso al I/O de salida:printf(“Hola mundo”);

Sistema dedicado

Crear bibliotecas de funciones:

LCD_printf(char *texto);LCD_Dato(char caracter);LCD_gotoxy(char x, char y);

sprintf resuelve todo

Genera textos.

Convierte datos int a BCD.Convierte datos floata BCD.Permite generar salidas en formatos muy complejos.

sprintf(texto, “Chau”);sprintf(texto, “%d”, a);sprintf(texto, “%f”, d);sprintf(texto, “V = %02.1f mV”, voltios);

Uso de los puertos de E/S

Acceso a pines individuales:

struct{

byte PTAD0:1byte PTAD1:1byte PTAD2:1byte PTAD3:1byte PTAD4:1byte PTAD5:1byte PTAD6:1byte PTAD7:1

}Bits;

Bits.PTAD0 = 1;

Mas sobre puertosAcceso a todo el puerto:

typedef union{

byte Byte;struct{

byte PTAD0:1byte PTAD1:1byte PTAD2:1byte PTAD3:1byte PTAD4:1byte PTAD5:1byte PTAD6:1byte PTAD7:1

}Bits;}PTADSTR;

PTADSTR.Byte = 0xff;

PTADSTR.Bits.PTAD0 = 1;

PTAD_PTAD0 = 1;

Manejo de periféricos

En PC usando system calls.En microcontroladores:

Freescale:Asistentes de configuración ( Processor Expert )Funciones de biblioteca.

En PIC:Bibliotecas.

Processor Expert

Permite configurar cualquier módulo del microcontrolador.

Processor Expert

Pueden configurarse todos los parámetros del módulo.

Processor Expert

Genera el código de inicializaciónGenera funciones para el manejo de módulo.Genera vectores de interrupción.

Bibliotecas para PIC

A/DComparadorEEPROMI2CPWM…

TemporizaciTemporizacióónn

Demoras cortas

Intercalando código en ensamblador:

unsigned char contador_1;

asm{LDA #$32STA contador_1

dem_100us_1:NOPNOPNOP

DBNZ contador_1,dem_100us_1

}

Ttotal = 50 x 2µs = 100µs

Tint = 10 ciclos x 200ns = 2µs

Demoras largasIntercalando código en ensamblador:

unsigned char contador_1;unsigned char contador_2;unsigned char contador_3;

for(contador_3 = 0; contador_3 < 100; contador_3++)for(contador_2 = 0; contador_2 < 20;

contador_2++) {

asm{

LDA #$C8STA contador_1

dem_1s_1:NOPNOPNOPDBNZ contador_1,dem_1s_1

}}

Ttotal = 100 x 10ms = 1s

Text = 20 x 500µs = 10ms

Tint = 250 x 2µs = 500µs

Demoras largas

Módulo timer con interrupciones:

void main(void){TI1_SetPeriodSec(1);}

ISR(TI1_Interrupt){

(void)TPM1C0SC;TPM1C0SC = 0x80;

(código del usuario)}

Código bloqueante

Durante el llamado a una función el programa no continúa su ejecución hasta retornar de ella.

Ej:

void main(void){

demora_seg(1);}

Código no bloqueante

El programa puede continuar con otras tareas mientras una función no entregue los resultados deseados.

Ej:void main(void){…}

ISR(TI1_Interrupt){

(void)TPM1C0SC;TPM1C0SC = 0x80;

(código del usuario)}

Timer tick de la PC

Produce interrupciones cada 1ms.El usuario puede generar eventos por timer tick.El usuario no debe atender la interrupción.

void __fastcall TForm1::Timer1Timer(TObject*Sender)

{( código del usuario )

}

Eventos de timer con microcontroladores

La velocidad del timer tick es determinada por el firmware.Pueden generarse eventos por timertick.El usuario no debe atender la interrupción.

void TI1_OnInterrupt(void){

( código del usuario )}

InterrupcionesInterrupciones

Arquitectura PIC

Existen 1 ó 2 vectores de interrupción.El usuario debe determinar con un if que periférico disparó la interrupción.

#pragma code low_vector=0x18void interrupt_at_low_vector(void){_asm

GOTO low_isr_endasm}

#pragma code#pragma interruptlow low_isrvoid low_isr(void) {}

Arquitectura Freescale

El Processor Expert resuelve buena parte del código.Existen vectores independientes para cada evento y periférico.El usuario no debe atender una interrupción. El Processor Expert genera el código que lo hace.

Evento de conversión A/D

word AD1_OutV;

ISR(AD1_Interrupt){

((TWREG*)(&AD1_OutV))->b.high = ADC1RH; ((TWREG*)(&AD1_OutV))->b.low = ADC1RL; OutFlg = TRUE;AD1_OnEnd();ModeFlg = STOP;

}

void AD1_OnEnd(void){

unsigned int medicion;}

¡¡CHAUCHAU!!