ARM Cortex-Bit-banding
주의:본문은 검증되지 않았습니다.
비트-밴딩(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
CLIEL LAB :: [C, C++] 비트필드(Bit Field)
C++ 비트 필드 - MSDN - Microsoft
C 비트 필드 - MSDN - Microsoft
Bit Fields in C
비트필드 (Bit-field) - 프로그래밍 언어 - 골드피처
'C언어,ARM' 카테고리의 다른 글
__INT_LEAST8_TYPE__ __INT_FAST8_TYPE__ (0) | 2017.01.14 |
---|---|
C언어 - 배열 값 대입 코드 비교 (0) | 2016.12.16 |
임베디드 - AVR(ATMega) 개발환경 vs ARM cortex 개발환경 비교 (0) | 2016.11.17 |
임베디드 디버깅, 개발을 위한 크로스컴파일 환경 구축 (0) | 2016.11.02 |
gcc 링커스크립트 - 부트로더 주소지정 방법 (0) | 2016.10.07 |