본문 바로가기
공부,일/atmega328P

ISR() 분석 - 전처리문 분석

by fromnothing1 2021. 7. 20.

 #define ISR() 문 분석을 통해서 #define 전처리 언어에 대해서 공부해보자 

 

interrrup.h 안에 있는  ISR() 정의 

#ifdef __cplusplus
#  define ISR(vector, ...)     
    extern "C" void vector (void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__; \
    void vector (void)
#else
#  define ISR(vector, ...)            \
    void vector (void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__; \
    void vector (void)
#endif

 

1. extern "C"

C++ 문법 네임맹글링 ( Name Mangling)  

 

c++  의 경우 컴파일 할때 컴파일러는 함수이름에 앞뒤로 여러가지 문자가 추가 되는데 이를 네임 맹글링이라 한다. 

 

네임 맹글링은  함수의 오버로드 기능 또는 링커가 똑같은 이름의 함수를 구분 할 수 있기위해서 컴파일러에서 자동으로 추가 되는 부분으로 네임맹글링 규칙은 컴파일러마다 다르다. 

 

c 언어의 경우 이러한 맹글링을 지원하지 않아 c++ 로 컴파일된 언어와 호환되지 않는데 extern "C" 를 사용하면 맹글링된 함수가  C 라는 것을 링커에게 알려줘서 C 작성된 프로그램과도 호환이 가능하다. 

 

출처:

http://hyacinth.byus.net/moniwiki/wiki.php/C%2B%2B/extern%20%22C%22%20%EB%A5%BC%20%EC%93%B0%EB%8A%94%20%EC%9D%B4%EC%9C%A0

 

2. __attribute__

이는  gcc 에만 있는 기능으로 컴파일러에게 추가적인 지시를 할 수 있는 기능이다.

https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/Function-Attributes.html

위의 사이트에  signal 속성에 대해 읽어보면 

 

컴파일러에게 

이 기능이 인터럽트 핸들러임을 알려줘서 컴파일러가 인터럽트 핸들러에게 사용하기 적합한 함수 진입 및 종료 시쿼스를 생성 하도록 명령한다. 

 

cf) attribute 심화 내용

https://indra17.tistory.com/entry/GNU-C-attribute

 

3. __VA_ARGS__ (가변인수 매크로 )

매크로 함수를 사용할때 변수의 갯수가 변할 수 있다. 이러한 경우 가변인수 매크로를 사용한다. 

출처:https://jhnyang.tistory.com/298

즉 ... 부분이 __VA_ARGS__  와 치환 된다. 

 

참고로 ##__VA_ARGS__ 의 경우는 가변인자가 들어 오지 않는경우 

즉 printlog_(fmt,) 과 같이 치환 될 경우 , 을 없애준다. 

 

ISR() 에서 가변인수 자리에 들어 올 수 있는 값은 

    • ISR_BLOCK                                      ;속성을 지정 안하면 기본으로 선택됨
    • ISR_NOBLOCK
    • ISR_NAKED                                      ;
    • ISR_ALIASOF( target_vector )

이고  interrup.h 안에 정의를 보면 attribute 를 통해서 정의되어 있는 모습을 봇수 있다.

#  define ISR_BLOCK
#  define ISR_NOBLOCK    __attribute__((interrupt))
#  define ISR_NAKED      __attribute__((naked))
#  define ISR_ALIASOF(v) __attribute__((alias(__STRINGIFY(v))))

 

 

 

 

https://blog.naver.com/PostView.nhn?isHttpsRedirect=true&blogId=ioizzzzzz&logNo=220068978054

에서 확인 해라 

4. \

#  define 문에서 줄바꿈은 \ 로 표시해줘야지 줄바꿈이라고 인식한다. 

 

 

 

마지막으로 gcc 에서 어떻게 전처리문으로 바꾸는지 실제로 사용해보자 (우분투에서 gcc 깔아서 실행함)

 

c 언어 코드  test.c

#define ISR(vector, ...)            \
    extern "C" void vector (void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__; \
    void vector (void)


ISR(INT0_vect, ISR_NAKED ) {

     PORTD ^= 0x1;

}

int main ()
{
return 0;
}
~                                                                              
~                                                                              
~

전처리후 파일 test.i

# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "test.c"


extern "C" void INT0_vect (void) __attribute__ ((signal,__INTR_ATTRS)) ISR_NAKED;
void INT0_vect (void) {

     PORTD ^= 0x1;

}

int main ()
{
return 0;
}

질문 1. 왜 ISR_NAKED 가 __attribute__((naked)) 로 변경 되지 않는가 ?

 

 

 

 

 

interrupt.h
0.01MB

댓글