Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Sistemas Empotrados
Grado en Ingeniería de Sistemas Electrónicos
Departamento de Tecnología Electrónica
Universidad de Málaga
Protección de datos, derechos de imagen y propiedad intelectual
Compilers,
Debuggers
Micriµm
RTOS
Stacks,
Specialty, Micriµm
“Middleware“
Programmers
Compiladores de C para ARM Cortex M
– Al conjunto de herramientas de desarrollo SW (ensamblador, compilador,
enlazador, bibliotecas estándar de soporte, etc.) se le suele llamar
“toolchain”
• Prebuilt
• Herramientas toolchain
// Enable the GPIO port that is used for the on-board LED.
SYSCTL_RCGC2_R = SYSCTL_RCGC2_GPIOF;
// Do a dummy read to insert a few cycles after enabling the peripheral.
ulLoop = SYSCTL_RCGC2_R;
/* Enable the GPIO pin for the LED (PF3). Set the direction as output, and
enable the GPIO pin for digital function.*/
• Extracto de cabecera:
//*****************************************************************************
//
// GPIO registers (PORTC)
//
//*****************************************************************************
#define GPIO_PORTC_DATA_BITS_R ((volatile unsigned long *)0x40006000)
#define GPIO_PORTC_DATA_R (*((volatile unsigned long *)0x400063FC))
#define GPIO_PORTC_DIR_R (*((volatile unsigned long *)0x40006400))
#define GPIO_PORTC_IS_R (*((volatile unsigned long *)0x40006404))
#define GPIO_PORTC_IBE_R (*((volatile unsigned long *)0x40006408))
#define GPIO_PORTC_IEV_R (*((volatile unsigned long *)0x4000640C))
#define GPIO_PORTC_IM_R (*((volatile unsigned long *)0x40006410))
#define GPIO_PORTC_RIS_R (*((volatile unsigned long *)0x40006414))
#define GPIO_PORTC_MIS_R (*((volatile unsigned long *)0x40006418))
#define GPIO_PORTC_ICR_R (*((volatile unsigned long *)0x4000641C))
#define GPIO_PORTC_AFSEL_R (*((volatile unsigned long *)0x40006420))
#define GPIO_PORTC_DR2R_R (*((volatile unsigned long *)0x40006500))
#define GPIO_PORTC_DR4R_R (*((volatile unsigned long *)0x40006504))
#define GPIO_PORTC_DR8R_R (*((volatile unsigned long *)0x40006508))
#define GPIO_PORTC_ODR_R (*((volatile unsigned long *)0x4000650C))
...............................
Cada registro se declara como un puntero a una dirección concreta del espacio de memoria
(según el mapa de memoria del microcontrolador)
Estructura básica de un programa (III)
int main(void)
{
int LED = 2;
SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
while(1)
{
Los periféricos se programan
// Turn on the LED mediante funciones
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, LED);
// Delay for a bit
SysCtlDelay(2000000);
// Cycle through Red, Green and Blue LEDs
if (LED == 8) {LED = 2;} else {LED = LED*2;}
}
}
Programación con API
• Biblioteca de funciones proporcionada por el fabricante del
microcontrolador.
– Ventajas:
• Funcionamiento “probado”
• Mayor legibilidad del código de la aplicación.
• Oculta detalles de implementación y complejidad de los periféricos
(¡algunos tienen casi 100 registros!!)
• Contiene workarrounds de posibles bugs de los dispositivos.
• Pregrabadas en ROM en algunos modelos
– Desventajas:
• Potencialmente menos eficiente.
• A veces puede ser necesario conocer detalles de su implementación
interna para evitar errores en su utilización.
• En el caso de los micros de la familia TIVA ,Texas
Instruments suministra la biblioteca TIVAWare
– Misma API para todos los microcontroladores de la familia.
Interrupciones y excepciones (I)
Tamaño asignado a la
pila
Tamaño asignado al
heap
Algunas funciones de la
librería estándar de C NO
FUNCIONAN sin memoria
dinámica
Más sobre la pila
• Entrada en excepción
– R0-R3, LR, PC y xPSR se guardan en la pila
Main
4
3
1
Exception Handler
Exception Vector
Registros a
preservar que se
van a usar y que no
son de scratch (esos
están preservados
por la función que
llamó a esta función)
Ejemplo Calling Convention (I)
Codificación en ensamblador
Función C
(con nivel de optimización 3)
int funcion2(int a, int b, int c, int x) funcion2:
{ MLA.W R0, R3, R0, R1
MLA.W R0, R3, R0, R2
return (a*x*x+b*x+c); BX R14
//Polinomio grado 2, por poner un ejemplo
}
Pierdo “el
árbol de
llamadas”
Dirección 0x40025500
Corresponde al GPIO F
Depurando una excepción de error (III)
¿Código que lo ha provocado (I)?
La sexta posición
contiene LR,
probablemente la
dirección de la
subrutina que llamó
a la que provocó el
error.
(0x18C5)
La séptima posición
de la pila es el PC
Que había cuando
saltó la excepción
(0x1466)
Depurando una excepción de error (III)
¿Código que lo ha provocado (II)?
PC Antiguo
Depurando una excepción de error (III)
¿Código que lo ha provocado (II)?
LR Antiguo
Depurando una excepción de error (IV)
Puedo recuperar el árbol de llamada si encuentro cualquier instrucción
que haga un BX LR ó BX R14. Anoto su dirección y mediante la
ventana de depuración escribo dicho valor en el registro PC. Al darle a
ejecutar paso a paso sale de la excepción (se mueve LR a PC) y
recupero la información del árbol de llamada.
Depurando una excepción de error (V)
Otra opción sería copiar manualmente el LR y el PC almacenados en
pila a los registros e incrementar SP en 8 posiciones (sumar 32).
Aunque no podré seguir depurando podemos ver el árbol de llamada y
tener una idea de dónde se ha producido el error