본문 바로가기
코스웨어/16년 스마트컨트롤러

20160314_오아람_업무일지_펌웨어분석+전역변수

by 알 수 없는 사용자 2016. 3. 16.
728x90
반응형

01. 인터럽트  

interrupt 란?

퓨터 작동 중에 예기치 않은 문제가 발생한 경우라도 업무 처리가 계속될 수 있도록 하는 컴퓨터 운영체계의 한 기능. 호출 주체가 신호가 된다. 함수를 호출한다.

외부인터럽트 : 밖에서 스위치 등을 연결하여 인터럽트를 거는것

내부인터럽트 : 내부의 회로가 특정한 상태가 되어 함수를 호출 해 주는 것

 

01) EICRA(External Interrupt Control Register A)

02) EICRA(External Interrupt Control Register B)

 

<<예제소스>> 

#define PINA  (*((volatile unsigned char *)0x20))
#define DDRA  (*((volatile unsigned char *)0x21))
#define PORTA  (*((volatile unsigned char *)0x22))
#define EICRA  (*((volatile unsigned char *)0x69))
#define EICRB  (*((volatile unsigned char *)0x6A))
#define EIMSK  (*((volatile unsigned char *)0x3D))
#define SREG  (*((volatile unsigned char *)0x5F))

#define INT7 7     
#define INT6 6
#define INT5 5
#define INT4 4
#define INT3 3
#define INT2 2
#define INT1 1
#define INT0 0

#define ISC7 6
#define ISC6 4
#define ISC5 2
#define ISC4 0
#define ISC3 6
#define ISC2 4
#define ISC1 2
#define ISC0 0


#define sei()   __asm__ __volatile__ ("sei" ::)//7번비트만 1로 만들어줌.어셈블리코드
#define sleep()  __asm__ __volatile__ ( "sleep" "\n\t" :: )



void __vector_1(void) __attribute__((signal, used, externally_visible));//인터럽트 신호를 받는다,사용된다,외부에서 이걸 볼 수 있어야한다.(호출가능하다)


int main(void)
{

  DDRA=0xff;
  PORTA=0x00;
  EICRA=(3<<ISC0);//ISC0==INT0
  EIMSK=(1<<INT0);//==EIMSK=1;,INT0만 열고 나머지문은 다 닫는다.만약 다른것도 열고 싶으면 (1<<INT0) | (1<<INT3);이렇게 쓴다.
  SREG=SREG|(1<<7);//어셈블리보다 코드보다 느리다.SREG=SREG | (1<<7)==sei();


  while(1)
  {
    sleep();
  }
  return 0;
}

void __vector_1(void)
{
  volatile unsigned int uiCnt;

  for(uiCnt = 030000>uiCnt ; ++uiCnt);

  PORTA=~PORTA;

}

<<결과화면>> 

- 용어정리 -

벡터 : 인터럽트마다 번호를 매겨놓음

도메인 네임 : 숫자 형태의 IP 주소를 기억하기 쉽게 하기 위해 부여된 이름 (ex - www.daum.net)

DNS(Domain Name Service) : DomainName->ip로 바꿔주는 것

vector table : code영역에 인터럽트의 주소번지를 표로 저장해놓은것

풀업저항 :  vcc근처에 저항을 붙이는 것(쇼트상태가 되는 것을 막아준다)

풀다운저항 : 그라운드 근처에 저항을 붙이는 것

제3상태 : 어느 누구도 h/l인지 모르는 상태

EIMASK : 레지스터의 조그만 문

SREG : 코어에 직접 영향을 준다

02. 전역변수_지역변수

 

전역 변수 : 함수 밖 선언(Data영역)

지역 변수 : 함수내 선언(Stack 영역)

<<메모리내 저장영역>>

 code(text)

 기계어

 data

 전역변수

 bss

 전역변수

 heap

 동적할당

 stack

 지역변수

 <<예제소스>>

#include<stdio.h>

int d;
int e=99;
int f;
int g=98;
int h;

int main()
{
  int a=0;
  int b;
  int c=100;

  printf("----------------------------------------------------------\n");
  printf("a의 주소 : %p\n",&a);
  printf("b의 주소 : %p                             stack영역\n",&b);
  printf("c의 주소 : %p\n",&c);
  printf("----------------------------------------------------------\n");
  printf("e의 주소 : %p\n",&e);
  printf("g의 주소 : %p                             data영역\n",&g);
  printf("----------------------------------------------------------\n");
  printf("d의 주소 : %p\n",&d);
  printf("f의 주소 : %p                              bss영역\n",&f);
  printf("h의 주소 : %p\n",&h);  
  printf("----------------------------------------------------------\n");
  printf("printf의 주소 : %p\n",printf);
  printf("main의 주소 : %p                          code영역\n",main);
  printf("----------------------------------------------------------\n");
  return 0;
}

<<결과화면>>

<<전역변수의 특징>>

01__초기화하지 않으면 비트단위로 0이 들어간다(binary zero)

02__초기값이 있는 그룹은 data영역, 초기값이 없는 그룹은 bss영역에 들어간다.(main과 printf는 code영역에 들어간다.)

 

<<전역변수를 많이 쓰면 안되는 이유>>

01__ 공용사용이기때문에 어떤 값이 들어있는지 헷갈린다. (변수관리가 어렵다.)

02__ 필요없을 때에도 메모리를 계속 차지한다.

03__실행파일 용량이 증가한다.

<<예제소스>>

#include<stdio.h>

void smart();
int a;

int main()
{
    
  printf("%d\n",a);

  smart();

  printf("%d\n",a);

  return 0;
}


void smart()
{
  a=99;
}

<<결과화면>>

<<예제소스>>

#include<stdio.h>

int a;

int main()
{
  int a=100;
  
  printf("%d",a);  

  return 0;
}

<<결과화면>>

지역변수와 전역변수의 이름이 같아도 허용한다.

전역변수는 공용으로 쓰일 수 있다.

printf가 속해있는 공간이 우선이다.

 

- 용어정리 -

compile time - code,data,bss는 실행파일이 만들어질때 만들어지는 것

run time - heap,stack은 실행될때 만들어지는 것

 

 

 


 

 

 

 

 

 

 

 

728x90