BIT-BAND Una Solución eficiente para modificar bits Introducción

BIT-BAND Una Solución eficiente para modificar bits
Introducción
Una CPU no puede modificar bits individuales de una posición de
memoria (o de un registro).La CPU solo puede modificar bytes o
words completos en cada acceso. Si la CPU desea modificar un bit
de un registro (o posición de memoria), debe hacer una copia de
este ultimo en un registro temporario modificar dicho bit mediante
operaciones lógicas (AND (clear) , OR (set) ,XOR (toggle)) y
finalmente escribir el valor modificado al lugar original.
Esta forma de modificar bits individuales usando operaciones del
tipo Read-Modify-Write funciona bien cuando se hace una operación
a la vez, pero puede generar problemas cuando dos o mas
aplicaciones acceden de manera concurrente a ese registro (o
posición de memoria). Por ejemplo que ocurre si una interrupción
se produce entre la lectura y la modificación ? El nuevo valor
sera sobre escrito por la interrupción.
Como funciona el BIT-BAND
BIT_BAND es un termino que usa ARM para describir un mecanismo que
esta disponible en los núcleos Cortex M3 Y M4.
Este mecanismo mapea cada bit de una región de memoria (llamada
Bit-Band-Region) a una palabra completa dentro de una segunda
región de memoria (llamada Bit-Band Alias Region)
El bit menos significativo de cada palabra en la region Bit-Band
alias se corresponde con un bit de la region bit-band.
El beneficio que se obtiene al usar Bit-Banding es que una
escritura a una palabra en la región llamada Bit-Band Alias
modifica un bit de la región llamada Bit-Band. A su vez si se
realiza una lectura de una palabra perteneciente a la region BitBand Alias este valor devuelve el valor del bit correspondiente de
la región Bit-Band. Lo importante es que en cualquier caso esta
operación se hace en un ciclo de maquina y por lo tanto no puede
ser interrumpida (operación atómica).
Se puede obtener una expresión que relacione ambas regiones:
Al pasar de un bit al siguiente dentro de la misma palabra (en la
región de bit band) incrementamos en 4 bytes el offset de la
palabra en la region bit band alias.
Bit-band
31 30 29 28 27 26 25
.....
Bit-band Alias
8
7
6
5
4
3
2
1
0
4 bytes
31 30 29 28
.....
6
5
4
3
2
1
0
31 30 29 28
.....
6
5
4
3
2
1
0
A su vez al pasar de una palabra a la siguiente nos desplazamos en
32 palabras en la zona bit band alias.
Bit-band
Bit Number
Bit-band Alias
31 30 29 28 27 26 25
.....
8 7
6
5
4
3
2
1
0
4 bytes
31 30 29 28
Word offset
.....
Bit Word offset
31 30 29 28
.....
.
.
.
6
5
4
3
2
1
0
32
6
5
4
3
2
1
0
Por lo tanto:
Bit_word_offset(alias) = (Word_offset x 32) + (Bit_number X 4)
Si la zona de alias empieza en bit_band_base entonces la direccion
de la palabra correspondiente sera:
Bit_word_addr(alias) = Bit_band_base(alias) + Bit_word_offset(alias)
Ej:
Bit_band_base (alias) : 0x22000000
Word_offset:
0xFFFFF
Bit_number: 7
Bit_word_addr(alias) = Bit_band_base + (Word_offset x 32) + (Bit_number X 4)
=
=
=
=
0x22000000 + 0xFFFFF * 32 +
0x22000000 + 0x01FFFFE0
+
0x22000000 + 0x01FFFFFC
0X23FFFFFC
7 * 4
0x1C
Memoria del sistema
El procesador tiene un mapa de memoria que queda definido por un
bus de direcciones de 32 Bit (0x0000_0000 a 0xFFFF_FFFF). En dicho
mapa se encuentran diferentes tipos de memorias y periféricos.
El mapa de memoria tiene dos regiones de bit band alias de 32MB
cada una que se mapean respectivamente en 2 zonas bit band de 1MB
cada una.
En el caso del K64F el layout de la zonas es el siguiente:
Peripheral
0x4000_0000-0x400F_FFFF
Peripheral Bit Band Area
0x4200_0000-0x43FF_FFFF Peripheral Bit Band Area Alias
SRAM
0x2000_0000-0x200F_FFFF SRAM Bit Band Area
0x2200_0000- 0x23FF_FFFF SRAM Bit Band Area Alias
Soporte de software
Las siguientes macros definidas en MK64F12.h
permiten el acceso a la region bit-band-alias
BITBAND_REGADDR(Reg,Bit)
/**
* @brief Macro to calculate address of an aliased word in the peripheral
*
bitband area for a peripheral register and bit (bit band region 0x40000000 to
*
0x400FFFFF).
* @param Reg Register to access.
* @param Bit Bit number to access.
* @return Address of the aliased word in the peripheral bitband area.
*/
#define BITBAND_REGADDR(Reg,Bit)
(0x42000000u + (32u*((uint32_t)&(Reg) - (uint32_t)0x40000000u)) + (4u*((uint32_t)(Bit))))
/**
* @brief Macro to access a single bit of a peripheral register (bit band region
*
0x40000000 to 0x400FFFFF) using the bit-band alias region access. Can
*
be used for peripherals with 32bit access allowed.
* @param Reg Register to access.
* @param Bit Bit number to access.
* @return Value of the targeted bit in the bit band region.
*/
#define BITBAND_REG32(Reg,Bit) (*((uint32_t volatile*)(BITBAND_REGADDR(Reg,Bit))))
#define BITBAND_REG(Reg,Bit) (BITBAND_REG32(Reg,Bit))
/**
* @brief Macro to access a single bit of a peripheral register (bit band region
*
0x40000000 to 0x400FFFFF) using the bit-band alias region access. Can
*
be used for peripherals with 16bit access allowed.
* @param Reg Register to access.
* @param Bit Bit number to access.
* @return Value of the targeted bit in the bit band region.
*/
#define BITBAND_REG16(Reg,Bit) (*((uint16_t volatile*)(BITBAND_REGADDR(Reg,Bit))))
/**
* @brief Macro to access a single bit of a peripheral register (bit band region
*
0x40000000 to 0x400FFFFF) using the bit-band alias region access. Can
*
be used for peripherals with 8bit access allowed.
* @param Reg Register to access.
* @param Bit Bit number to access.
* @return Value of the targeted bit in the bit band region.
*/
#define BITBAND_REG8(Reg,Bit) (*((uint8_t volatile*)(BITBAND_REGADDR(Reg,Bit))))