주의:본문은 검증되지 않았습니다.
비트-밴딩(Bit-banding)
---------------------------------------------------------
- 메모리를 절약하기위해, BOOL같은 변수는 1비트만 사용할 수 있게 해주는 방식.
- C컴파일러의 bool, BOOL등은 int형등으로 컴파일이 된다.
- 1비트변수를 사용하려면, 아래 주소를 액세스해야한다.
#define문을 사용하여 변수를 할당해야함을 의미한다.

실질적으로는 아래 그림과 같이 구성된다.
32비트 주소를 액세스하면, 1비트만 해당된다.

데이터쉬트등의 pdf문서에서는 아래와 같이 복잡한 수식(?)을 늘어 놓는다.
bit_word_offset = (byte_offset x 32) + (bit_number x 4) bit_word_addr = bit_band_base + bit_word_offset |
Bit-banding 메모리는 1Mbyte나 사용할 수 있으나, 실제로는 얼마되지 않는다.
내가 사용하는 칩은 얼마나 사용할 수 있을까?
STM32F205RCT6TR칩을 예로들어보면, 100k의 RAM을 가지고있다.
사실상 모든 RAM영역을 bit-banding하여 사용할 수 있음을 의미한다.

C언어로 변수할당하여 사용하는 변수와, C언어로 변수할당이 되었는지, 안되었는지 알 수 없는 RAM을 무작적, 직접 액세스할 수는 없다.
그래서, C언어로 bit-banding할 변수를 할당해놓고, 위의 복잡한(?)공식을 통해, RAM을 직접 액세스하면,
1비트단위로 액세스가 가능하다는 이야기이다.
C언어에서도 구조체(struct)로 1비트단위 액세스가 쉽게 된다.(struct bit field)
그러나, 이방식은 8~32비트에서 n비트만을 추출/삽입하는 코드가 들어간다.
그래서 비트필드 변수를 읽고, 쓰는작업은 느리다.
그러나, bit-banding을 사용하면, C언어의 비트필드보다 훨씬 더 빠르다는것이다.
(약 2~4배정도 빠를것으로 예상)
일단 비트밴딩할 변수를 할당하고, 해당 변수의 각 비트를 주소를 정해주어야 한다.
예) 아래는 예시이므로, 직접 확인해보기 바랍니다.
byte a;
#define RAM_START_ADDR 0x20000000
#define BIT_BANDING_START_ADDR 0x22000000
#define RAM_BIT_BANDING_GAP (BIT_BANDING_START_ADDR-RAM_START_ADDR)
#define a0 (*(RAM_BIT_BANDING_GAP+((&a)-RAM_START_ADDR)*8+0))
#define a1 (*(RAM_BIT_BANDING_GAP+((&a)-RAM_START_ADDR)*8+1))
#define a2 (*(RAM_BIT_BANDING_GAP+((&a)-RAM_START_ADDR)*8+2))
...
#define a7 (*(RAM_BIT_BANDING_GAP+((&a)-RAM_START_ADDR)*8+7))
a=0;
a1=1;
if(a==0x02)
{
printf("OK");
}
else
{
printf("err");
}
문제점
---------------------------
- 크로스컴파일이 안된다?
가능은 하다. 단, 실제변수 영역보다 8배 더 많은 영역을 비트-밴딩 영역으로 할당해야한다.
또한, 일반변수 액세스와, 비트밴딩 변수 영역이 다르므로, 2가지 방식으로 액세스가 불가능하다.
물론, 비트밴딩 함수/매크로를 만들어주면 되긴하다.
그러나, 그렇게되면, 모든 변수의 대입에 함수를 사용해야하고,
소스 코드가 너무 커지고, 복잡해지는 문제(?)가 발생한다.
cbi,sbi,gbi등을 이용한다면?
---------------------------------------------------------------------------
- cbi등의 매크로를 개조하여, 해당주소-비트의 bit-banding주소를 얻어서, 액세스하면, 쉽게 사용가능하다.
또한 실제 동작코드도 작아지고(?), 속도도 매우 빨라지게 된다.
- 레지스터에는 적용할 수 없어, 속도가 떨어지는 문제가 발생한다.
아래는 예문 코드이므로, 동작하지 않습니다. #define RAM_START_ADDR 0x20000000 #define BIT_BANDING_START_ADDR 0x22000000 #define BIT_BANDING_GAP (BIT_BANDING_START_ADDR-RAM_START_ADDR) #define BIT_BAND8(a,i) *((byte*)(&(a)-RAM_START_ADDR+BIT_BANDING_START_ADDR)+(i))
#define sbi(a,i) BIT_BAND8(a,i)=1 #define cbi(a,i) BIT_BAND8(a,i)=0 #define gbi(a,i) BIT_BAND8(a,i) |
주변장치 액세스할때 bit-banding은?
------------------------------------------------------------------------------------------
한번에 원하는 비트를 on/off할 수 있어 좋으나,
한번에 여러비트를 설정해야하는 경우도 많다. 이경우에는 더 느릴 수 도 있다.
결론
----------------------
Bit-banding은 매우 훌륭한 기능이나,
요즘 ARM Cortex칩들의 RAM이 부족하지는 않다.
과거의 8051이나, ATMega칩에 비해, 몇배나 더 많아졌다.
속도 또한 매우 빨라졌다.
굳이 bit-banding을 사용할 이유가 없다.
1) 메모리(RAM)가 정말 부족하고, 속도가 매우 중요한 경우
2) 속도가 매우 중요한 경우(주변장치 액세스)
soen.kr/lecture/ccpp/cpp1/13-4-1.htm
비트 구조체는 비트들을 멤버로 가지는 구조체이며 비트 필드(bit field)라고도 부른다. 잘 알다시피 비트는 기억의 최소 단위이며 0 또는 1중 하나를 기억한다.lab.cliel.com › Programming › C C++
2010. 4. 27. - struct bitfield{ unsigned char a : 1; unsigned char b : 1; unsigned char c : 1; unsigned char d : 1; unsigned char e : 1; unsigned char f : 1;https://msdn.microsoft.com/ko-kr/library/ewwyfdbe.aspx
Visual Studio 2017 RC에 대한 최신 설명서는 Visual Studio 2017 RC 설명서를 참조하세요. 클래스와구조체는 정수 형식보다 작은 저장 공간을 차지하는 멤버를 ...https://msdn.microsoft.com/ko-kr/library/yszfawxh.aspx
구조체 또는 공용 구조체의 멤버에 대한 선언자 이외에, 구조체 선언자는 "비트 필드"라는 지정한 비트 수가 될 수 있습니다. 길이는 필드 이름의 선언자에서 콜론으로 ...https://www.tutorialspoint.com/.../c_bit_fields.htm이 페이지 번역하기 Suppose your C program contains a number of TRUE/FALSE variables grouped in a structurecalled status, as follows − struct { unsigned int widthValidated; ...goldpitcher.co.kr/pages/viewpage.action?pageId=3715
2007. 11. 6. - 일반적인 구조체에서 구조체 구성요소는 C가 지원하는 데이터 형태로만 나누어지는데 비해 비트필드는 비트 단위로 구성요소를 나눌 수 있기 ...