정보공간_1

[6기 수원 조성찬] Arm cortex-M3 가독성있게 코딩합시다. 본문

IT 놀이터/Elite Member Tech & Talk

[6기 수원 조성찬] Arm cortex-M3 가독성있게 코딩합시다.

알 수 없는 사용자 2014. 12. 8. 15:56

안녕하세요. 엘리트멤버 6기 수원멤버십 23-1기 조성찬 입니다.

전시간에 이어서 진행을 하겟습니다. 


전 시간까지의 코드를 보면 주소 번지를 직접 사용하기 때문에 단순하긴 하지만 한눈에 도저히 알아 볼 수 없는 코드였습니다당연히 실제로 사용을 할떄는 이렇게 사용하지 않죠


그렇기 때문에 훌륭한 개발자 분들이 라이브러리를 구성해 주었고 우리는 이 라이브러리가 적용되면 코드가 어떻게 바뀔 수 있는지 알아 보겠습니다.


 


우선 위에 코드가 최근 사용한 코드인데요. 미리 저런 코드를 접해보고 나서 공부를 하고 레지스터맵을 참고하지 않는 이상은 저 코드만으로는 어떤 역할을 수행하고 어떤 내용을 가지고 있는지 전혀 알 수가 없습니다. 매우 치명적인 단점을 가지고 있는 코드인데요. 당연히 실제로 코딩을 할때는 저렇게 쓰지 않겟죠?


 실제적으론 위와 같은 식으로 작동을 하겟지만, 라이브러리를 통하면 훨씬 보기 좋아 지게 됩니다.


위의 그림이 바로 stm32f10x_gpio.h 에 있는 내용중 일부입니다.


라이브러리를 보면 GPIO의 0~15pin에 대해서 각각 핀에 대해서 상대적으로 어떤 hex 값을 가지는지 설정이 되어 있고 추가적으로 모든 핀을 동시 선택하는 부분까지도 정의가 되어 있습니다.


이를 절대 주소가 아닌 상대주소를 활용하는 부분인데요. 특정 GPIOx 값에 대해서 더하고나 연산을 통해서 사용하게 됩니다.



이 외에도 stm32f10x_rcc.h 에 보면 클럭 인가를 위한 RCC_APB2Perigh_GPIOB, RCC_APB2ENR 가 있고, GPIO 콘트롤을 위한 GPIOB_CRH, GPIOB_BSRR, BPIOB_BRR 등등.... 여러 가지 레지스터의 주소값들이 다양하게 정의 되어 있음을 알 수 있습니다.


이 값들을 활용하면 

(*(volatile unsigned *)0x40021018) |= 0x8;  ====> RCC_APB2ENR |= RCC_APB2Periph_GPIOB;

이렇게 바뀔 수 있는 것이죠!


하지만 이렇게 표현하는 것도 완벽한 표현은 아닙니다. 바로 정의된 것이 무엇인지, 어떤 이름을 가지는지 사용자가 일일이 찾아 보거나 알아야 한다는 것입니다. 그렇기 때문에 다른 라이브러리에서 충분히 납득이 가고 카테고리 별로 묶는 식으로 구현된 부분 역시 존재 합니다.



우선 RCC_APB2ENR 레지스터는 크게 보면 RCC 레지스터에 일부입니다.

그렇기 때문에 구조체로서 구현이 되어서 순서대로 배치가 되었고 각 레지스터 내용이 32bit로 이루어 졌기 때문에 uin32_t 의 레지스터를 다수 보요한 RCC_TypeDef 자료형을 구조체로 구성합니다.



그리고 RCC 에 해당한느 주소값에 RCC_TypeDef 로 타입 캐스팅을 하면 -> 연산자를 사용해서 값을 활용할 수 있습니다.

(*(volatile unsigned *)0x40021018) |= 0x8

RCC_APB2ENR |= RCC_APB2Periph_GPIOB

RCC->APB2ENR |= RCC_APB2Periph_GPIOB;

이렇게 3줄의 코드가 같은 뜻임을 알 수 있습니다.

구조체를 활용하니 계층적으로 어느 레지스터에 어떤 기능들이 있는지 이름으로 좀 더 쉽게 볼 수 있게 되었습니다.


참고


ARM Cortex-M3 시스템 프로그래밍 완전정복 1

http://cafe.naver.com/embeddedcrazyboys/