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))))
© Copyright 2024