336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

사용자 삽입 이미지
● 사용부품

     PB-2S

     PIC Basic 보드

     LCD

     4X4 키패드

     STEP 모터

     IR 리모콘

● 사용포트(0~26)

      0 ~ 7번포트(0블럭) : IR 리모콘

      8 ~ 15번포트(1블럭) : 키패드

     16 ~ 19번 포트 : STEP 모터

     20번 포트 : 스피커

     21 ~ 22번 포트 : LED

     - 총 23개 포트 사용

● 기능 설명

⋅ 자 동 문 잠 김

     - 문이 닫히면 센서에 의해 확인

     - 잠금장치 해제 후에도 30초가 지날때까지 문을 열지 않으면 자동으로 잠김

     - 문을 닫은 후 바로 열 상황에 대비하여 5초 정도 후에 잠김

             ⟹ 잠금 장치에 센서 사용으로 인한 신뢰도 향상

     - 잠겨있는 상태에서 외부 무단침입 방지를 기능

            ⟹ 비밀번호 입력 외 비정상적인 방법으로 문이 열렸을 경우 경보음

⋅ 비 밀 번 호

     - 비밀번호 수정

          ◦ 문바깥쪽 키패드를 사용하여 변경

◦ 비밀번호 수정 버튼을 누르면 현재 비밀번호 확인절차 이후 변경가능하며 실수 같은 예외사항을 줄이기 위해 바뀐 비밀번호를 한번 더 확인

     - 비밀번호 확인

         ◦ 문 바깥쪽 키패드를 이용하여 비밀번호 입력

         ◦ 숫자 키패드를 누르면 자동으로 비밀번호 입력모드로 변경

         ◦ 정확한 비밀번호가 입력되면 문 잠김이 해제

         ◦ 3회 이상 비밀번호 오류시 경보음

⋅ 음 성 녹 음(자동 응답기능, 미구현)

     - 부재중 이거나 개인적인 사정으로 손님 방문이 불가능 할 때를 위한 기능

     - ‘메뉴버튼 -> 음성녹음 버튼’으로 부재중 멘트 녹음

     - 부재중 모드 활성화시 초인종을 누르면 입력된 멘트 출력

⋅ 초 인 종

     - 초인종이 눌리면 집안에서 인식할 수 있는 소리가 울림
    
     - 자동응답 기능 활성화 시 집안에 소리가 울림기능이 작동하지 않고 스피커를 통해 녹음되어진 메시지를 전달

            ◦ 한번더 초인종을 누르면 매세지 녹음 가능


● 프로그램 소스

DIM I AS BYTE '입력 변수

DIM E AS BYTE '키패트 메뉴 관련

DIM OPW(4) AS BYTE ' 저장된 비밀번호

DIM TPW(4) AS BYTE ' 입력받은 비밀번호

DIM TTPW(4) AS BYTE ' 입력받은 비밀번호

DIM K AS BYTE '임의변수(비밀번호 관련)

DIM M AS BYTE '비밀번호 틀린 횟수

DIM N AS BYTE '확인버튼 관련

DIM L AS BYTE '비밀번호 관련

DIM Q AS BYTE '비밀번호 변경 관련

DIM MT AS BYTE '스텝모터 관련 변수

DIM R AS BYTE '리모콘 입력 관련 변수

DIM P AS BYTE '센서 관련 변수

DIM PT AS BYTE '리모콘 관련 변수(센서 1 잠금장치)

DIM PO AS BYTE '리모콘 관련 변수(센서 2 문)

DIM LM AS BYTE '잠금장치 관련 변수(LM=0 열림, LM=1 잠김)

DIM CNT AS BYTE '카운트

DIM CNTT AS BYTE '카운트

SET PICBUS HIGH

LCDINIT

K = 0

M = 1

P = 1

LM = 1

CNT = 0

CNTT = 0

PO = 0

OUT 21,1

PT = 0

OUT 22,1

'0으로 비밀번호 초기화

OPW(0) = 15

OPW(1) = 15

OPW(2) = 15

OPW(3) = 15

10R = BYTEIN(0) '리모콘

IF R = 17 THEN

PO = 0

OUT 21,1

ELSEIF R = 18 THEN

PO = 1

OUT 21,0

ELSEIF R = 20 THEN

PT = 0

OUT 22,1

ELSEIF R = 21 THEN

PT = 1

OUT 22,0

END IF

IF K = 0 THEN

CLS

LOCATE 2,1

PRINT "DIGITAL"

LOCATE 2,2

PRINT "DOOR LOCK"

END IF

IF P = 1 AND PT = 1 THEN

CLS

LOCATE 1, 1

PRINT "ARLET!!!"

BEEP 20

BEEP 20

BEEP 20

BEEP 20

BEEP 20

GOTO 100

ELSEIF P = 1 AND PO = 1 THEN

CLS

LOCATE 1, 1

PRINT "ARLET!!!"

100BEEP 20

BEEP 20

BEEP 20

BEEP 20

BEEP 20

GOTO 100

END IF

I = KEYDELAY(PADIN(1), 1, 30, 30)

IF I = 0 THEN GOTO 10

'메뉴버튼(E = 1)

IF I = 5 THEN

IF E = 0 THEN

40K = 1

CLS

LOCATE 0,0

PRINT "<*MENU*>"

LOCATE 0,1

PRINT "1.CHANGE THE P/W"

LOCATE 0,2

PRINT "2.RECORDING"

LOCATE 0,3

PRINT "3.Listen"

E = 1

ELSEIF E =1 THEN

E = 0

K = 0

GOTO 10

END IF

'열기버튼

ELSEIF I = 1 OR E = 5 THEN

OUT 17, 1

OUT 16, 0

OUT 18, 1

CLS

LOCATE 6,1

PRINT "OPEN"

PLAY 20, "C7D7E7"

FOR I = 0 TO 47

OUT 19, 1

DELAY 2

OUT 19, 0

DELAY 2

NEXT I

CLS

P = 0

K = 0

LM = 0

PO = 1

OUT 21,0

GOTO 70

'잠금버튼(센서 사용시 필히 수정!!)

ELSEIF I = 9 THEN

60IF LM = 0 THEN

P = 1

PO = 0

PT = 0

OUT 17, 1

OUT 16, 1

OUT 18, 1

CLS

LOCATE 6,1

PRINT "CLOSE"

PLAY 20, "E7D7C7"

FOR I = 0 TO 47

OUT 19, 1

DELAY 2

OUT 19, 0

DELAY 2

NEXT I

CLS

PT = 0

OUT 21,1

OUT 22,1

K = 0

LM = 1

ELSEIF LM = 1 THEN

P = 1

PO = 0

PT = 0

OUT 17, 1

OUT 16, 1

OUT 18, 1

CLS

LOCATE 6,1

PRINT "CLOSE"

PLAY 20, "E7D7C7"

CLS

PT = 0

OUT 21,1

OUT 22,1

K = 0

LM = 1

END IF

'자동응답 버튼(E = 2)(보이스 레코더 사용시 필히 수정)

ELSEIF I = 13 THEN

CLS

LOCATE 2,1

PRINT "Be away"

PLAY 20, "G7E7"

IF E = 0 THEN

DELAY 1000

PRINT " ON"

PLAY 20, "C7D7E7"

E = 2

ELSE

DELAY 1000

PRINT " OFF"

PLAY 20, "E7D7C7"

E = 0

END IF

CLS

K = 0

'확인 버튼(비밀번호 확인)

ELSEIF I = 14 THEN

CLS

IF K = 4 THEN

FOR N = 0 TO 3

IF OPW(N) = TPW(N) THEN

IF N =3 THEN

LOCATE 6,1

PRINT "OPEN"

PLAY 20, "C7D7E7"

CLS

OUT 17, 1

OUT 16, 0

OUT 18, 1

FOR I = 0 TO 47

OUT 19, 1

DELAY 2

OUT 19, 0

DELAY 2

NEXT I

LM = 0

PO = 1

OUT 21,0

GOTO 70

END IF

ELSE

IF M = 3 THEN

CLS

LOCATE 2,1

PRINT "INPUT ERROR"

LOCATE 2,2

PRINT "Num."

PRINT DEC(M)

PLAY 20, "G4G4G4G4G4G4G4"

DELAY 2000

CLS

K = 0

M = 1

GOTO 10

ELSE

CLS

LOCATE 2,1

PRINT "INPUT ERROR"

LOCATE 2,2

PRINT "Num."

PRINT DEC(M)

PLAY 20, "G4"

CLS

K = 0

M = M + 1

GOTO 10

END IF

END IF

NEXT N

END IF

K = 0

'CALL 버튼

ELSEIF I = 16 THEN

IF E = 2 THEN

CLS

LOCATE 2, 1

PRINT "Be away"

LOCATE 2, 2

PRINT "Message..."

DELAY 4000

ELSEIF E = 0 THEN

CLS

LOCATE 2, 1

PRINT "CALLING..."

PLAY 20, "G2E2"

END IF

CLS

K = 0

'숫자패드 옵션

ELSE

CLS

'메뉴 버튼 활성화 시

IF E = 1 THEN

IF I = 12 THEN

CLS

LOCATE 0,0

PRINT "CHANGE P/W"

L = 0

K = 0

N = 0

M = 1

Q = 1

GOTO 20

ELSEIF I = 11 THEN

CLS

LOCATE 0,0

PRINT "RECORDING..."

DELAY 2000

CLS

L = 0

E = 0

K = 0

GOTO 40

ELSEIF I = 10 THEN

CLS

LOCATE 0,0

PRINT "LISTENING..."

DELAY 2000

CLS

L = 0

E = 0

K = 0

GOTO 40

END IF

ELSEIF E = 0 OR E = 2 THEN

IF K <= 3 THEN

L = 0

LOCATE 1,1

PRINT "Enter the p/w"

TPW(K) = I

LOCATE 6,2

FOR L = 0 TO K

PRINT "*"

NEXT L

K = K + 1

ELSE

CLS

LOCATE 2,1

PRINT "INPUT ERROR"

PLAY 20, "G4"

CLS

K = 0

GOTO 10

END IF

END IF

END IF

GOTO 10

'비밀번호 변경부분

20IF K <= 5 THEN

L = 0

LOCATE 1,1

PRINT "Enter the p/w"

I = KEYDELAY(PADIN(1), 1, 30, 30)

IF I = 0 THEN GOTO 20

TPW(K) = I

LOCATE 6,2

FOR L = 0 TO K

PRINT "*"

NEXT L

K = K + 1

ELSE

CLS

LOCATE 2,1

PRINT "INPUT ERROR"

PLAY 20, "G4"

CLS

K = 0

GOTO 20

END IF

IF I = 14 THEN

CLS

FOR N = 0 TO 3

IF OPW(N) = TPW(N) THEN

IF N = 3 THEN

CLS

PLAY 7, "C7D7E7"

L = 0

K = 0

N = 0

M = 1

Q = 1

GOTO 30

END IF

ELSE

IF M = 3 THEN

CLS

LOCATE 2,1

PRINT "INPUT ERROR"

LOCATE 2,2

PRINT "Num."

PRINT DEC(M)

PLAY 20, "G4G4G4G4G4G4G4"

DELAY 2000

CLS

K = 0

M = 1

GOTO 10

ELSE

CLS

LOCATE 2,1

PRINT "INPUT ERROR"

LOCATE 2,2

PRINT "Num."

PRINT DEC(M)

PLAY 20, "G4"

CLS

K = 0

M = M + 1

GOTO 20

END IF

END IF

NEXT N

K = 0

END IF

GOTO 20

30IF K <= 4 THEN

L = 0

LOCATE 1,1

PRINT "Enter new p/w"

I = KEYDELAY(PADIN(1), 1, 30, 30)

IF I = 0 THEN GOTO 30

TTPW(K) = I

LOCATE 6,2

FOR L = 0 TO K

PRINT "*"

NEXT L

IF K = 3 THEN

CLS

PLAY 20, "C7D7E7"

L = 0

K = 0

N = 0

M = 1

Q = 1

GOTO 50

END IF

K = K + 1

ELSE

CLS

LOCATE 2,1

PRINT "INPUT ERROR"

PLAY 20, "G4"

CLS

K = 0

GOTO 30

END IF

GOTO 30

50 IF K <= 4 THEN

LOCATE 1,1

PRINT "Enter again"

I = KEYDELAY(PADIN(1), 1, 30, 30)

IF I = 0 THEN GOTO 50

TPW(K) = I

LOCATE 6,2

FOR L = 0 TO K

PRINT "*"

NEXT L

IF K = 3 THEN

CLS

FOR N = 0 TO 3

IF TPW(N) = TTPW(N) THEN

IF N = 3 THEN

FOR N = 0 TO 3

OPW(N) = TPW(N)

NEXT N

CLS

LOCATE 2,1

PRINT "P/W changed"

PLAY 20, "C7D7E7"

L = 0

K = 0

N = 0

M = 1

Q = 1

GOTO 40

END IF

ELSE

IF M = 3 THEN

CLS

LOCATE 2,1

PRINT "INPUT ERROR"

LOCATE 2,2

PRINT "Num."

PRINT DEC(M)

PLAY 20, "G4G4G4G4G4G4G4"

DELAY 2000

CLS

K = 0

M = 1

E = 0

GOTO 10

ELSE

CLS

LOCATE 2,1

PRINT "INPUT ERROR"

PLAY 20, "G4"

CLS

K = 0

M = M + 1

GOTO 50

END IF

END IF

NEXT N

END IF

K = K + 1

ELSE

CLS

LOCATE 2,1

PRINT "INPUT ERROR"

PLAY 20, "G4"

CLS

GOTO 50

END IF

GOTO 50

70R = BYTEIN(0)

CNT = CNT + 1

LOCATE 6,1

PRINT "OPEN"

IF E= 0 AND CNT = 250 THEN

CNTT = CNTT + 1

IF CNTT = 5 THEN GOTO 60

ELSE

IF R = 21 THEN

CNT = 0

CNTT = 0

PT = 1

OUT 22, 0

E = 1

GOTO 70

ELSEIF R = 20 THEN

CNT = 0

CNTT = 0

PT = 0

OUT 22, 1

DELAY 5000

E = 0

GOTO 60

END IF

END IFl

GOTO 70

'Programming > 그밖에...' 카테고리의 다른 글

Touch screen Calibration  (0) 2009.09.10
CIE L*a*b*  (0) 2009.06.01
단위환산표  (0) 2008.05.21
어드레싱모드(addressing mode)  (0) 2008.04.01
MMU와 MPU의 차이점  (0) 2008.03.31
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
01234567891011121314

'사진 & 여행' 카테고리의 다른 글

어린이날 부천 로봇 댄스대회  (1) 2009.06.05
크리스마스 데스크탑 배경화면 1920*1200  (1) 2008.12.11
순천 & 여수 여행기  (1) 2008.10.10
부산 여행 사진들  (1) 2008.05.14
장옥이 결혼식  (0) 2008.05.14
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667

작년 이맘때쯤 정민이 녀석과 다녀온 부산
2박3일의 짧은 여행이었지만
나에게 좋은 기억만을 안겨준 곳

그리고 처음으로 찍어본 야경사진들

지금의 나와 작년 이맘때즈음의 나
...과연 누가더 행복한 것일까??

'사진 & 여행' 카테고리의 다른 글

어린이날 부천 로봇 댄스대회  (1) 2009.06.05
크리스마스 데스크탑 배경화면 1920*1200  (1) 2008.12.11
순천 & 여수 여행기  (1) 2008.10.10
선유도 공원 주변의 야경들...  (2) 2008.05.14
장옥이 결혼식  (0) 2008.05.14
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

0123456789101112131415

마냥 행복해 보이는 장옥이의
결혼식에서 찍은 사진들
다들 너무 오랫만에 봐서 그런지
평소보다 많이 반가웠던 친구들
그리고 조금은 나이가 들어가는
아쉬움이 교차하는 순간들..

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

ADC - Add with carry -> Rd := Rn + Op2 + Carry

ADD - Add -> Rd := Rn + Op2

AND - AND -> Rd := Rn AND Op2

B - Branch -> R15 := address

BIC - Bit clear -> Rd := Rn AND NOT Op2

BL - Branch with link -> R14 := R15, R15 := address

BX - Branch and exchange -> R15 := Rn, T bit := Rn[0]

CDP - Coprocess data processing -> (Coprocessor-specific)

CMN - Compare Negative -> CPSR flag := Rn + Op2

CPM - Compare -> CPSR flag := Rn - Op2

EOR - Exclusive OR -> Rd := (Rn AND NOT Op2) OR (Op2 AND NOT Rn)

LDC - Load coprocessor from memory -> Coprocessor load

LDM - Load multiple registers -> Stack mainpulation (Pop)

LDR - Load register from memory -> Rd := (address)

MCR - Move CPU register to coprocessor register -> cRn := rRn{<op>cRm}

MLA - Multiply accumulate -> Rd := (Rm x Rs) + Rn

MOV - Move register or constant -> Rd := Op2

MRC - Move from coprocesser or register to CPU register -> Rd := cRn{<op>cRm}

MRS - Move PSR status/flags to register -> Rn := PSR

MSR - Move register to PSR status/flags -> PSR := Rm

MUL - Multiply -> Rd := Rm x Rs

MVN - Move negative register -> Rd := 0 x FFFFFFFF EOR Op2

ORR - OR -> Rm := Rn OR Op2

RSB - Reverse subtract -> Rd := Op2 - Rn

RSC - Recerse subtract -> Rd := Op2 - Rn -1 + Carry

SBC - Subtract with Carry -> Rd := Rn - Op2 -1 + Carry

STC - Store coprocesser register to memory -> address := CRn

STM - Store Multiple -> Stack manipulation (Push)

STR - store register to memory -> <address> := Rd

SUB - Subtract -> Rd := Rn -Op2

SWI - software interrupt -> OS call

SWP - Swap register with memory -> Rd := [Rn] , [Rn] := Rm

TEQ - Test bitwise equality -> CPSR flag := Rn EOR Op2

TST - Test bits -> CPSR flags := Rn AND Op2

'Programming > ARM & Luminary Micro' 카테고리의 다른 글

ARM Cortex-A9의 위엄...  (0) 2010.11.16
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

1 Data Types

우리가 사용하는 데이터는 컴퓨터의 메모리에 연속된 비트의 나열로 저장이 된다. 이러한 비트의 나열은 컴퓨터입장에서는 문제가 안 되겠지만 인간의 입장에서는 알아보기 힘들다는 문제가 발생한다. 그래서 데이터 타입을 두어서 인간이 좀더 쉽게 사용할 수 있도록 하고 있다.

데이터 타입은 다음과 같은 특징을 가지고 있다.
  • 데이터가 어떻게 표현되고 사용 될지를 결정한다.
  • 데이터 타입에 따라 컴퓨터가 어떻게 데이터를 다룰지를 알려주다. (숫자로 다룰지 아니면 문자로 다룰지 등..)
  • 모든 값은 데이터 타입에 의해서 표현될 수 있다.

예를 들어서 메모리에 다음과 같은 비트패턴이 저장되어 있다고 가정해보자.
  0000 0000 0110 0111 
 

이 값이 어떻게 표현될까 ? 이것은 데이터 타입을 어떻게 정의하느냐에 따라 달라진다. 만약 데이터 타입을 'int로 하기로 했다면 숫자 103으로 표현될 것이다. 그러나 문자를 저장하는 char로 하기로 했다면 영문자 g로 표현이 된다.

데이터 타입은 이렇게 인간의 입장에서 컴퓨터 메모리에 저장된 데이터를 어떻게 다룰 것인지를 결정하기 위해서 사용이 된다.

아래의 코드를 실행시켜보기 바란다.
#include <stdio.h> 
 
int main(int argc, char **argv) 
{ 
  int a = 103; 
  char b = 103; 
 
  printf("%d\n", a); 
  printf("%c\n", b); 
} 
 
똑같은 103인데, 서로 다르게 출력되는걸 확인할 수 있을 것이다.

2 Primitive Data Types

인간은 매우 다양한 형태의 데이터를 다루기를 원하고, 그런일을 할 수 있는 프로그램을 만들어 낼 수 있어야 한다. 다루는 데이터의 형태가 다양하니, 데이터 타입 역시 다양하면 좋을 것이다. 그러나 컴퓨터는 매우 단순한 기계다. 쓸데없이 데이터 타입을 이것 저것 만들면, 이것을 다루는 컴퓨터 역시 달가워하지 않을 것이다. 프로그래머 역시 각 데이터 타입에 따른 고려사항이 늘어나니 권장할만한 사항이 아니다.

그래서 데이터타입을 다루어야 하는 프로그래밍 언어는 Primitive Data Type이라고 불리우는 최소한의 반드시 필요한 데이터 타입을 지원하고 있다. Primitive Data Type은 원시 데이터 타입 이라고 부르기도 한다.

각 원시 데이터 타입은 고유의 크기를 가지고 있으며, 표현할 수 있는 데이터의 한계가 정의되어 있다. 다음은 C 언어에서 지원하는 원시 데이터 타입과 크기, 데이터 범위를 보여주는 표다.

2.1 숫자형 원시 데이터 타입

숫자를 표현하기 위해서 사용되는 데이터 타입이다. 크게 정수형 데이터를 표현하기 위한 정수형 원시 데이터 타입부동소숫점형 원시 데이터 타입으로 나눌 수 있다.
  • 정수형 원시 데이터 타입
    char 1byte -128 127
    short 2byte -32768 32767
    long int 4byte 2,147,483,648 2,147,483,647
    long long int 8byte 9,223,372,036,854,775,808 9,223,372,036,854,775,807

이들 정수형 데이터 타입들은 signed비트라는 것을 가지고 있어서, 음수까지 표현할것인지를 정의할 수 있다. 음수까지 표현할 거라면 signed를 양수만 표현할거라면 unsigned를 타입의 앞에 붙여준다. 따로 붙여주지 않았다면 signed 가 붙은걸로 해석을 한다. 즉 위의 데이터 타입은 실제로는 signed char, signed short, signed long int, signed long long int와 동일하다.

unsigned를 명시하게 되면 양의 정수만 표현하게 된다. 음의 정수를 표현할 필요가 없으니 그만큼 양수 쪽으로 표현범위가 늘어날 것이다. unsigned char 이라면 255, unsigned long int 라면 4,294,967,295 가 된다.

  • 부동소숫점형 원시 데이터 타입
    float 4byte +/- 10E-37 +/- 10E38
    double 8byte +/- 10E-307 +/- 10E308

2.2 enumerated type

일반적으로 enumerated 타입은 숫자로 나열된 카테고리 같은 데이터를 만들기 위해서 사용한다. C에서는 enum을 이용해서 enumerated 타입의 데이터를 정의할 수 있다.
enum cardsuit { 
   CLUBS, 
   DIAMONDS, 
   HEARTS, 
   SPADES 
}; 
 
이제 enum 을 이루는 각각의 요소들은 숫자 0,1,2... 로 차례대로 대응되게 된다. 다음의 프로그램을 실행시켜 보자.
#include <stdio.h> 
enum cardsuit { 
  CLUBS, 
  DIAMONDS, 
  HEARTS, 
  SPACES 
}; 
int main() 
{ 
  printf("Card CLUBS is %d\n", CLUBS); 
  printf("Card DIAMONDS is %d\n", DIAMONDS); 
  printf("Card HEARTS is %d\n", HEARTS); 
  printf("Card SPACES is %d\n", SPACES); 
} 
 

다음과 같은 결과를 확인할 수 있을 것이다.
# ./enum 
Card CLUBS is 0 
Card DIAMONDS is 1 
Card HEARTS is 2 
Card SPACES is 3 
 

그렇지만 CLUBS 가 0이 아닌 다른 수로 대응되어야 할 경우도 생길 것이다. 그럴 땐, 필요한 값을 대입시켜 주면 된다. 즉 값을 명시하지 않으면 0부터 시작해서 1씩 증가하고, 값을 명시하면 명시된 값을 시작으로 1씩 증가하는 것으로 보면 된다.

문제
cardsuit를 다음과 같이 정의 했을 때, 어떤 값이 출력될지 생각해 보라.

enum cardsuit { 
  CLUBS = 1, 
  DIAMONDS, 
  HEARTS = 100, 
  SPACES 
}; 
 

2.3 Pointer type

컴퓨터는 계산을 하기 위한 기계다. 이때 계산에 사용될 모든 데이터는 일단 메모리로 읽혀져서 필요한 계산을 하게 된다. 예를 들어 하드디스크에 A 라는 문서가 있다고 가정해 보자. 이 문서를 편집하기 위한 프로그램을 가동시키면, 프로그램은 하드디스크에 있는 문서를 모두 읽어서 컴퓨터의 메모리로 불러들인 다음 필요한 일을 하게 된다. 다른 모든 연산들역시 마찬가지다.

그렇다면 문제가 발생한다. 컴퓨터에는 여러개의 프로그램이 떠 있을테니, 각각의 프로그램이 사용하는 데이터가 메모리의 여기저기 저장되어 있을 것이다. 이때 프로그램은 자신이 사용할 데이터가 메모리상의 어느 위치에 있는지 알고 있어야 한다.

이를 위해서 메모리에는 아래 그림과 같이 주소 값이 부여되어 있다.

pointer.png

프로그램은 이 기억값을 기억해서 데이터의 위치를 정확히 찾아내어서 읽어오게 되는 것이다. Pointer는 이러한 주소값을 저장하는 데이터 타입이다.

다른 데이터 타입들이 그렇듯이 pointer도 고유의 크기를 가지고 있다. pointer 데이터 타입의 크기는 4byte이다. 메모리상의 주소에는 마이너스 값이 필요가 없으므로 0 - 4,294,967,295의 숫자가 저장된다. 32bit 컴퓨터에 사용가능한 메모리의 총크기가 4Giga다 라는 얘기가 여기에서 나온다. 가리킬수 있는 숫자의 범위가 4,294,967,295 (약 4giga)이므로, 이를 초과한 영역에 저장된 데이터는 읽어올 수가 없기 때문이다.

이는 C 와 같은 프로그래밍 언어에도 그대로 적용된다. 포인터의 크기가 4byte 이니, 최대다룰 수 있는 메모리의 크기가 4Giga로 제한이 된다. 물론 여러분이 64bit 컴퓨터운영체제 그리고 컴파일러를 사용한다면 테라 byte급의 데이터를 다룰 수 있다. 64bit 컴퓨터가 대용량 데이터 처리에 유리하다는 얘기가 나오는 이유다.

포인터는 이쯤에서 끝내도록 하겠다. 포인터에 대한 자세한 내용은 따로 한장 정도를 할애해서 자세히 다루도록 하겠다.

3 type casting - 형변환

아래 프로그램을 컴파일 후 실행시켜 보자.
#include <stdio.h> 
 
int main(int argc, char **argv) 
{ 
  unsigned char ch = 'c'; 
 
  printf("%c\n", ch); 
  ch = ch+1; 
  printf("%c\n", ch); 
  ch = ch+1; 
  printf("%c\n", ch); 
} 
 
결과로 c d e 가 출력될 것이다.

이상하군. 분명히 두개는 서로 다른 데이터 타입인데, 더하기가 되는군 ?

앞서 언급했지만, 데이터형이란 표현방식에 따른 것일 뿐이다. 컴퓨터 입장에서는 모두가 비트일 뿐이다. 즉 ch+1은 컴퓨터 입장에서 다음과 같이 계산이 된다.
                               0110 0011   = 'a' 
 0000 0000 0000 0000 0000 0000 0000 0001   = '1' 
 ========================== 
 0000 0000 0110 0100   = 'b' 
 
만약 printf("%d\n" ch+1) 을 한다면, 100 이 출력될 것이다. 비트패턴을 숫자로 표현하도록 표현방식을 바꿨기 때문이다.

이렇게 모두 동일한 비트일 뿐임으로 서로 다른 타입간의 계산이 가능해진다. 그러나 이건 어디까지나 가능하다 일뿐 실제로는 의도하지 않는 다양한 문제가 발생할 수 있다.

  • 데이터타입의 크기에 따른 문제
    데이터 타입은 서로 다른 크기를 가지고 있다. 위의 코드에서 ch 에 1000을 더하면 어떻게 될까. 1099가 나오길 예상할 수 있겠지만 ch의 테이터 타입인 char는 1byte의 크기로 255까지만 표현이 가능하다. 때문에 데이터 저장공간을 초과하게 될 것이다. 실제로는 1byte의 상위 비트는 버려지게 된다. 고로 0-255까지의 값이 출력이 될것이다. 뭐.. 값이 255를 초과하지 않는 범위에서 연산을 한다면 문제가 없기는 하겠지만 실수로 문제가 발생할 소지가 다분하다.

    다른 데이터 타입끼리라도 주의해서 프로그래밍을 하면 문제 없겠지만 가능하면, 타입을 맞추어서 계산을 하는게 좋다.

  • signed bit 문제
    정수형 데이터 타입은 signed bit 를 가지고 있어서 이걸로 양수인지 음수인지를 판단하게 된다. 다음의 코드를 확인해 보자.

    #include <stdio.h> 
     
    int main(int argc, char **argv) 
    { 
      unsigned int i = 100; 
     
      if (i < -10) 
      { 
        printf("Large\n"); 
      } 
    } 
     
    상식적으로 100 은 -10보다 크기 때문에 if문의 블럭은 실행되지 않아야 겠지만, 컴파일해서 실행시켜 보면 블럭문이 실행이 되는걸 알 수 있다. 이는 i 가 unsigned 형으로 -10 을 unsigned 형으로 보고 비교를 하기 때문이다. -10이 unsigned 형이 되면 4,294,967,285 으로 표현이 된다. 이를 이해하기 위해서는 2의 보수를 통한 singed 데이터 처리에 대해서 알고 있어야 하는데, 5장 데이터와 비트문서를 읽어보기 바란다.

    이 문제를 해결하기 위해서 형변환을 수행한다. 위의 프로그램의 경우 문제를 피해가는 가장 좋은 방법은 i를 signed 형으로 선언하는게 될것이다. 그러나 불가피 하게 unsigned 형을 고집해야 할 경우가 발생한다. 그때는 casting(형변환)연산자를 통해서 형변환을 하도록 한다.

    if ((signed)i < -10) 
    { 
    ... 
    } 
     
    이제 제대로 되는걸 확인할 수 있을 것이다.

프로그램을 작성할 때는 데이터가 어디에 쓰일 것인지를 명확히 해서, 그에 맞는 데이터 타입을 지정해 줘야 한다. 그렇지만 사람이다 보니, 위에서 처럼 사소한 실수를 하기도 한다. 문제는 이런 프로그램도 문제 없이 컴파일이 된다는 것이다. 결국 프로그램이 실행하는 도중에 문제를 일으키게 될 것이다. 다행히 gcc 컴파일러는 컴파일 옵션을 통해서 저러한 문제를 사전에 잡아낼 수 있게 하고 있다. 위 프로그램을 type.c로 저장하고 아래와 같은 옵션을 주고 컴파일 해보자.
# gcc -W -Wall -o type type.c 
... 
type.c:7: warning: comparison between signed and unsigned 
... 
 
comparison between signed and unsigned와 같은 경고메시지를 출력함을 알 수 있다. 자세한 내용은 리팩토링 : 모든 경고메시지를 제거하라 문서를 읽어보기 바란다. 아직 읽기 버겁다면, 그냥 대충 저런게 있나보다 하는 수준에서 읽어두어도 도움이 될 것이다.

4 문자와 문자열 표현

데이터는 크게 문자와 숫자로 이루어져 있음을 알고 있다. 그런데 정작 문자문자열을 표현하기 위한 데이터 타입을 다룬거 같지를 않다. 이에 대해서 얘기해 보고자 한다.

C 언어에서 문자를 위한 데이터 타입으로는 char 데이터 타입을 사용한다. char 는 1byte 256의 크기를 가지는데, 1byte 문자권의 영어와 수십개의 특수문자를 충분히 표한할 수 있는바 char를 문자를 저장하기 위한 데이터 타입으로 사용하고 있다.

컴퓨터에서 표현되는 문자는 0에서 255까지의 각 크기에 대응되는 문자들이 표준으로 정의되어 있다. 각 값에 대응되는 문자는 ASCII 테이블로 정리되어 있다.

http://www.joinc.co.kr/albums/album01/age.gif

http://www.joinc.co.kr/albums/album01/agf.gif

그러나 ASCII 테이블만 가지고는 일본어, 한글, 중국어와 같은 2byte 문자는 표현할 수 없다. 2byte 문자는 char를 2개 이상 사용해서 저장해야 한다.

이제 마지막으로 문자열이 남았다. C는 문자열을 위한 데이터 타입을 가지고 있지 않다. C에서 문자열을 처리하기 위해서는 배열을 사용해야만 한다. 이것은 원시 데이터 타입을 여러개를 포함하고 있는 데이터 구조다. 예를 들어 문자열은 char를 여러개 포함할 수 있는 데이터 구조를 이용하면 표현할 수 있을 것이다. 배열은 다음장에서 자세히 다루도록 하겠다.

5 typedef 를 이용한 타입 재정의

데이터 타입은 타입에 맞는 고유한 이름을 가지고 사용하게 된다. 그런데 타입의 이름이 너무 길 경우, 이를 이용해서 프로그램을 작성할 경우 불편한 점이 발생한다. 다음의 경우를 보자.
int main() 
{ 
  unsigned long int a; 
  unsigned long int b; 
  unsigned long long c; 
  ... 
} 
 
사용하는데 문제는 없겠지만, 저렇게 긴 타입의 변수가 여기저기에 생성된다면 가독성이 떨어지는 지저분한 코드가 만들어질 가능성이 있다. 이럴경우 typedef 를 이용해서 기존의 데이터 타입을 다른 짧은 이름으로 재정의 해서 사용할 수 있다. typedef는 다음과 같이 사용할 수 있다.
typedef [원래 데이터 형] [재정의될 데이터 타입의 이름] 
 
typedef를 이용하면, 다음과 같이 코드를 깔끔하게 만들 수 있다.
typedef unsigned long int uint; 
typedef unsigned long long ulint; 
 
int main() 
{ 
    uint a; 
    uint b; 
    ulint c; 
} 
 

6 문제

  1. char 데이터 타입을 이용해서 hello world를 화면에 출력해 보자.
    • char를 여러개 써야함.
    • printf 를 통해서 출력할 수 있음.
  2. char 데이터 타입을 이용해서 hello world를 출력해보자. 단 정수형 숫자를 사용해야 한다.
    • ASCII 테이블을 이용하면 됨.
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

◉ 어드레싱 모드(addressing mode)

프로그램이 수행되는 동안 피연산자가 지정되는 방법은 명령어의 어드레싱 모드에 의해 좌우된다.

어드레싱 모드는 실제의 피연산자를 정하기 위해 명령어 속에 있는 주소 필드의 값을 수정하거나 다른 것으로 대체하는 것들을 규정한다.

포인터, 카운터 인덱싱, 프로그램 리로케이션 등의 편의를 사용자에게 제공함으로써 프로그래밍을 하는데

융통성을 주거나 명령어의 주소 필드의 비트를 줄이기 위해 어드레싱 모드 기법이 사용된다.

• 함축 어드레싱 모드(implied addressing mode mode)

• 즉치 어드레싱 모드(immediate addressing mode)

• 레지스터 어드레싱 모드(register addressing mode)

• 레지스터 간접 어드레싱 모드(register indirect addressing)

• 변위 어드레싱 모드(displacement addressing mode)

• 직접 어드레싱 모드(direct addressing mode)

• 간접 어드레싱 모드(indirect addressing mode)

• 상대 어드레싱 모드(relative addressing mode)

• 인덱스 어드레싱 모드(indexed register addressing mode)

• 베이스 레지스터 어드레싱 모드(base register addressing)


함축 어드레싱 모드(implied addressing mode)

명령어 실행에 필요한 오퍼랜드를 지정하지 않아도 묵시적으로 수행하는 방식.

메모리를 참조하지 않고

• 레지스터 단독으로 수행하는 방법.

• 장점 : 명령어 길이가 짧다.

예)

SHL : 누산기의 내용을 좌측으로 시프트하는 명령어

CPL : Acc의 내용을 1의 보수하여 다시 누산기에 로드하는 명령


즉치 어드레싱 모드(immediate addressing mode)

오퍼랜드에 연산에 필요한 숫자 데이터를 직접 넣어주는 방식.

명령어 자신이 데이터를 직접 포함하고 있어 명령어의 실행이 바로 이루어지는 방법.

• 데이터를 구하기 위해 메모리를 액세스할 필요가 없음.

• 상수를 정의하거나 변수값을 초기화하는데 편리하게 사용.

• 사용할 수 있는 수의 크기가 오퍼랜드 필드의 크기로 제한.

 

레지스터 어드레싱 모드(register addressing mode)

• 연산에 사용할 데이터가 레지스터에 저장되어 있으며 레지스터를 참조하는 지정 방식.

• 오퍼랜드 필드의 내용은 레지스터 번호이며 그 번호가 가리키는 내용이 명령어 실행 데이터로 사용.

장점 : 명령어에서 오퍼랜드 필드의 길이가 적어도 되고 데이터 인출을 위한 메모리 접근이 필요 없다.

• 유효주소는 레지스터의 번지가 된다.

 

레지스터 간접 어드레싱 모드(register indirect addressing mode)

오퍼랜드 필드가 레지스터의 번호(레지스터의 내용이 가리키는 메모리가 유효 주소)이다.

지정 레지스터의 내용은 실제 데이터를 인출함.

기억장치 영역은 레지스터의 길이에 달려 있다.

 

변위 어드레싱 모드(displacement addressing mode)

• 두개의 오퍼랜드를 가지며 직접 주소지정방식과 레지스터 간접 주소지정방식을 조합하여 수행.

• 첫 번째 오퍼랜드는 레지스터의 번호, 두 번째 오퍼랜드는 변위를 나타내는 주소.

• 유효 주소= 변위 + 레지스터의 내용

 

직접 어드레싱 모드(direct addressing mode)

오퍼랜드 필드의 내용이 실제 데이터가 들어 있는 메모리 주소를 지정하고 있는 유효주소가 되는 방식.

메모리에 저장되어 있는 데이터를 인출하기 위해 한번만 메모리에 접근하면 되므로 유효주소 결정을

위한 다른 절차나 계산이 필요없다.

• 장점 : 오퍼랜드가 메모리의 번지가 되기 때문에 간단함.

단점 : 오퍼랜드의 비트 수가 제한되어 있기 때문에 직접 접근할 수 있는 기억장치 주소 공간이 제한.

 

간접 어드레싱 모드(indirect addressing mode)

• 오퍼랜드 필드의 값이 해당하는 주기억장치 주소를 찾아 간 후 그 주소의 내용으로 다시 한 번 더

주기억장치의 주소를 지정하는 방식.

직접 주소지정방식에서 주소를 지정할 수 있는 기억장치 용량이 제한되는 단점을 해결하기 위한 방법.

• 장점 : 메모리의 번지지정을 더 크게 할 수 있다.

• 단점 : 명령어 실행 과정에서 두 번씩 메모리를 참조함으로써 시간이 많이 걸린다.

 

상대 어드레싱 모드(relative addressing mode)

• 유효주소 = (현재 명령어의 오퍼랜드 내용) + (프로그램 카운터의 내용)

• 장점 : 전체 메모리 주소가 명령어에 포함되어야 하는 일반적인 분기 명령어보다 적은 수의 비트만

있으면 된다.

 

인덱스 어드레싱 모드(indexed register addressing mode)

• 유효주소 = 인덱스 레지스터의 내용 + 변위

• 인덱스 레지스터는 인덱스 값을 저장하는 특수 레지스터.

• 변위는 기억장치에 저장된 데이터 배열의 시작 주소를 가리킨다.

• 인덱스 레지스터의 내용은 그 배열의 시작주소로부터 각 데이터까지의 거리를 나타낸다.

 

베이스 레지스터 어드레싱 모드(base register addressing mode)

• 유효주소 = 베이스 레지스터의 내용 + 변위

• 프로그램 전체를 재배치에 사용.

[출처] 어드레싱모드|작성자 빅초이

'Programming > 그밖에...' 카테고리의 다른 글

Touch screen Calibration  (0) 2009.09.10
CIE L*a*b*  (0) 2009.06.01
단위환산표  (0) 2008.05.21
PIC Basic으로 구현한 자동응답 디지털 도어락  (0) 2008.05.15
MMU와 MPU의 차이점  (0) 2008.03.31
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
[ MMU와 MPU의 차이점]
  - 출처: http://cafe.naver.com/elp.cafe
  - MMU 와 MPU | 소프트웨어 강좌 
  - 2004.04.29 12:20 
  - cslee03   http://cafe.naver.com/elp/134

**** MMU(Memory Management Unit)와 MPU(Memory Protection Unit)
- Memory를 관리한다는 점에서 비슷
- 하지만 MMU와 MPU는 다름
- 정확하게 얘기하자면 MMU는 MPU 기능외에 복잡한 기능을 가지고 있음
  일단 MMU및 MPU에 대한 H/W적인 정보를 원하신다면 www.arm.com에서 관련 정보를 얻으 실수 있읍니다.

**** ARM9에서
- ARM920계열은 MMU를 장착한 Core
- ARM940 계열은 MPU를 장착한 Core
  해당 계열의 Refrence Manual을 다운받아 보시면 MMU및 MPU구조에 대한 설명이 잘 나와 있읍니다.
  ARM946ES(940계열, MPU) http://www.arm.com/pdfs/DDI0155A_946ES.pdf
  ATM920T(920계열 MMU) http://www.arm.com/pdfs/DDI0151C_920T_TRM.pdf


해당 Manual을 보시면 설명이 자세히 나와 있으며,
MMU및 MPU을 이해하시기 위해서는 Cache에 대한 Concept 또한 이해하셔야 합니다.

**** MMU와 MPU에 대해 크게 두가지로 구분
1. MMU와 MPU의 구조, 기능적인 차이(H/W관점)
2. S/W개발에 있어서 MMU와 MPU는 어떤 차이점

우선
1. MPU는 CPU에 Attach된 RAM을 관리하는 장치

Memory를 여러개의 Partition으로 나누어서 Cache/Non-Cache Region등을 나눌수 있고
각 Region별로
- Read/Write Permission을 제어
- Write Bufferable Region등을 지정

간단히 말하면,
메모리를 user가 원하는 대로 나누어서
- Cache Region
- Non-Cache Region
- Write Bufferable Region
- non-Bufferable Region
- Read Only Region
- Read/Write Region
으로 Configure할 수 있으며, Cache관련하여 Invaliation, Clean, Flush등등의 기능을 제공

ARM core에서는 MPU Control
- cp15 register group
- mcr/mrc instruction
을 이용합니다.

__________________________________________________________
| MMU는                                                    |
| MPU가 갖는 기능은 물론 아주 특별히 중요한 기능을 가짐    |
| Virtual Address <-> Physical Address Mapping 기능입니다. |
| 즉 CPU Core에서 발생시키는                               |
|    Virtual Address를 Physical Address로 Mapping하여      |
|    Physical Address로 실제 Memory를 Access하게 됩니다.   |
----------------------------------------------------------

MPU에서는 Virtual Address의 개념이 없읍니다.
즉 Physical Address와 Virtual Address는 항상 1:1 mapping되며,
따라서
User(program)은 항상 DRAM의 physical address를 가지고 memory를 접근하게 됩니다.

반면에
MMU의 경우 Virtual Address <-> Physical Address Mapping기능을 제공합니다.

이러한 기능을 제공하면 어떤 장점이 있냐구요?
여러가지 장점이 있읍니다. 이중 가장 중요한 두가지 점만을 적어 봅니다.

(1) 먼저 memory운영에 있어서 실제 Physical한 Address영역을 Virtual Address로 접근하여 사용함으로써 Memory의 사용 효율을 높일수 있읍니다. 예를 들어 System Booting후에 각종 Program에서 Memory를 이것 저것 사용하다보니 쪼가리 RAM이 여기저기 생겼다라고 가정해 보십시오. 이들 Memory의 Physical Address는 연속적인 Address영역에 존재하지 않읍니다. 예를 들어

0x10000 ~ 0x10200, 0x10600~0x10800, 0x10a00~0x10c00의 사용되지 않은 영역이 있다고 합시다.

보통 프로그램 수행시에, 프로그램은 독립적인 Stack및 Heap영역을 사용하게 되고, 이 영역은 연속적인 Memory Address영역에 존재하여야 합니다. 원칙적 어떤 프로그램이 0x600의 메모리는 원한다하더라도 위의 세영역을 사용할 수 없읍니다. 이유는 연속적인 영역이 아니기 때문이죠. 우리가 코드를 Compile하고 Linking하여 Image를 만들때, 혹은 그 코드내에서 memory를 Allocation받을때 언제나 연속적인 Memory영역을 가정합니다.

근데 MMU가 있는 경우는 상황이 달라집니다.
- MMU는 Virtual Address <-> Physical Address의 Mapping기능을 제공
- 따라서 0x10000 ~ 0x10200, 0x10600~0x10800, 0x10a00~0x10c00의 Physical Address를 0xa0000~0xa0600으로 mapping시킬수 있읍니다.
(참고로 이것은 예일뿐 보통 mapping의 단위는 이와 같이 작지 않고 256K, 512K, 1M...와 같이 근값입니다, 단지 설명을 위한 예라는 점을 기억하세요)

따라서 실제 CPU는 0xa0000~0xa0600의 연속적인 address영역을 사용하고 이를 MMU가 physical address로 mapping하여 0x10000 ~ 0x10200, 0x10600~0x10800, 0x10a00~0x10c00의 영역을 access하게 됩니다.
어떠세요? 이렇게 사용하면 Memory Utilization이 높아지겠죠? 훌륭합니다.
좀 있어보이는 용어로 압축하여 표현하자면 Memory Fragmentation문제를 해결합니다.
있어보이나여? :)


(2) MPU는 Physical Address <-> Virtual Address가 1:1 mapping이라고 했읍니다.
그럼 예를 들어 메모리가 8M이면 8M이상의 크기를 갖는 Application은 어케 동작 할 수 있을까여?
MPU즉 physical, virtual address가 1:1, 즉 같은 값을 갖는 경우라면 불가능 합니다.
하지만 MMU가 있는 경우 상황이 달라집니다.
MMU는 Memory뿐만 아니라 HDD, Flash등등의 영역을 Memory Address로 mapping시킨다음 이를 Memory와 같이 사용할 수 있도록 합니다.
CPU가 어떤 Address를 Access할떄 MMU는 해당 Address가 DRAM상의 address인지, 아니면 HDD와 같은 Device에 memory와 같이 할당된 Address인지 분별하고, memory address인 경우 해당 virtual address에 해당하는 physical address를 이용memory를 access하고, 만약 memory address아니라면 해당 device(예를 들어 HDD)에서 정보를 가져오게 됩니다.
이때 해당 영역을 memory로 Loading하게 됩니다. 이러한 mapping을 위해 MMU는 내부에 mapping table을 가지고 있읍니다.
어떻게 생각하세요? 보통 PC를 생각할때는 이와 같은 기능은 없어서는 안돠겠죠? 또 한번 훌륭합니다.



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

두번째로 S/W를 개발하는 입장에서 MMU와 MPU는 어떤 차이점을 유발하는가?



이문제는 그야 말로 Case By Case라고 봅니다.

어떤 분은 MMU없는 것은 사용하기도 싫다 라고 말씀하시던데...제 의견은 그렇지 않습니다. 자신이 개발하려는 목적에 따라 MPU가 좋을 수도 있고, MMU가 좋을 수도 있읍니다.



일단 Linux를 Embedded용으로 많이 사용하시는데, Linux에 있는 많은 Application들을 그대로 사용하시고 싶다면 MMU가 있어야 겟죠. 즉 절라 크기가 큰 Application들을 전부 올리구, PC version으로 release되는 application들을 별 고민 없이 사용하고자 하신다면 MMU있어야 합니다. 주로 application개발 하시는 분들이 원하시는 바죠. 예를 들어 PDA개발하시는 분은 MMU있는 버전 사용하셔야 합니다. 왜냐? Graphic, Window, Application,Game등등 Memory크게 필요한 Application많습니다. HDD나 Flash달아서 memory상에서만 program이 돌지 않고 스위칭하게 됩니다. 따라서 MMU가 없는 경우 memory 크게 달아야 하고, program도 알맞게 수정되어야 합니다. memory와 HDD의 가격은 단순히 비교해서 하드가 80G에 10만원이면 Memory는 256M 10만원....

으...엄청 차이납니다. 글서 Program을 RAM에만 올려서 사용하신다면 돈좀 들여야 할 것 같습니다.



반면에 VDSL Router, IP 공유기 같은 네튼워크 제품 개발하시는 분들....MMU필요없읍니다. Protocol Stack이나 Network Application등은 크기 작습니다. 애써 memory외에 다른 장치에 Program올려놓을 필요없읍니다. 괜히 올렸다가 성능 떡이 되어(memory Access속도는 엄청 빠르죠? HDD에 비교하면 말이여...) 욕 얻어 먹고 팔지도 못합니다. Memory Fragmentation? 요새 Memory엄청 쌉니다. 그거좀 아껴보겟다고 MMU사용합니까? 미친짓입니다...



이외에 H/W적인 특징 외에 개발 과정에 있어서의 문제점두 있읍니다. 예를 들어 linux에서 shared library를 사용하고 싶은데, MMU 장착 CPU용으로 release된 linux에서는 이를 지원하는데 MPU 장착 CPU용으로는 release된 linux에서는 없다면????? 이는 H/W적인 문제에 기인하는 것이 아닙니다. 단지 해당 CPU용으로 Code가 안만들어 졌기 때문이죠... 여기서 한가지 집고 넘어갈 것은 Linux에서 가장 먼저 개발되는 것은 PC용입니다. PC요? 아시다시피 현존하는 가장 빠른 대중화된 CPU인 Pentium씁니다. MMU당근 있죠....글서 처음 개발 되는 각종 코드는 해당 base하에 작성 됩니다. 글서 MPU를 갖는 CPU를 기반으로 어떤 제품을 만들때 특정 Application을 올리려면 기다려야 한다거나 고생을 하는 경우가 많습니다. 물론 개발자 자신이 MMU가 있는 버전용으로 작성된 각종 코드를 맘대루 수정하고 핸들링 하여 사용할 수 있다면 문제 없겠지만....소규모 개발 집단에서 하기에는 버겁습니다.



결국 자신이 개발하려는 제품이 먼지...해당 제품에서 필요한 S/W기능(Stack, Application)이 먼지, 그러한 S/W가 MPU Based Linux에 Porting되어 있는지 알아보셔야 합니다. 이렇게 설명하면 복잡한가여? 남들이 개발 해놓은 스펙을 많이 참고하세요. 즉 Bech-Marking한 제품이 어떤 CPU를 사용하고 어떤 Linux를 사용했는데 어떤 Application이 올라가있더라.... 그렇게 파악할 수 있읍니다. 일단 그렇게 타겟을 잡고 좀더 구체적으로 자신이 사용하고자 하는 Linux에서 사용할 수 있는(큰 수정 없이) S/W를 체크해 봅니다.

예를 들어 IPSec을 개발하고자 합니다. MMU없는거 사용하고 싶습니다. 글서 글로트렉스 Cello 사용하고자 합니다. Cello에는 uClinux사용한다고 합니다. uClinux찾아보니 IPSec(freeSWAN)을 지원합니다. 그럼 사용할 수 있는 거지요... (글로트렉스 광고해서 죄송합니다. :) )



마지막으로 MPU구 어쩌구 저쩌구 MMU > MPU라면 머하러 MPU사용합니까? 라고 질문하시는 분들을 위해 한마디 더...

(1) 첫째 가격...

MMU있는거 가격 비쌉니다. 이유는 ARM의 경우만 하더라고 MMU가 있는 Core(ARM920 Series)는 MPU가 있는 Core(ARM940 Series)보다 Silicon 크기가 2-3배 정도 됩니다. 즉 생산 단가가 비싸진다는 거죠...당근 판매단가 비쌉니다. 머어 허기사 이는 실제 생산 단가일뿐 때로는 시장에서 미친척하는 손해보구 파는 회사두 있읍니다.

(2) 둘째 편리성

MPU의 경우 Virtual<--> Physical Address가 1:1mapping되므로 암생각없이 어디서나 Memory Directly Access가능합니다. 별로 중요하지 않다고생각하실수 있으나 , 실제 성능을 높인다거나 할떄 복잡한 구조적 코딩 대신 성능 위주의 코딩시에 매우 유용합니다.



마지막으로 드리고 싶은 말은 MPU/MMU에 대해 공부하실때 Cache Management에 대해서도 같이 공부하셔야 이해도 쉽고, 얻는 것도 많습니다

'Programming > 그밖에...' 카테고리의 다른 글

Touch screen Calibration  (0) 2009.09.10
CIE L*a*b*  (0) 2009.06.01
단위환산표  (0) 2008.05.21
PIC Basic으로 구현한 자동응답 디지털 도어락  (0) 2008.05.15
어드레싱모드(addressing mode)  (0) 2008.04.01
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

유닉스/리눅스 명령어 레퍼런스


파일 명령어

ls - 디렉토리 목록보기
ls -al - 숨은 파일까지 정렬된 형태로 보기
cd dir - dir 디렉토리로 이동
cd - home 디렉토리로 이동
pwd - 현재 위치한 디렉토리 보여주기
mkdir dir - dir라는 디렉토리 만들기
rm file - file을 지우기
rm -r dir - dir 디렉토리를 지우기
rm -f file - 강제로 file 삭제
rm -rf dir - dir 디렉토리와 디렉토리 아래에 있는 모든 파일 삭제
cp file1 file2 - file1을 file2라는 이름으로 복사
cp -r dir1 dir2 - dir1 디렉토리에 있는 것들을 dir2 디렉토리로 복사; dir2가 존재하지 않는다면 만듬
mv file1 file2 - file1을 file2로 이름을 바꾸거나 옮김,
file2가 디렉토리로 존재한다면 file1을 file2 디렉토리로 옮김
ln -s file link - file로 연결된 link라는 심볼릭 링크를만듬
touch file - file을 생성하거나 업데이트
cat > file - 입력을 file로 저장
more file - file의 내용을 출력
head file - file의 첫 10줄을 출력
tail file - file의 마지막 10줄을 출력
tail -f file - file에 추가되는 내용을 출력,마지막10줄부터 출력함


프로세스 관리
ps - 현재 활성화된 프로세스 보여주기
top - 실행중인 모든 프로세스 보여주기
kill pid-프로세스id pid를 종료
killall proc - proc로 시작하는 모든 프로세스 종료
bg - 정지되있거나 화면에서 안보이게 실행중인 프로세스 보여주기; 정지된 프로세스를 화면에 출력하지 않고 계속 진행하기
fg - 화면에 보이지 않게 작동하던 작업 중 최근의 것을 화면에출력하면서 작동시키기
fg n - 화면에 보이지 않게 작동하던 작업 중 n 번째 작업을 화면에 출력하면서 작동시키기


파일 퍼미션
chmod 숫자 file - file의 퍼미션값을 숫자로 바꿈. 숫자는 3자리이며 첫 번째는 소유자,두 번째는 그룹,
세 번째는 익명의권한을 더해서 나타냄.
파일 퍼미션
chmod 숫자 file - file의 퍼미션값을 숫자로 바꿈. 숫자는 3자리이며 첫 번째는 소유자,두 번째는 그룹, 세 번째는 익명의
권한을 더해서 나타냄.

SSH
ssh user@host - user로 host에 접속
ssh -p 포트넘버 user@host - host의 지정한 포트넘버에
user로 접속
ssh-copy-id user@host-사용자명,암호를 입력하지 않고
로그인 할 수 있도록 ssh key를 복사


검색
grep pattern files - file안의 pattern을 찾기
grep -r pattern dir - dir 디렉토리 안에서 재귀적으로pattern 찾기
command | grep pattern - command 명령의 출력에서pattern을 찾는다
locate file - 파일을 찾음


시스템 정보보기
date - 현재 날짜와 시각을 출력
cal - 이번달 달력을 출력
uptime - 현재 기동시간을 출력
w - 온라인인 사용자를 출력
whoami - 어느 사용자로 로그인 하였는지 출력
finger user -user에 관한 정보 출력
uname -a - 커널 정보 출력
cat /proc/cpuinfo - cpu 정보 출력
cat /proc/meminfo - 메모리 정보 출력
man command - command에 대한 매뉴얼 출력
df - 디스크 사용량 출력
du - 디렉토리 사용량 출력
free - 메모리와 스왑 정보 출력
whereis app - app를 실행가능한 위치 출력
which app - app가 기본으로 실행되는 곳을 보여줌


압축
tar cf file.tar files - files들을 포함한 file.tar를 만듬
tar xf file.tar - file.tar을 압축해제
tar czf file.tar.gz files - Gzip 압축을 사용한 압축
tar zxf file.tar.gz - Gzip을 이용해 압축해제
tar cjf file.tar.bz2 - Bzip2 압축을 사용한 압축
tar xjf file.tar.bz2 - Bzip2 압축을 사용한 압축해제
gzip file - file을 압축해서 file.gz로 이름변경
gzip -d file.gz - file.gz를 fiel로 압축해제


네트워크
ping host - host에 핑을 보내 결과 출력
whois domain - domain에 대한 whois 정보 출력
dig domain - domain에 대한 DNS 정보를 출력
dig -x host - 호스트까지의 경로를 되찾아가기


설치
소스로부터 설치
./configure
make
make install
dpkg -i pkg.deb - 패키지 설치(Debian)
rpm -Uvh pkg.rpm - 패키지 설치(RPM)


단축키
Ctrl+C - 현재 명령의 실행을 강제로 마침
Ctrl+Z-현재 명령을 멈춤,fg를 이용해서 계속해서 화면에서 보
이도록 실행하거나 bg 를 이용해서 안보인채 계속 실행
Ctrl+D-현 세션에서 로그 아웃,exit와 비슷
Ctrl+W - 현재 라인에서 한 단어 삭제
Ctrl+U - 현재 줄 전체 삭제
Ctrl+R - 최근 입력한 명령어 보여주기
!! - 마지막 명령어 반복실행
exit - 현재 세션에서 로그 아웃

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

SIGACTION

Section: Linux Programmer's Manual (2)
Updated: 8 May 1999
Index
Return to Main Contents
 

이름

sigaction, sigprocmask, sigpending, sigsuspend - POSIX 시그널 처리 함수  

사용법

#include <signal.h>

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

int sigpending(sigset_t *set);

int sigsuspend(const sigset_t *mask);  

설명

sigaction 시스템 호출은 특정 시그널이 수신되었을 때, 프로세스가 취할 액션을 변경하는데 사용된다.

signum 는 시그널을 가리키며, SIGKILLSIGSTOP 를 제외한 모든 시그널 값이 될 수 있다.

act 가 null이 아닐 때, 시그널 signum 에 대한 새로운 액션은 act 가 되며, oldact 이 null이 아닐 때, 기존의 액션은 oldact 에 저장된다.

sigaction 구조는 다음과 같이 정의된다.


struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
}

아키텍쳐에 따라 공용체로 되어 있기도 하므로, sa_handlersa_sigaction 을 모두 지정하지 말라.

sa_restorer 요소는 쓰이지 않으며, 사용되어서는 안된다. POSIX는 sa_restorer 요소를 갖지 않는다.

sa_handlersignum 시그널이 오면 실행되는 액션을 명시하며, 디폴트 액션을 취하라는 SIG_DFL , 시그널을 무시하라는 SIG_IGN , 시그널을 처리하는 특정 함수에 대한 포인터 중의 하나가 될 수 있다. 세번째의 경우 시그널 처리 함수는 시그널 번호만을 유일한 인수로 갖는다.

sa_sigaction 또한 signum 시그널과 연결된 액션을 명시한다. 처리 함수는 시그널 번호를 첫번째 인수로, siginfo_t 에 대한 포인터를 두번째 인수로, 그리고 void형 포인터로 캐스트된 ucontext_t 에 대한 포인터를 세번째 인수로 갖는다.

sa_mask 는 시그널 핸들러의 실행 동안 블록화되어야 하는 시그널의 마스크를 제공한다. 또한, SA_NODEFER 또는 SA_NOMASK 이 사용되지 않으면, 핸들러를 시동시켰던 그 시그널도 블록화된다.

sa_flags 는 시그널 처리 프로세스의 행위를 변경시키는 일련의 플래그들을 명시한다. 이는 bitwise 혹은 플래그는 아래 플래그 들의 0개 이상의 OR 비트 연산으로 만들어진다.


SA_NOCLDSTOP
signumSIGCHLD 이면 자식 프로세스가 중지되어도 통지를 받지 않는다. (즉, 자식 프로세스들이 SIGSTOP, SIGTSTP, SIGTTIN , SIGTTOU 중 하나를 수신할 때)
SA_ONESHOT 또는 SA_RESETHAND
시그널 처리기가 호출되어 한번 실행된 후, 시그널 액션을 원래의 디폴트 액션으로 되돌려 놓는다. (이는 signal(2) 호출에 대한 기본 행위이다.)
SA_RESTART
일부 시스템 호출들이 시그널을 통해 재시작할 수 있도록 함으로서 BSD 시그널과의 호환성을 제공한다.
SA_NOMASK or SA_NODEFER
어떤 시그널 처리기의 동작동안 그 시그널 자신을 막지 않는다.
SA_SIGINFO
시그널 처리기가 한 개가 아닌 3개의 인수를 취한다. 이 경우, sa_handler 대신에 sa_sigaction 이 설정되어야 한다. (sa_sigaction 필드는 리눅스 2.1.86에서 추가되었다.)

sa_sigactionsiginfo_t 변수는 다음의 요소들을 갖는 구조체(struct)이다.


siginfo_t {
int si_signo; /* 시그널 넘버 */
int si_errno; /* errno 값 */
int si_code; /* 시그널 코드 */
pid_t si_pid; /* 프로세스 ID 보내기 */
uid_t si_uid; /* 프로세스를 전송하는 실제 사용자 ID */
int si_status; /* Exit 값 또는 시그널 */
clock_t si_utime; /* 소모된 사용자 시간 */
clock_t si_stime; /* 소모된 시스템 시간 */
sigval_t si_value; /* 시그널 값 */
int si_int; /* POSIX.1b 시그널 */
void * si_ptr; /* POSIX.1b 시그널 */
void * si_addr; /* 실패를 초래한 메모리 위치 */
int si_band; /* 밴드 이벤트 */
int si_fd; /* 파일 기술자 */
}

si_signo, si_errno 그리고 si_code 는 모든 시그널에 대해 정의되었다. kill(2), POSIX.1b 시그널과 SIGCHLD은 si_pidsi_uid 을 채운다. SIGCHLD 은 또한 si_status, si_utime, si_stime 을 채운다. si_int 그리고 si_ptr 는 POSIX.1b 시그널의 송신자에 의해 명시된다. 좀더 자세한 사항을 보려면, sigqueue(2) 을 참조하라. SIGILL, SIGFPE, SIGSEGV 그리고 SIGBUS은 si_addr 를 오류의 주소로 채운다. SIGPOLL 은 si_bandsi_fd 를 채운다. si_code 는 왜 시그널이 보내졌는지에 대해 지시한다. 이는 bitmask가 아닌 값이다. 나올 수 있는 모든 시그널 값은 이 테이블에 나열되어 있다.

si_code
Value Signal origin
SI_USER kill, sigsend or raise
SI_KERNEL The kernel
SI_QUEUE sigqueue
SI_TIMER timer expired
SI_MESGQ mesq state changed
SI_ASYNCIO AIO completed
SI_SIGIO queued SIGIO
SIGILL
ILL_ILLOPC illegal opcode
ILL_ILLOPN illegal operand
ILL_ILLADR illegal addressing mode
ILL_ILLTRP illegal trap
ILL_PRVOPC privileged opcode
ILL_PRVREG privileged register
ILL_COPROC coprocessor error
ILL_BADSTK internal stack error
SIGFPE
FPE_INTDIV integer divide by zero
FPE_INTOVF integer overflow
FPE_FLTDIV floating point divide by zero
FPE_FLTOVF floating point overflow
FPE_FLTUND floating point underflow
FPE_FLTRES floating point inexact result
FPE_FLTINV floating point invalid operation
FPE_FLTSUB subscript out of range
SIGSEGV
SEGV_MAPERR address not mapped to object
SEGV_ACCERR invalid permissions for mapped object
SIGBUS
BUS_ADRALN invalid address alignment
BUS_ADRERR non-existant physical address
BUS_OBJERR object specific hardware error
SIGTRAP
TRAP_BRKPT process breakpoint
TRAP_TRACE process trace trap
SIGCHLD
CLD_EXITED child has exited
CLD_KILLED child was killed
CLD_DUMPED child terminated abnormally
CLD_TRAPPED traced child has trapped
CLD_STOPPED child has stopped
CLD_CONTINUED stopped child has continued
SIGPOLL
POLL_IN data input available
POLL_OUT output buffers available
POLL_MSG input message available
POLL_ERR i/o error
POLL_PRI high priority input available
POLL_HUP device disconnected

sigprocmask 호출은 현재 블록화된 시그널들을 변경시키는데 사용된다. 호출은 지정된 how 값에 따라 다르게 동작한다.


SIG_BLOCK
set 인수가 지정한 시그널 집합이 블록시킬 시그널 집합에 더해진다.
SIG_UNBLOCK
set 에 포함된 시그널들이 블록시킬 시그널들의 집합에서 삭제된다. 블록하고 있지 않은 시그널을 삭제하려 해도 괜찮다.
SIG_SETMASK
블록화할 시그널 집합을 set 으로 설정한다.

oldset 이 null이 아닐 때, 기존의 마스크 시그널 집합은 oldset 에 저장된다.

sigpending 호출은 블록화에 막혀 기다리고 있는 시그널을 살펴볼 수 있도록 해준다. 기다리는 시그널들의 시그널 마스크는 set 내에 저장된다.

sigsuspend 호출은 프로세스가 막고 있는 시그널 마스크를 지정한 mask 로 잠시 대체하고, 다음 시그널이 수신될 때까지 프로세스를 중지시킨다.  

반환값

sigaction , sigprocmask , sigpending 는 성공하면 0을 실패하면 -1을 리턴한다. sigsuspend 항상 -1을 리턴한다. 보통 에러 EINTR 과 함께.

에러

EINVAL
지정한 시그널이 부적절하다. 혹은 받을 수 없는 SIGKILL 또는 SIGSTOP 에 대한 액션을 변경하려고 했다.
EFAULT
act, oldact, set 또는 oldset 이 프로세스의 메모리 영역이 아닌 곳을 가리키고 있다.
EINTR
시스템 호출이 인터럽트되었다.
 

주의

sigprocmask 호출로 SIGKILL 또는 SIGSTOP 을 블록화할 수 없다. 이런 명령은 무시된다.

POSIX에 따르면, 프로세스가 kill() 또는 raise() 함수가 만들어 낸 것이 아닌 GFPE, SIGILL, 혹은 SIGSEGV를 무시한 이후의 프로세스의 동작은 정의되지 않는다. 정수를 0으로 나눈 결과 또한 정의되지 않는다. 일부 아키텍쳐에선 0으로 나누기가 SIGFPE 시그널을 만들어 낼 것이다. (또한 가장 큰 음의 정수를 -1로 나누어도 SIGFPE를 생성할 수 있다.) 이 시그널을 무시하면 무한 루프를 초래할 수 있다.

POSIX 스펙은 오직 SA_NOCLDSTOP 만을 정의한다 . 다른 sa_flags 의 사용은 이식이 불가능하다.

SA_RESETHAND 플래그는 동일한 이름의 SVr4 플래그와 호환가능하다.

SA_NODEFER 플래그는 커널 1.3.9과 새로운 버전하에서 동일한 이름의 SVr4 플래그와 호환가능하다.

SVr4 호환성을 위한 SA_RESETHANDSA_NODEFER 이름들은 오직 라이브러리 버전 3.0.9 그리고 그 이후의 버전에서만 존재한다.

SA_SIGINFO 플래그는 POSIX.1b에 의해서만 명시된다. 이에 대한 지원은 리눅스 2.2에 추가되었다.

sigaction 현재 시그널 처리기에 쿼리를 하기 위해 널 두번째 인수로 호출될 수 있다. 이를 널 두번째 그리고 세번째 인수들로 이를 호출함으로서 현재 머신에 대한 주어진 시그널이 타당한가를 체크하는데 사용될 수 있다.

시그널 체계 조작에 대한 자세한 정보를 얻으려면, sigsetops(3) 을 참조하라.  

호환

POSIX, SVr4. SVr4 는 EINTR 조건에 대한 문서를 제공하지 않는다.  

관련 항목

kill(1), kill(2), killpg(2), pause(2), raise(3), siginterrupt(3), signal(2), signal(7), sigsetops(3), sigvec(2)  

번역

ASPLINUX <man@asp-linux.co.kr> 2000년 7월 29일
한글 Manpage 프로젝트 (http://man.kldp.org) 2005년 2월 13일

+ Recent posts