PDF de programación - Programación en C para Sistemas Embebidos (con ejemplos basados en MSP430)

Imágen de pdf Programación en C para Sistemas Embebidos (con ejemplos basados en MSP430)

Programación en C para Sistemas Embebidos (con ejemplos basados en MSP430)gráfica de visualizaciones

Publicado el 21 de Febrero del 2020
321 visualizaciones desde el 21 de Febrero del 2020
164,5 KB
55 paginas
Creado hace 7a (16/08/2012)
SASE 2012

Programación en C

para Sistemas Embebidos

(con ejemplos basados en MSP430)

Mg. Guillermo Friedrich

UTN-FRBB

Tópicos destacados

- Generalidades sobre la arquitectura MSP430

- Paso de parámetros a funciones y variables locales

- Uso de estructuras y punteros a estructuras

- Estructuras y uniones “anónimas”

- Campos de bits

- Constantes

- Variables asociadas a SFR del micro

- Proteger la concurrencia sobre variables compartidas

- Atención de interrupciones

- Fijar direcciones de memoria usadas por código y datos

SASE 2012

2

MSP430

- Arquitectura RISC 16-Bit, Ciclo de Instrucción 62.5 o
125-ns

- MSP430F133: 8KB+256B Flash Memory, 256B RAM

- MSP430F135: 16KB+256B Flash Memory, 512B RAM

- MSP430F147: 32KB+256B Flash Memory, 1KB RAM

- MSP430F148: 48KB+256B Flash Memory, 2KB RAM

- MSP430F149: 60KB+256B Flash Memory, 2KB RAM

- MSP430G2553: 16KB+256B Flash Memory, 512 B
RAM

SASE 2012

3

MSP430: mapa de memoria

SASE 2012

4

MSP430

- La reducida cantidad de RAM obliga a tener en cuenta
algunos detalles al programar en C.

- Los parámetros y variables locales (auto) de las funciones
utilizan registros del procesador y a veces también la pila.

- Las variables con valores constantes (por ej. tablas de
parámetros, textos predefinidos, etc.) conviene declararlas
como const, para que sean ubicadas en memoria Flash.

SASE 2012

5

Codificación eficiente para aplicaciones embebidas

- Seleccionar los tipos de datos más adecuado.

- Controlar la ubicación de los objetos de código y
datos en memoria.

- Controlar las optimizaciones del compilador.

- Escribir código eficiente.

SASE 2012

6

Selección de los tipos de datos

- Usar los tipos más pequeños que sea posible.

- Tratar de evitar el uso de double y long long (64 bits)

- No usar campos de bit de tamaño mayor que 1.

- Tratar de evitar el uso de punto flotante.

- Si un puntero no se va a usar para modificar datos,
declararlo const (Por ej.: const char *p).

SASE 2012

7

Uso de punto flotante

- En un micro sin coprocesador matemático, las
operaciones de punto flotante son ineficientes en
tiempo de ejecución y uso de memoria.

- Si se puede, es preferible usar tipos float (32 bits)
en lugar de double (64 bits).

- Las constantes de punto flotante por defecto son
double, excepto que se las especifique como float.
a += 1.0f // float

a += 1.0 // double

SASE 2012

8

Campos de bits

- Por ejemplo, dada la siguiente estructura de campos de
bits:

union bits
{

struct
{

unsigned int b1:1;
unsigned int b2:2;
unsigned int b3:3;
unsigned int b4:4;
unsigned int b6:6;

}b;

unsigned int w;

}bf;

SASE 2012

9

Campos de bits

- Las operaciones sobre campos de un bit pueden
requerir una sola instrucción de máquina.

En C:

bf.b.b1 = 1;

En lenguaje ensamblador:

bis.w

#0x1,&bf

SASE 2012

10

Campos de bits

- Las operaciones sobre campos de más de un bit
requieren varias instrucciones de máquina:

En C:

bf.b.b3 = 5;

En lenguaje ensamblador:

mov.w
and.w
bis.w
mov.w

&bf,R15 ; copia
#0xFFC7,R15 ; borra
#0x28,R15 ; setea
R15,&bf ; copia

SASE 2012

11

Campos de bits

- La misma operación implementada sin campos de
bits es más eficiente:

En C:

w &= 0x00c7; // borra 3 bits

w |= 5 << 3; // escribe el 5

En lenguaje ensamblador:

and.w

bis.w

#0xC7,&w ; borra

#0x28,&w ; escribe

SASE 2012

12

Estructuras y Uniones anónimas

- Son propias del lenguaje C++

- Algunos compiladores de C tienen extensiones que
las admiten.

- Los nombres de los miembros tienen alcance fuera
de la estructura o unión.

SASE 2012

13

Estructuras y Uniones anónimas

union bits
{

struct
{

unsigned int b1:1;
unsigned int b2:2;
unsigned int b3:3;
unsigned int b4:4;
unsigned int b6:6;

}b;

unsigned int w;

}bf;

// unnamed
union
{

struct
{

unsigned int b1:1;
unsigned int b2:2;
unsigned int b3:3;
unsigned int b4:4;
unsigned int b6:6;

};

unsigned int w;

};

Estructuras y Uniones anónimas

// unnamed
union
{

struct
{

unsigned int b1:1;
unsigned int b2:2;
unsigned int b3:3;
unsigned int b4:4;
unsigned int b6:6;

};

unsigned int w;

};

}

// los miembros de las
// struct y union
// unnamed tienen
// alcance global,
// no pueden repetirse

main()
{ // Pone todo a 0

w = 0;
// asigna valores
// a algunos campos
b3 = 5;
b6 = 9;

Estructuras y Uniones anónimas

- Las estructuras y uniones anónimas son de utilidad
para manipular los registros del procesador que
están mapeados en direcciones de memoria.

- Por ejemplo: el registro U0CTL (Control de USART0)
está ubicado en la dirección 0x070, es de 8 bits y
tiene la siguiente estructura:

SASE 2012

16

Estructuras y Uniones “unnamed” (sin nombre)

__no_init volatile union
{

unsigned char U0CTL;
struct
{

unsigned char SWRST : 1;
unsigned char MM : 1;
unsigned char SYNC : 1;
unsigned char LISTEN: 1;
unsigned char CHAR : 1;
unsigned char SPB : 1;
unsigned char PEV : 1;
unsigned char PENA : 1;

};

} @ 0x0070; // mapea la variable a la dir 70h

Estructuras y Uniones “unnamed” (sin nombre)

// Configuración de USART0 como UART,

// 8 bits, paridad par, un bit de stop

USART0 = 0; // pone todo a cero

// setea los bits necesarios

CHAR = 1; // 8 bits

PENA = 1; // paridad habilitada

PEV = 1; // paridad par

SASE 2012

18

Estructuras y Uniones anónimas

- También son de utilidad para definir variables booleanas,
ahorrando memoria.

- Para ello se usan estructuras de campos de bits. Por ejemplo:

union {

struct {

unsigned int waitingSomeEvent: 1;
unsigned int ready4something : 1;
......
unsigned int someEvent
unsigned int anotherFlag

: 1;
: 1;

};
unsigned int flags;

};

SASE 2012

19

Estructuras y Uniones anónimas

- Poner a cero todos los flags:

flags = 0;

- Modificar o testear algún flag:

if( waitingSomeEvent && someEvent )

{

}

someEvent = 0;

SASE 2012

20

Manejo de registros mapeados en memoria usando máscaras

- Para el mismo ejemplo del registro U0CTL:

#define U0CTL (*(unsigned char *)0x0070)

#define SWRST 0x01

#define MM 0x02

......

#define CHAR 0x10

......

#define PENA 0x80

Manejo de registros mapeados en memoria usando máscaras

- Ej. poner a 1 CHAR y MM, el resto en cero:

U0CTL = CHAR | MM;

- Ej. poner a cero MM sin modificar el resto:

U0CTL &= ~MM;

Alineamiento de estructuras

- En el MSP430 (y otros micros de 16 bits), los datos de
tamaño mayor que un byte deben estar alineados en
direcciones pares.

- En los de 32 bits, se alínean en direcciones múltiplos de 4.

- El compilador agrega bytes de relleno para alinear variables

- También se hace alineamiento dentro de las estructuras.

- El acceso a variables desalineadas requiere de más
instrucciones de máquina.

SASE 2012

23

Alineamiento de estructuras

- Cuando no es admisible el relleno dentro de una
estructura (por ej. para respetar el formato de un
mensaje), se usa la directiva #pragma pack

- El acceso a una variable desalineada genera más
código de máquina y es más lento.

SASE 2012

24

Alineamiento de estructuras

- Por ejemplo, dada la siguiente estructura:

struct var{

char c; // entre c y n1
int n1; // un byte de relleno
int n2;

}v;

Veamos la operación v.n1 = w; con y sin
alineamiento

SASE 2012

25

Alineamiento de estructuras

- Con alineamiento de a 16 bits (por default):

mov.w

R10, &0x228

- Con alineamiento por byte ( #pragma pack(1) ):

mov.b R10,R14
swpb R10
and.w #0xFF,R10
mov.b R14,&0x24D ; LSB a dir impar
mov.b R10,&0x24E ; MSB a dir par

Paso de parámetros a funciones

El paso de parámetros a funciones consume tiempo
y puede consumir memoria de la pila.

Dependiendo de la arquitectura del procesador y del
compilador, los parámetros se pueden pasar en
registros y/o a través de la pila.

En los casos siguientes –sobre MSP430– se ven
ambas situaciones.

SASE 2012

27

Paso de parámetros a funciones

Una función con hasta 4 parámetros los recibe en registros
(R12, R13, R14 y R15).

Ejemplo:

void f2(unsigned char b, int n)

{

}

int a, i;

for(i=0, a=0; i<n; ++i)

a += b+i;

SASE 2012

28

Paso de parámetros a funciones

La llamada a ésta función queda así:

En C:

f2('a',32);

En lenguaje ensamblador:

mov.w #0x20,R13 ; 32

mov.b #0x61,R12 ; ‘a’

call #f2

SASE 2012

29

Paso de parámetros a funciones

Una función con más de 4 parámetros recibe 4 en registros
(R12, R13, R14 y R15) y el resto en la pila.

Ejemplo:

int f5(int a,int b,int c,int d,int e)

{

}

int suma = a + b + c + d + e;

return suma;

SASE 2012

30

Paso de parámetros a funciones

El llamado a ésta función se realiza así:

En C:

n = f5(10,20,30,40,50);

En lenguaje ensamblador:

push.w #0x32 ;el 5° a la pila
mov.w #0x28, R15 ;4° al 1° en reg.

mov.w #0x1E, R14

mov.w #0x14, R13

mov.w #0x0A, R12

call #f5

mov.w R12, R15 ; retorna en R12

Paso de parámetros a funciones

Un par de consejos prácticos serían:

• Tratar de usar la mínima de parámetros que sea necesario.

• Analizar si conviene usar variables globales:

Si bien no es una práctica recomendada en general, en
arquitecturas con poca cantidad de RAM puede ayudar a
optimizar el uso de memoria y la performance.

• Agrupar variables en estructuras y pasar como parámetro el
puntero a la estructura.

SASE 2012

32

Paso de estructuras a funciones

El paso de variables struct, ya sea como parámetro o como
valor retornado, conviene hacerlo mediante punteros.

Por ejemplo, dada la siguiente estructura y variables:

struct int5

{

};

int a, b, d, c, e;

struct int5 A, B;

33

Paso de estructuras a funciones

Si en lugar de la función f5 del ejemplo anterior se
implementara mediante otra función f5s, que espera un
puntero a struct int5, en C quedaría así:

n = f5s(&A);

Y en lenguaje ensamblador:
mov.w

#0x220,R12 ; R12: puntero a A

call

#f5s

mov.w

R12,R10 ; R12: valor retorno

SASE 2012

34

Paso de estructuras a funciones

Las estructuras son muy útiles porque permiten
agrupar variables que tienen relación entre si.

También s
  • Links de descarga
http://lwp-l.com/pdf17311

Comentarios de: Programación en C para Sistemas Embebidos (con ejemplos basados en MSP430) (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios
Es necesario revisar y aceptar las políticas de privacidad