Está en la página 1de 34

Embedded C

Programming
Hardware Abstraction

Abstracción de Hardware

Programming
Programación en Lenguaje C - Abstracción de hardware

Abstracción de Hardware

La abstracción de hardware funciona como una interfaz entre el software y hardware; permite que las aplicaciones
sean independientes del hardware, es decir que no acceden directamente al hardware sino que lo hacen a una
capa abstracta.

Ventajas de utilizar abstracción de hardware:

• Portabilidad: permite correr una aplicación en diferentes plataformas de hardware.


• Modularidad: con un diseño modular es más sencillo corregir bugs y reemplazar código sin afectar
el proyecto completo.
• Seguridad: desarrolladores de las capas de aplicación no podrán acceder tan fácil al hardware, por
lo que se pueden evitar accidentes desafortunados.

En este contexto, abstracción significa que el hardware no está fijamente definido, sino que más bien
se le puede definir en la capa de abstracción

Programming
Programación en Lenguaje C - Abstracción de hardware

La abstracción de hardware permite que la aplicación no acceda directamente al hardware sino que lo hace
mediante una capa abstracta.

Application

Hardware Abstraction

Hardware

Programming
Programación en Lenguaje C - Abstracción de hardware

Abstracción de hardware

En sistemas embebidos normalmente se utilizan dos conecptos para implementar la abstracción de hardware:

• BSP (Board Support Package): Abstrae configuraciones específicas de la tarjeta electrónica, por ejemplo: pines
de canales analógicos para el ADC, pines para controlar LED’s, pines de entrada para control de botones, pines
para control de sensores, líneas de comunicación serial (UART, SPI, I2C, etc.), pantallas, líneas de clock, voltajes
de entrada, entre otros.

• HAL (Hardware Abstraction Layer): Abstrae funcionalidades específicas de la arquitectura del MPU o MCU. Por
ejemplo configuraciones de la CPU, oscilador, periféricos como timers, interrupciones, ADC, SPI, UART, USB,
Ethernet, etc.

Programming
Programación en Lenguaje C - Abstracción de hardware

La abstracción de hardware permite que la aplicación no acceda directamente al hardware sino que lo hace
mediante una capa abstracta.

Application

BSP (Board Support Package) HAL (Hardware Abstraction Layer)

Hardware

Programming
Programación en Lenguaje C - Abstracción de hardware

Punto de partida

Un buen punto de partida es revisar un programa sin abstracción de hardware. Este programa está pensado para correr
en un PIC24FJ128GA705. A pesar de que probablemente pueda correr en MCU similares de la familia PIC24, no podrá
hacerlo en otros MCU como un PIC16, PIC18, AVR, STM, etc.

while(1)
{
if(PORTAbits.RA7 == 0 || PORTAbits.RA10 == 0)
{
LATBbits.LATB4 = 0;
LATCbits.LATC3 = 0;
LATCbits.LATC4 = 0;
LATCbits.LATC5 = 0;
}

else
{
LATBbits.LATB4 = 1;
LATCbits.LATC3 = 1;
LATCbits.LATC4 = 1;
LATCbits.LATC5 = 1;
}
}

Programming
Programación en Lenguaje C - Abstracción de hardware

El problema con acceder directamente al hardware

El problema con el programa anterior es que accede directamente a registros de hardware del microcontrolador, por esta
razon cualquier microcontrolador que no coincida con la misma configuración de registros no podrá correr el programa.
El programa anterior podrá usarse como capa cercana al hardware pero no como capa de aplicación.

La idea de tener un proyecto con abstracción de hardware es tener una capa de aplicación que pueda correr en
diferentes modelos de microcontroladores y en diferentes tarjetas. Para esto solo será necesario cambiar la capa de
abstracción de hardware de acuerdo al microcontrolador donde se desea correr el proyecto a través de los archivos bsp
y hal.

Programming
Programación en Lenguaje C - Abstracción de hardware

Solución: Abstracción de hardware

Volver el hardware como algo abstracto indica que la aplicación no espere acceder a componentes de un hardware
específico, sino más bien el hardware se considera abstracto para la aplicación.

Existen algunos patrones de diseño para implementar la abstracción de hardware, uno de los más simples y comunes es
el patron de diseño: Hardware Proxy Pattern (Patron de proxy de hardware).

El patron de proxy de hardware está basado en el patron de proxy utilizado ampliamente en los lenguajes orientados a
objetos.

Programming
Programación en Lenguaje C - Hardware Proxy Pattern

Hardware Proxy Pattern

Programming
Programación en Lenguaje C – Hardware Proxy Pattern

Hardware Proxy Pattern

El patron de proxy de hardware crea elementos de software responsables de acceder a una pieza de hardware. El
hardware puede estar mapeado en memoria, puerto o interrupción, o incluso puede mapearse a través de una conexión
en serie, bus, red o enlace inalámbrico.

El proxy publica servicios que permiten leer y escribir valores en el hardware, así como inicializar, configurar y apagar el
dispositivo según corresponda.

El proxy proporciona una interfaz de codificación y conexión independiente para los clientes y, por lo tanto, promueve
una fácil modificación en caso de que cambie la naturaleza de la interfaz del dispositivo o la conexión.

Programming
Programación en Lenguaje C – Hardware Proxy Pattern

Problema que soluciona el Patron de Diseño Proxy

Si cada cliente accede a un dispositivo de hardware directamente, los problemas debidos a cambios de hardware se
agravan.

Si cambia la codificación de bits, la dirección de memoria o la tecnología de conexión, se debe rastrear y modificar a
cada cliente. Al proporcionar un proxy para que se ubique entre los clientes y el hardware real, el impacto de los cambios
de hardware es muy limitado, lo que facilita tales modificaciones.

Para facilitar el mantenimiento, los clientes deben desconocer la codificación, el cifrado y la compresión de bits que
utiliza el dispositivo; estos detalles deben ser administrados por el proxy de hardware con funciones privadas internas.

Programming
Programación en Lenguaje C - Abstracción de hardware

Básicamente el patrón de proxy de hardware se compone de: Proxy Clients, Hardware Proxy y Hardware Device.

Proxy Clients: “Conocen” el proxy de


hardware e invoca sus servicios para
Application(Proxy Clients API Calls) acceder al hardware.

Hardware Proxy: Proporciona la


abstracción de hardware. Tiene
Hardware Abstraction (Hardware Proxy) tanto datos como funciones que se
personalizan para el dispositivo en
cuestión

Hardware Device: Representa el


Hardware Device hardware real. No se escribe código
en este elemento.

Programming
Programación en Lenguaje C – Hardware Proxy Pattern

Estructura del Patron Proxy Hardware – Diagrama UML

Programming
Programación en Lenguaje C – Hardware Proxy Pattern

Estructura del Patron Proxy Hardware

Proxy Clients: El cliente proxy "conoce" el proxy de hardware e invoca sus servicios para acceder al dispositivo de
hardware.

Hardware Proxy: Ésta es la clase, función o archivo principal del sistema. Tiene tanto datos como funciones que se
personalizan para el dispositivo en cuestión. Generalmente proporcionan funciones para inicializar, habilitar, deshabilitar
y configurar el dispositivo de hardware. También podemos encontrar funciones que proporcionan acceso de lectura a los
valores del dispositivo o bien configuran valores que se envían al dispositivo.

Hardware Device: Este elemento representa el hardware real. Como tal, no escribirá código C para este elemento, pero
está presente solo para ayudar a comprender el diagrama. La asociación que se muestra entre el dispositivo de
hardware y el proxy de hardware se realiza a través de una interfaz de hardware direccionable por software, como una
dirección de puerto, una dirección de memoria o una interrupción.

Programming
Programación en Lenguaje C – Hardware Proxy Pattern

Patron Proxy Hardware – Implementación en código

Descripción de la práctica: Implementar un programa para acceder a los LED’s y botones de una tarjeta electrónica
utilizando abstracción de harware con el patron Proxy Hardware. Utilizar el concepto de BSP (Board Support Package)
para mapear los LED’s y botones de la placa en cuestión.

Funciones HardwareProxy: Dependencia de tipos de Hardware Proxy

• void BUTTON_Enable (BUTTON button) • BUTTON


• bool BUTTON_IsPressed (BUTTON button) • LED
• void LED_On (LED led)
• LED_Off (LED led)
• LED_Enable (LED led)

Programming
Programación en Lenguaje C - Hardware Proxy Pattern

Patron Proxy Hardware


Implementación en código

Diagrama UML

Programming
Programación en Lenguaje C – Hardware Proxy Pattern

Patron Proxy Hardware – Implementación en código


Funciones HardwareProxy:

Las siguientes funciones son llamadas por el cliente Proxy para acceder al hardware, en este caso para manipular LED’s
y Botones.

• void BUTTON_Enable(BUTTON button): Habilita el boton indicado en el parámetro.


• bool BUTTON_IsPressed(BUTTON button): Devuelve true si el boton indicado en el parametro está presionado
o false si no está presionado.

• void LED_On(LED led): Enciende el LED indicado en el parámetro.


• LED_Off(LED led): Apaga el LED indicado en el parámetro.
• LED_Enable(LED led): Habilita el LED indicado en el parámetro.

Dependencia de tipos de Hardware Proxy

• BUTTON
• LED

Programming
Programación en Lenguaje C – Hardware Proxy Pattern

Patron Proxy Hardware – Implementación en código


Dependencia de tipos de Hardware Proxy

Los tipos BUTTON y LED deberán definirse de acuerdo a la configuración de la tarjeta electrónica (mapeo de leds y
botones). En el siguiente ejemplo se muestra la definición de tipos para la palca PIC-IoT WG basada en el
PIC24FJ128GA705.

La placa tiene 4 LED’s de diferentes colores y 2 botones.

typedef enum
typedef enum {
{ LED_NONE,
BUTTON_NONE, RED_LED,
BUTTON_SW0, YELLOW_LED,
BUTTON_SW1 GREEN_LED,
}BUTTON; BLUE_LED
} LED;

Programming
Programación en Lenguaje C – Hardware Proxy Pattern

Patron Proxy Hardware – Implementación en código


Dependencia de tipos de Hardware Proxy

Los tipos BUTTON y LED deberán definirse de acuerdo a la configuración de la tarjeta electrónica (mapeo de leds y
botones). En el siguiente ejemplo se muestra la definición de tipos para la palca Xplained Mini basada en el
ATmega328PB.

La placa tiene 1 LED y 1 botón.

typedef enum typedef enum


{ {
BUTTON_NONE, LED_NONE,
BUTTON_SW0 LED_BOARD
}BUTTON; } LED;

Programming
Programación en Lenguaje C - Abstracción de hardware

Patron Proxy Hardware – Implementación en código

Proxy Clients: Aquí se mandan a llamar


las funciones LED_Enable(), LED_On,
Application(API Calls) LED_Off(), BUTTON_Enable(), etc.

Hardware Proxy: Aquí se implementan


las funciones LED_Enable(), LED_On,
Hardware Abstraction (Hardware Proxy) LED_Off(), BUTTON_Enable(), etc

Hardware Device: Representa los


Hardware Device registros SFR del MCU para acceder
a los puertos y manipular los LED’s y
Botones

Programming
Programación en Lenguaje C - Abstracción de hardware

Patron Proxy Hardware – Implementación en código

Ejemplo para encender un LED con la función LED_On()con la placa PIC-IoT WG

Proxy Clients: Llamado a la función


LED_On(). Como parámetro se pasa
Application -> LED_On(<type>LED)Call el LED que se desea encender, en este
caso el LED azul.

Hardware Proxy: En la implementación


Hardware Abstraction -> LED_On(BLUE_LED){…} de la función LED_On(BLUE_LED) se
accede al puerto y pin específico donde
se encuentra el LED AZUL

Hardware Device: Representa el


Hardware Device -> PORT puerto y pin en RAM donde se
encuentra el LED AZUL

Programming
Programación en Lenguaje C – Hardware Proxy Pattern

.c app_led_switch.c
.c leds.c (BSP)
#include "system.h"

void app_switch_led() #include "leds.h"


{ #include <xc.h>
LED_On(BLUE_LED);
} #define RED_LED_LAT LATBbits.LATB4
#define YELLOW_LED_LAT LATCbits.LATC3
#define GREEN_LED_LAT LATCbits.LATC4
#define BLUE_LED_LAT LATCbits.LATC5

void LED_On(LED led)


{
.c
main.c .h
leds.h switch(led)
{
#include "system.h" typedef enum case RED_LED:
#include "app_led_switch.h” { RED_LED_LAT = 0;
int main() LED_NONE, break;
{ RED_LED,
SYSTEM_Initialize(SYSTEM_STATE_POLLING); YELLOW_LED, case YELLOW_LED:
GREEN_LED, YELLOW_LED_LAT = 0;
while(1) BLUE_LED break;
{ } LED;
app_switch_led();
case GREEN_LED:
} GREEN_LED_LAT = 0;
}
break;

Hardware case BLUE_LED:

Application – Client Proxy Abstraction BLUE_LED_LAT = 0;


break;
Hardware Proxy
case LED_NONE:
break;

Programming
Programación en Lenguaje C – Hardware Proxy Pattern

.h
.c app_led_switch.c leds.h
.c leds.c (BSP)
typedef enum
#include "system.h" {
LED_NONE,
void app_switch_led() RED_LED, #include "leds.h"
{ YELLOW_LED, #include <xc.h>
LED_On(BLUE_LED); GREEN_LED,
} BLUE_LED #define RED_LED_LAT LATBbits.LATB4
} LED; #define YELLOW_LED_LAT LATCbits.LATC3
#define GREEN_LED_LAT LATCbits.LATC4
#define BLUE_LED_LAT LATCbits.LATC5

Esta línea de código no es portable a void LED_On(LED led)


como se podría pensar ya que {
.c
main.c switch(led)
BLUE_LED representa una {
#include "system.h"
característica específica de case RED_LED:
#include "app_led_switch.h”
int main() hardware, y se encuentra en la RED_LED_LAT = 0;
break;
{ sección de aplicación o cliente
SYSTEM_Initialize(SYSTEM_STATE_POLLING);
Proxy. case YELLOW_LED:
YELLOW_LED_LAT = 0;
while(1) break;
{ ¿Qué pasá si la placa no tiene un led
app_switch_led();
} azul? Se pierde la abstracción de case GREEN_LED:
GREEN_LED_LAT = 0;
} hardware… break;

Hardware case BLUE_LED:

Application – Client Proxy Abstraction BLUE_LED_LAT = 0;


break;
Hardware Proxy
case LED_NONE:
break;

Programming
Programación en Lenguaje C – Hardware Proxy Pattern

.h io_mapping.h
.c app_led_switch.c
.c leds.c (BSP)
#define LED_WIFI_CONN BLUE_LED
#include "system.h"

void app_switch_led() #include "leds.h"


{ #include <xc.h>
LED_On(LED_WIFI_CONN);
} #define RED_LED_LAT LATBbits.LATB4
#define YELLOW_LED_LAT LATCbits.LATC3
#define GREEN_LED_LAT LATCbits.LATC4
#define BLUE_LED_LAT LATCbits.LATC5

void LED_On(LED led)


{
.c
main.c .h
leds.h switch(led)
{
#include "system.h" typedef enum case RED_LED:
#include "app_led_switch.h” { RED_LED_LAT = 0;
int main() LED_NONE, break;
{ RED_LED,
SYSTEM_Initialize(SYSTEM_STATE_POLLING); YELLOW_LED, case YELLOW_LED:
GREEN_LED, YELLOW_LED_LAT = 0;
while(1) BLUE_LED break;
{ } LED;
app_switch_led();
case GREEN_LED:
} GREEN_LED_LAT = 0;
}
break;

Hardware case BLUE_LED:

Application – Client Proxy Abstraction BLUE_LED_LAT = 0;


break;
Hardware Proxy
case LED_NONE:
break;

Programming
Programación en Lenguaje C – Hardware Proxy Pattern

.h io_mapping.h
.c app_led_switch.c
.c leds.c (BSP)
#define LED_WIFI_CONN BLUE_LED
#include "system.h"

void app_switch_led() #include "leds.h"


{ #include <xc.h>
LED_On(LED_WIFI_CONN);
} #define RED_LED_LAT LATBbits.LATB4
#define YELLOW_LED_LAT LATCbits.LATC3
#define GREEN_LED_LAT LATCbits.LATC4
io_mapping.h proporciona #define BLUE_LED_LAT LATCbits.LATC5
mejor abstracción entre la aplicación void LED_On(LED led)
y la abstracción del hardware. {
.c
main.c .h
leds.h
Funciona como puente entre ambos switch(led)
{
#include "system.h" lados del programa. typedef enum case RED_LED:
#include "app_led_switch.h” { RED_LED_LAT = 0;
int main() LED_NONE, break;
{ RED_LED,
SYSTEM_Initialize(SYSTEM_STATE_POLLING); YELLOW_LED, case YELLOW_LED:
GREEN_LED, YELLOW_LED_LAT = 0;
while(1) BLUE_LED break;
{ } LED;
app_switch_led();
case GREEN_LED:
} GREEN_LED_LAT = 0;
}
break;

Hardware case BLUE_LED:

Application – Client Proxy Abstraction BLUE_LED_LAT = 0;


break;
Hardware Proxy
case LED_NONE:
break;

Programming
Programación en Lenguaje C – Abstracción de Hardware

project
Carpeta

MPLAB project
apps bsp
Archivos .c y .h

App name

board_PIC24 Board_AVR

firmware

leds.c leds.c
app_src Board_PIC24.X Board_AVR.X
leds.h leds.h
buttons.c buttons.c
buttons.h buttons.h
io_mapping.c io_mapping.c
main.c
io_mappin.h io_mapping.h
app.c
system.c system.c
app.h
system.h system.h

Programming
Programación en Lenguaje C - Hardware Adapter Pattern

Hardware Adapter Pattern

Programming
Programación en Lenguaje C – Hardware Adapter Pattern

Hardware Adapter Pattern

El patrón de adaptador de hardware proporciona una forma de adaptar una interfaz de hardware existente a las
expectativas de la aplicación.

El patrón de adaptador de hardware es útil cuando la aplicación requiere o utiliza una interfaz, pero el hardware
real proporciona otra. El patrón crea un elemento que adapta las dos interfaces.

Programming
Programación en Lenguaje C – Hardware Adapter Pattern

Problema que soluciona el patron adaptador

Si bien el hardware que realiza funciones similares tiende a tener interfaces similares, a menudo la información
que necesitan y el conjunto de servicios difieren. En lugar de reescribir los clientes del dispositivo de hardware
para usar la interfaz proporcionada, se crea un adaptador que proporciona la interfaz esperada a los clientes
mientras convierte las solicitudes hacia y desde la interfaz de hardware real.

El patrón de adaptador de hardware es útil cuando tiene hardware que satisface la necesidad semántica del
sistema pero que tiene una interfaz incompatible. El objetivo del patrón es minimizar la reelaboración del código
cuando un diseño o implementación de hardware se reemplaza por otro.

Programming
Programación en Lenguaje C – Hardware Adapter Pattern

Estructura del Patron


Adaptador

Diagrama UML

Programming
Programación en Lenguaje C – Hardware Adapter Pattern

Estructura del Patron Adaptador

HardwareInterfaceToClient: Esta interfaz representa el conjunto de servicios y listas de parámetros que el cliente
espera que proporcione el proxy de hardware. Como interfaz, es una colección de especificaciones de servicio y no
tiene implementación. La implementación en este caso la proporciona la clase de adaptador de hardware.

AdapterClient: El cliente del adaptador espera invocar los servicios de un elemento de software que representa el
hardware, según lo especificado por la interfaz de interfaz de hardware a cliente. Es un elemento en el sistema de
aplicación que espera controlar, monitorear o usar el dispositivo de hardware.

HardwareAdapter: El adaptador de hardware realiza una "adaptación" entre el cliente y el proxy de hardware. Es
decir, las solicitudes de servicio realizadas por Adapter Client se convierten en una secuencia de servicios que
están disponibles desde Hardware Proxy.

Las funcionalidades de HardwareProxy y HardwareDevice se revisaron en el patron Proxy.

Programming
Programación en Lenguaje C – Hardware Adapter Pattern

Patron Hardware Adapter – Implementación en código

Descripción de la práctica: Realizar un adaptador de hardware de la práctica anterior.

//Interfaz
typedef struct
{
void (*enable) (LED led); //HardwareAdapter
void (*On) (LED led); const leds_t led = {
void (*Off)(LED led); .enable = LED_Enable,
}leds_t; .On = LED_On,
.Off = LED_Off
typedef struct };
{ const buttons_t button = {
void (*enable)(BUTTON button); .enable = BUTTON_Enable,
bool (*IsPressed)(BUTTON button); .IsPressed = BUTTON_IsPressed
}buttons_t; };

extern const buttons_t button;


extern const leds_t led;

Programming
Programación en Lenguaje C – Hardware Adapter Pattern

Patron Hardware Adapter – Implementación en código

Descripción de la práctica: Realizar un adaptador de hardware de la práctica anterior.

//AdapterClient
if(button.IsPressed(BUTTON_CONN) == true){
led.On(LED_INDICATOR);
}
else{
led.Off(LED_INDICATOR);
}

Programming
Programación en Lenguaje C – Hardware Adapter Pattern

Programming

También podría gustarte