C언어,ARM

ARM Cortex-Bit-banding

안녕1999 2016. 12. 5. 23:30

주의:본문은 검증되지 않았습니다.


비트-밴딩(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) 속도가 매우 중요한 경우(주변장치 액세스)





가.정의 - 혼자 연구하는 C/C++ by WinApi

soen.kr/lecture/ccpp/cpp1/13-4-1.htm
비트 구조체는 비트들을 멤버로 가지는 구조체이며 비트 필드(bit field)라고도 부른다. 잘 알다시피 비트는 기억의 최소 단위이며 0 또는 1중 하나를 기억한다.

CLIEL LAB :: [C, C++] 비트필드(Bit Field)

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;

C++ 비트 필드 - MSDN - Microsoft

https://msdn.microsoft.com/ko-kr/library/ewwyfdbe.aspx
Visual Studio 2017 RC에 대한 최신 설명서는 Visual Studio 2017 RC 설명서를 참조하세요. 클래스와구조체는 정수 형식보다 작은 저장 공간을 차지하는 멤버를 ...

C 비트 필드 - MSDN - Microsoft

https://msdn.microsoft.com/ko-kr/library/yszfawxh.aspx
구조체 또는 공용 구조체의 멤버에 대한 선언자 이외에, 구조체 선언자는 "비트 필드"라는 지정한 비트 수가 될 수 있습니다. 길이는 필드 이름의 선언자에서 콜론으로 ...

Bit Fields in C

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; ...

비트필드 (Bit-field) - 프로그래밍 언어 - 골드피처

goldpitcher.co.kr/pages/viewpage.action?pageId=3715
2007. 11. 6. - 일반적인 구조체에서 구조체 구성요소는 C가 지원하는 데이터 형태로만 나누어지는데 비해 비트필드는 비트 단위로 구성요소를 나눌 수 있기 ...