TMS320/Study2014. 8. 11. 15:33

공부하는 내용

 

#pragma 전처리기


Start!

 

핸드북에서는 #pragma에 대하여 섹션설정과 관련햇 설명해 놓았다. 물론 MMR과 관련하여 설명하고 있으므로 그것으로 충분할지도 모른다. 하지만 MMR선언 및 조작과 관련하여서는 앞의 글로 충분하다고 생각하며 우리가 cmd를 확인할 수는 있어도 함부로 만질일은 거의 없을 것이다. 따라서 MMR과 관련된 섹션 설정 및 cmd작성은 '제어'를 목표로 그 선행지식을 위한 본 블로그에 맞지 않기에 핸드북에 맡기기로 하고 간단하게 #pragma에 대해서 다루기로 하겠다. 만약 device driver관련한 dll, lib등에 관심있다면 그와 관련된 전문서적을 참고하는것이 나을 듯 하다.

 

예전에 pragma에 대해서 다음과 같이 언급하였다.

 

pragma는 전처리기(preprocessor)을 의미하고 C컴파일러에 지시를 내릴 때 사용하는 명령이다. pragma의 지시어는 once, comment, loop등 다양하다.

 

아래를 숙지하자.

 

1.전처리문은 다양한 종류가 있다.

2.전처리기 앞에는 #을 적는다.

3.전처리기의 긑에는 ;을 붙이지 않는다

4.한줄에 하나의 전처리기만 사용 할 수 있다.

5.하나의 전처리기를 여러 줄로 나누어 처리하려면 줄 끝에 \(역 슬래쉬)를 붙인다.

 

전처리기의 종류는

 

1.#include                                             : 파일 처리를 위한 전처리문

2.#define, #undef                                   : 형태의 정의를 위한 전처리문

3.#if, #ifdef, #ifndef, #else, #elif, #endif    : 조건처리를 위한 전처리문

4.#pragma                                            : 컴파일 옵션 처리를 위한 전처리문

 

우리는 이중 4.#pragma에 대해 '짧게' 다루고자 한다.

 

#pragma는 전처리기 중 하나로 컴파일러에 명령을 내린다.

 

컴파일러에 대해 naver 백과사전의 내용을 인용하겠다.

고급언어(ex. c)로 쓰인 프로그램이 대상 기계(컴퓨터, 임베디드 장치 등)가 직접 이해할 수 있는 목적언어(어셈블리, 기계어 등)로 바꾸는 일을 하는 프로그램이다.[.out, .obj 등을 만들어 준다]

 

#pragma에 대해서 몇몇 예시를 들어 간단히 설명한다.

 

1.#pragma once() : 컴파일을 한번만 실행

:헤더 파일에서 자주 쓰이며 여러 소스 또는 헤더에서 참조될 때 중복참조의 여지가 있을 때 자주 사용된다.

 

2.#pragma pack() : 메모리 공간 최적화(구조체의 정렬 방식 지정)

()안에 숫자가 들어가며 구조체의 공간을 아낄 수 있다. 자세한 설명은 : http://euro87.tistory.com/150

3.#pragma warning() : 특정 경고 설정

 

4.#pragma DATA_SECTION, CODE_SECTION

 

실제로 dsp등을 사용하면서 다룰만한 것은 once나 pack 정도일 것이다. 섹션 설정은 크게 다룰 일은 없을 것이다.

'TMS320 > Study' 카테고리의 다른 글

28XDSP의 MMR선언과 배치 방법 정리  (0) 2014.08.11
구조체 명명법, MMR 관련 헤더 파일 종류  (0) 2014.08.11
28계열의 MMR선언 및 조작(1)  (0) 2014.08.11
MMR이란?  (0) 2014.08.08
cmd 파일  (0) 2014.08.07
Posted by 십자성군
Software/Programming2014. 8. 11. 12:19

프로그래밍 목적이라기 보다는 DSP에서 한번 나왔던 개념이기에 혹시 궁금하신 분들은 참고하길 바랍니다~

 

사전적인 의미

:구조체의 구성 요소(member)의 선언에서 ':'을 함께하는 정수식을 지정하는 방법

 

목적

:메모리의 낭비를 줄이기 위함

 

요즘 컴퓨터는 성능이 매우 좋아서 별로 쓰이지 않지만, DSP와 같이 자원이 한정적인 기기들에는 여전히 유용하다.

예를들어 Int형 정수를 사용하는데 그 값은 0아니면 1만 나온다고 하자.(가령 GPIOA의 MUX는 0아니면 1이면 충분하다.) Uint16이라고 해도 16비트 즉 2바이트다. 1비트면 충분한데 16비트로 사용한다면 정말 큰 메모리 낭비이지 않겠는가? 이때, 선언은 16비트라도 메모리를 1비트로 사용할 수 있다.

 

아래 구조체를 보자

 

struct BitFieldTest    {

unsinged int a : 2;

unsinged int b : 3;

};

 

이 구조체에 대한 size는 32비트(16X2)로 잡히고 하위 두 비트(0,1 번째)와 그 위의 세 비트(2,3,4 번째)가 사용되고 나머지 비트들은 사용되지 않는다. 따라서 메모리를 아낄 수 있다.

 

단점을 들자면 이 32비트 메모리에서 특정 비트들만 값을 변경할 때, 예를 들어 BitFieldTest.a = 1을 하면 단순히 a에 1을 대입하는 것이 아니라 (BitFieldTest & 3 | 1)로 처리되어 비트 연산을 수행하기 때문에 메모리는 아끼지만 속도가 느려지게 된다. MCU에서 MUX레지스터를 자주 바꾸지는 않을테니 큰 문제는 되지 않을것이라 본다.

위의 (BitFieldTest & 3 | 1)이 무슨 의미냐 하면 3이란 숫자는 0b11로 2비트를 의미하기 때문에 BitField의 2비트를 &로 추려내고 여기에 or연산자로 1을 대입하는 것이다. 따라서 한번 연산할 것을 2번연산하게 되는 것이다.

 

struct GPAMUX_BITS    {

Uint16 PWM1_GPIOA0 : 1;

Uint16 PWM2_GPIOA1 : 1;

...

};

 

DSP 28x의 GPAMUX_BITS이다 단지 ON, OFF 만 사용한다면 0,1이면 되기에 1비트만으로도 충분하다.

 

signed 변수를 사용할 때 오버플로우 또는 언더플로우가 발생하지 않도록 값의 대입을 조심하도록 하자.

또한 당연하겠지만 비트수에 따른 표현 가능한 수의 갯수는 2의 n승이다.

Posted by 십자성군
TMS320/Study2014. 8. 11. 12:01

공부하는 내용

구조체를 기반으로 한 MMR조작 및 선언의 기본


Start!

 

 

GPAMUX BIT 

Peripheral Name 

GPIO Name 

GPADIR Bit 

Type 

Reset 

PWM1 

GPIOA0 

R/W 

1

PWM2

GPIOA1

1

R/W 

0

2

PWM3

GPIOA2

2

R/W 

0

3

PWM4

GPIOA3

3

R/W 

0

4

PWM5

GPIOA4

4

R/W 

0

5

PWM6

GPIOA5

5

R/W 

0

6

T1PWM_T1CMP

GPIOA6

6

R/W 

0

7

T2PWM_T2CMP

GPIOA7

7

R/W 

0

8

CAP1_QEP1

GPIOA8

8

R/W 

0

9

CAP2_QEP2

GPIOA9

9

R/W 

0

10

CAP3_QEPI1

GPIOA10

10

R/W 

0

11

TDIRA

GPIOA11

11

R/W 

0

12

TCLKINA

GPIOA12

12

R/W 

0

13

C1TRIP

GPIOA13

13

R/W 

0

14

C2TRIP

GPIOA14

14

R/W 

0

15

C2TRIP 

GPIOA15 

15 

R/W  

GPAMUX 레지스터 구조

 

struct GPAMUX_BITS  {        // bits   description
   Uint16 PWM1_GPIOA0:1;     // 0 
   Uint16 PWM2_GPIOA1:1;     // 1
   Uint16 PWM3_GPIOA2:1;     // 2 
   Uint16 PWM4_GPIOA3:1;     // 3 
   Uint16 PWM5_GPIOA4:1;     // 4 
   Uint16 PWM6_GPIOA5:1;     // 5
   Uint16 T1PWM_GPIOA6:1;    // 6 
   Uint16 T2PWM_GPIOA7:1;    // 7       
   Uint16 CAP1Q1_GPIOA8:1;   // 8
   Uint16 CAP2Q2_GPIOA9:1;   // 9
   Uint16 CAP3QI1_GPIOA10:1; // 10
   Uint16 TDIRA_GPIOA11:1;   // 11
   Uint16 TCLKINA_GPIOA12:1; // 12
   Uint16 C1TRIP_GPIOA13:1;  // 13 
   Uint16 C2TRIP_GPIOA14:1;  // 14 
   Uint16 C3TRIP_GPIOA15:1;  // 15  
        
};

 

GPAMUX에 대한 구조체를 위와같이 선언하였다. Uint16은 typedef unsinged int    Uint16

으로 선언된 16비트 부호없는 정수를 의미한다. 또한 각각의 변수는 비트필드로 1비트만을 사용하도록 하였다. PWM1등 GPIOA의 기능을 확인할 수 있다.

 

아래를 보자

 

union GPAMUX_REG {
   Uint16             all;
   struct GPAMUX_BITS bit;
};

 

union구조체 사용하여 GPAMUX에 대하여 bit또는 all을 이용하여 접근할 수 있음을 알 수 있다.

 

또한 아래와 같이

 

struct GPIO_MUX_REGS {
   union  GPAMUX_REG   GPAMUX;
   union  GPADIR_REG   GPADIR;
   union  GPAQUAL_REG  GPAQUAL;
   Uint16              rsvd1;
   union  GPBMUX_REG   GPBMUX;
   union  GPBDIR_REG   GPBDIR;
   union  GPBQUAL_REG  GPBQUAL;  
   Uint16              rsvd2[5];
   union  GPDMUX_REG   GPDMUX;
   union  GPDDIR_REG   GPDDIR;
   union  GPDQUAL_REG  GPDQUAL;  
   Uint16              rsvd3;
   union  GPEMUX_REG   GPEMUX;
   union  GPEDIR_REG   GPEDIR;
   union  GPEQUAL_REG  GPEQUAL;  
   Uint16              rsvd4;
   union  GPFMUX_REG   GPFMUX;
   union  GPFDIR_REG   GPFDIR;
   Uint16              rsvd5[2];
   union  GPGMUX_REG   GPGMUX;
   union  GPGDIR_REG   GPGDIR;
   Uint16              rsvd6[6];
};

 

GPIO A~BDEFG의 MUX레지스터군을 확인할 수 있다.

또한 아래와 같이 선언하여 다른 코드에서 GPIO_MUX_REGS에 참조가 가능하도록 하고 있다.

DSP281x_Gpio.h.를 참고하라

 

extern volatile struct GPIO_MUX_REGS GpioMuxRegs;

 

이와 관련된 섹션설정은 DSP281x_GlobalVariableDefs.c에서 확인할 수 있다.

 

#pragma DATA_SECTION(GpioMuxRegs,"GpioMuxRegsFile");

 

volatile struct GPIO_MUX_REGS GpioMuxRegs;

 

또한 nonBIOS.cmd에서 아래를 확인할 수 있다.

 

GpioMuxRegsFile   : > GPIOMUX,     PAGE = 1

 

여하튼 우리는 GpioDataRegs를 통해 GPIO_MUX_REGS 구조체에 접근할 수 있으며 GPIOA에 대한 설정도 가능한 것이다.

 

예를들어

 

GpioMuxRegs.GPAMUX.all = 0x0000 ;
GpioMuxRegs.GPAMUX.bit.PWM1_GPIOA0 = 1 ;    // PWM

 

위 코드를 보면, GPAMUX_REG 구조체의 all을 통해서 총 16비트에 한번에 값을 주거나, GPAMUX_BITS  구조체를 갖는 bit에 접근하여 개개의 비트에 접근할 수도 있다.

 

=============================================================================

기본은 마쳤지만 Tip으로써 아래를 보자.

 

/*

GpioMuxRegs.GPAMUX.bit.PWM1_GPIOA    =1;

GpioMuxRegs.GPAMUX.bit.PWM2_GPIOA    =1;

GpioMuxRegs.GPAMUX.bit.PWM3_GPIOA    =1;

GpioMuxRegs.GPAMUX.bit.PWM5_GPIOA    =1;

GpioMuxRegs.GPAMUX.bit.PWM6_GPIOA    =1;

*/

 

GpioMuxRegs.GPAMUX.all=0x0037;

 

위의 주석처리를 1번이라하고 그 아래를 2번이라고 하자. 두 코드 모두 같은 의미를 가지고 있다. 하지만 1번은 5사이클, 2번은 1사이클로 명령처리를 끝낸다. 큰 차이는 안나겠지만 되도록이면 2번과 같이 코드를 짜는것이 나을것이다. 하지만 개발하는 입장에서 인수인계의 문제를 생각한다면 1번이 더 편하겠지. 따라서 위와같이 1,2번 둘다 기재하고 1번을 주석처리하는 것이 여러모로 편할 것이다.

'TMS320 > Study' 카테고리의 다른 글

구조체 명명법, MMR 관련 헤더 파일 종류  (0) 2014.08.11
28계열의 MMR선언 및 조작(2)  (0) 2014.08.11
MMR이란?  (0) 2014.08.08
cmd 파일  (0) 2014.08.07
DSP281x_GlobalVariableDefs.c  (0) 2014.08.07
Posted by 십자성군