C언어 기초
LocalVariable.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include <stdio.h> int SimpleFuncOne(void) { int num = 10; num++; printf("SimpleFuncOne num: %d \n", num); return 0; } int SimpleFuncTwo(void) { int num1=20; int num2=30; num1++; num2--; printf("num1 & num2: %d %d \n", num1, num2); return 0; } int main(void) { int num = 17; SimpleFuncOne(); SimpleFuncTwo(); printf("main num : %d \n", num); return 0; } | cs |
지역변수 num 이 현재 2개가 있으나
각각 함수내에서만 존재하는 지역변수 이므로...
함수를 벗어나면 영향을 끼치지 않음
그래서 26번째줄의 num은 17의 값을 가지고
SimpleFunOne은 내부의 num값 10으로 값을 증가해서 11의 값을 출력시킴
LocalValHideval.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <stdio.h> int main() { int num = 1; if(num == 1) { int num = 7; num+=10; printf("if문 내 지역변수 num: %d \n", num); printf("if문 내 지역변수 num주소: %p \n", &num); } printf("main 함수 내 지역변수 num: %d \n",num); printf("main 함수 내 지역변수 num주소: %p \n", &num); return 0; } | cs |
if문 내의 지역변수와 외부의 지역변수는 각각 다른 메모리 주소를 가지고 있는것을 볼수있음
리눅스
장치 폴더 구조
유닉스및 리눅스는 장치를 각각의 파일로 취급
파일개념으로 접근하여 제어함
/dev 에 각각 장치 설정 파일들이 들어있음
/dev/ram 메모리
/dev/std 모니터 접근 화면출력
/dev/tty 터미널 접속 파일
man 페이지 : 명령어 메뉴얼을 확인할수있는 메뉴얼
사용방법 : man 해당명령어
ex) man vi
POSIX(Portable Operating System Interface)
POSIX[포직스]는 유닉스 운영체계에 기반을 두고 있는 일련의 표준 운영체계 인터페이스이다. 표준화에 관한 필요성은, 컴퓨터를 사용하고 있는 기업들이 다시 코딩하지 않고서도 다른 컴퓨터 회사가 만든 컴퓨터 시스템에도 운영할 수 있도록, 호환성이 있는 프로그램을 개발하기 원하는 데에서 기인함
Canonical Mode Input Processing ( 특정행위시에만 값을 반환 )
흔히 정규모드라고 하며 기본적으로 라인단위로 입출력을 처리. 여기에서 말하는 라인의 개념은 우리들이 에디터에서 작업할때의 라인과 같은 개념으로 '\n' 혹은 EOF(End-Of-File) 를 만날때까지의 문자열을 말한다. 보통 사용자와 컴퓨터와 대화하기 위한 입출력은 정규모드 상태에서 행해진다. 이상태에서는 문자열 입력후 Enter 키를 눌러야 리턴이 됨. (혹은 Ctrl+d 를 눌러서 EOF 를 발생시킬경우)
또한 정규 방식에서는 ERASE와 KILL 문자등이 허용된다. 정규방식 자체가 라인단위 입출력작동임으로 당연히 Erase, kill 문자를 사용할수 있을것이다.
기본적으로 터미널은 정규모드로 시작됨
NonCanonical Mode Input Processing( 실시간 값을 반환 )
비정규모드. 정규모드가 라인단위로 입출력을 처리하는 것과 달리 비정규모드는 한바이트씩 처리.
한바이트씩 처리하게 됨으로 정규모드에서 가능했던 여러가지 특수문자들(ERASE, KILL, EOF, NL, CR)을 사용할수 없게 됨
예제 echo_off.c 가 비정규모드로 작동하는 프로그램인데, delete 키등이 먹지 않음을 알수 있다.
비정규모드에서는 ERASE 문자가 사용되지 않기 때문이다. echo_off.c 를 비정규 모드로 작성한 이유는 정규모드로 할경우 개행문자 '\n' 이 입력되기 전까지는 리턴되지 않음으로 바이트단위로 리턴하도록 하기 위해서이다. 위 예제코드에서 new_settings.c_lflag &= (~ICANON); 을 주석처리 한다음에 실행시키면 엔터키를 입력하기 전까지는 화면에 "*" 이 출력되지 않음을 알수 있을것이다. 대신 Delete 와 같은 몇몇 특수문자의 전달이 가능함을 알수 있다.
라즈베리파이
시리얼 통신 RX / TX
라즈베리파이 GPIO 핀 배열
UART RX/TX통신을 위해 8번(TX)과 10번(RX)핀을 사용
termios 각각 터미널 속성값
표 1. 터미널 속성값 - c_iflag
설명 | 터미널 입력과 관련된 제어를 한다. 입력제어 값들은 모드 on 되어있는 상태이다. |
IGNBRK | break 컨디션을 무시한다. break 컨디션은 연속된 0의 값을 가지는 비트로 정의된다. 만약 IGNBRK 가 on 되어 있고 입력데이타에 break 컨디션이 전달된다면 무시하게 된다. |
BRKINT | 이것은 break 컨디션 상에서 SIGINT 를 가로채기 위해서 사용된다. 만약 IGNBRK 가 off 되어있고, BRKINT가 세팅되어 있는 상태에서 break 컨디션이 입력된다면 이것은 출력쿠에 쌓이게 된다. 만약 터미널이 foreground process 상태로 돌고 있는 도중이라면, SIGINT 신호를 발생시키게 된다. |
IGNPAR | parity 에러무시한다. |
INPCK | parity 체크를 실시한다. |
ISTRIP | 만약 이 플레그를 on 시키면, 유효한 입력 문자를 처음 7bit 로 세팅하게 된다. 그렇지 않을경우 8bit 입력으로 처리한다. |
INLCR | NL 문자(new-line)를 CR(carriage return) 문자로 대체시킨다. 만약 이 플레그가 on 된다면, NL 문자는 CR 문자로 변경된다. |
IGNCR | CR 문자를 무시한다. on 될경우 입력되는 CR 문자를 무시한다. (읽지 않는다) |
ICRNL | CR 문자를 NL 문자로 대체시킨다. IGNCR 이 on 되어 있지 않은 상태에서 ICRNL이 on 되어 있을경우 받은 CR 을 NL 로 변경한다. |
IXON | start 와 stop 출력제어를 활성화 한다. 만약 플레그가 on 인 상태에서 STOP 캐릭터를 받았다면 출력을 멈추게 된다. 그러다가 START 캐릭터를 받게 되면 다시 출력을 시작하게 된다. 이것은 flow-control(흐름제어)를 위한 용도로 사용되며, 실제 STOP, START 캐릭터를 읽어들이지는 않는다. 만약 플레그가 off 상태라면 STOP, START 캐릭터를 읽어들인다. |
IXOFF | 입력제어를 위해서 start 와 stop 를 활성화 한다. 만약에 플레그가 on 으로 되어있다면 시스템은 입력큐가 가득 찼을때 STOP 캐릭터를 전송한다. 그리고나서 입력큐에 있는 데이타를 모두 읽었다면 START 캐릭터를 전송한다. IXON과 함께 흐름제어를 위해서 사용된다. |
IXANY | 어떤 문자에 대해서라도 출력을 한다. 이 플레그가 on 이라면 입력된 어떤 문자라도 출력을 시작 하게 된다. |
IMAXBEL | 만약 입력스트림이 overflows 될경우 ASCII BEL 을 반향한다. |
표 2. 터미널 속성값 - c_iflag
설명 | 출력을 어떻게 다룰지에 관한 설정을한다. 기본설정은 모든 비트에 대해서 on(1) 의 상태이다. |
OPOST | Post-process output 모드. 만약 이 플레그가 off 상태라면 문자는 변화없이 전달된다. 그렇지 않고 on 이라면, 뒤에 오는 flag 에 의해서 변경될수 있다. |
OLCUC | 이 플레그가 on 되어 있을경우 영문소문자 는 영문대문자로 치환되어서 전달된다. |
ONLCR | 이 플레그가 on 되어 있을경우 NL 문자는 CR-NL 문자로 치환되어서 전달된다. |
OCRNL | 이 플레그가 on 되어 있다면 CR 문자는 NL 문자로 치환된다. |
ONOCR | 이 플레그가 on 되어 있다면 CR이 아닌 첫번째 문자부터 전달되게 된다. |
OFILL | 시간지연을 위해서 fill 문자를 이용한다. 이 플레그가 on 되어 있다면, 문자 전달시간지연을 위해서 time 지연을 사용하지 않고 fill 문자를 전달하는 것으로 대신한다. |
OFDEL | 이 플레그가 on 되어 있다면 fill 문자로 DEL이 전달된다. |
NLDLY | new-line 문자지연이다. NL0 과 NL1 두개의 값이 준비되어 있다. NL0 은 지연없음이며, NL1 의 경우 약 0.1 초 정도의 지연시간이 생긴다. 만약 OFILL 플레그가 on 되어 있다면, 지연을 만들기 위해서 두개의 fill 문자를 전달한다. |
CRDLY | CR 문자지연이다. 여기에는 CR0, CR1, CR2, CR3 의 값이 준비되어 있다. CR0 은 지연없음, CR1 은 컬럼위치에 따라 지연시간 결정, CR2 는 약 0.10 초, CR3 는 약 0.15초의 지연이 생긴다. |
TABDLY | 수평탭 시간지연이다. TAB0, TAB1, TAB2, TAB3 의 값이 준비되어 있다. TAB0은 지연없음, TAB1 은 컬럼위치에 따라 지연시간 결정, TAB2 는 0.1초가량의 지연된다. TAB3 로했을경우 탭은 스페이스로 확장된다. |
BSDLY | 백스페이스키 시간지연이다. BS0과 BS1 이 준비되어 있으며, BS0은 지연없음, BS1 은 약 0.05 의 시간지연을 나타낸다. OFILL 플레그가 세팅되어 있으며 BS1 이라면 한개의 fill 문자를 보낸다. |
표 3. 터미널 속성값 - c_cflag
설명 | 하드웨어의 터미널제어에 관련된 속성들이다. 모뎀과 같은 하드웨어 제어에 많이 쓰인다. |
CBAUD | baud rate 에 대한 설정이다. 하드웨어에 따라서 속도의 변화가 불가능한경우도 있다. 모뎀을 사용해본적이 있다면 baud rate 에 대해서 자주 들어보았을것이다. 자주 사용되는 baud rate 는 B4800, B9600, B19200, B38400 으로 각숫자가 baud 속도를 나타낸다. 참고로 baud 는 하드웨어의 데이타 처리 속도를 나타낸다. 이외에 B50, B75, B110, B134, B150, B200, B300, B600, B1200, B1800, B2400 이 있다. 마찬가지로 B 다음의 숫자가 baud 속도이다. |
CSIZE | 문자의 크기를 지정하기 위해서 사용한다. CS5, CS6, CS7, CS8 이 준비되어 있으며, 각각 5, 6, 7, 8bit 를 나타낸다. |
CSTOPB | stop 비트의 수를 정한다. 이 플레그가 on 되어있다면 2개의 stop 비트를 그렇지 않다면 1개의 stop 비트를 보낸다. |
CREAD | receiver 을 활성화한다. |
HUPCL | 이 플레그가 세팅되어 있다면, 마지막 프로세스가 종료되거나, 마지막 프로세스의 line(회선)이 닫힐경우 disconnect 가 발생한다. |
PARENB | parity 를 추가한다. 이 플레그가 on 되어 있으면, parity 를 생성하고 검색하게 된다. 각문자에 parity bit 가 추가된다. |
표 4. 터미널 속성값 - c_lflag
설명 | 로컬(사용자) 터미널에 관한 속성과 관련되어 있다. 초기값은 모두 on 상태이다. |
ISIG | signal 을 받아들인다. 이 플레그가 on 되어 있다면, INTR, QUIT, SUSP, DSUSP 과 같은 특수 문자를 받아들인다. |
ICANON | 이 플레그가 on되면 정규모드로 입력이 이루어진다. |
NOFLSH | queue flush 를 비활성화 시킨다. |
ECHO | 반향을 설정한다. 만약 이 플레그가 off 되어있다면 입력은 반향되지 않는다. |
ECHOE | erase 문자를 반향한다. 만약 이 플레그와 함께 ECHO 플레그가 on 되어있다면 ERASE 가 발생할경우 스크린에서 마지막 문자를 지우게 된다. |
ECHOE | erase 문자를 반향한다. 만약 이 플레그와 함께 ECHO 플레그가 on 되어있다면 ERASE 가 발생할경우 스크린에서 마지막 문자를 지우게 된다. |
ECHOPRT | 만약 ECHO 플래그가 on 되어있고 ECHOPRT가 on 되었을경우 ERASE 가 발생한다면 (back 스페이스키를 입력한다면) 삭제되는 문자가 '\' 뒤에 표시되게 된다. 만약 모든 문자를 삭제했다면 '/' 가 출력되게 된다. |
ECHOKE | Backspace-Space-Backspace entire line on line kill |
ECHONL | NL문자가 반향된다. ECHONL 플레그가 on 되어있다면, ECHO 플래그가 on 되어있지 않더라도 NL 문자가 반향된다. |
ECHOCTL | 제어문자가 반향되도록 한다. 제어문자는 0에서 37 까지의 ASCII 코드이다. 이 플레그를 on 시킨상태에서 CTRL+X 같은 제어문자를 입력할경우 ^X 로 화면에 표시될것이다. |
표 5. 제어문자 속성값 - c_cc
설명 | c_cc 배열은 제어문자를 제어하기 위해서 사용한다. 즉 CTRL+X, CTRL+X, CTRL+C 등의 문자와 관련된 제어를 할수 있다. |
VINTR | 일시중지(Ctrl+C)와 관련된 제어이다. 만약 ISIG 플레그가 on 되어 있다면 일시중지 문자를 입력시키면 포그라운드 프로세스에 SIGINT 시그널이 발생된다. |
VQUIT | Quit 제어문자 Ctrl+\ 와 관련된다. ISIG 플래그가 on 되어 있고 Quit 제어문자가 입력되면 SIGQUIT 시그널이 발생한다. |
VERASE | ERASE 제어문자(백스페이스) 와 관련된다. 정규모드(ICANON) 플래그 가 on 되어 있고, ERASE 제어문자가 발생하면 가장 마지막 문자가 지워진다. |
VKILL | KILL 제어문자 (Ctrl+u)와 관련된다. |
VEOF | Ctrl-d 제어문자와 관련된다. ICANON 플래그가 on 되어 있고, EOF가 발생하면 읽기 대기중인 모든문자들은 개행문자를 만나지 않더라도 바로 프로세스에게 전달된다. |
VSTOP | STOP 제어문자(Ctrl+s)와 관련된다. |
VSUSP | SUSP 제어문자 (Ctrl+z)와 관련된다. ISIG 플래그가 on 되어있는 상태에서 Ctrl+z 가 입력되면 모든 포그라운드 프로세스에 SIGSTOP 신호가 전달된다. |
VWERSE | WERASE 제어문자 (Ctrl+w) 와 관련된다. |
sread.c - 수신RX
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> //Used for UART #include <termios.h> //Used for UART #include <sys/types.h> #include <sys/stat.h> #define SPEED B115200 //데이터 전송속도 #define SPORT "/dev/ttyAMA0" //라즈베리파이 터미널 접속 int main(void) { char cBuff[255]; //수신한 데이터를 저장할 버퍼 변수 int iDev = 0; //통신 포트를 파일 개념으로 사용하기 위한 디스크립터 int iRet = 0; // 데이터 수신용 struct termios stOldState; //처음 상태저장 struct termios stNewState; //새 상태저장 iDev = open(SPORT,O_RDWR | O_NOCTTY); // if(0 > iDev) { perror(SPORT); return -100;//exit(-100); } tcgetattr(iDev, &stOldState); bzero(&stNewState, sizeof(stNewState)); stNewState.c_cflag = SPEED | CRTSCTS | CS8 | CLOCAL | CREAD; stNewState.c_iflag = IGNPAR | ICRNL; stNewState.c_oflag = 0; stNewState.c_lflag = ICANON; //Cannonical 설정 bzero(stNewState.c_cc, NCCS); stNewState.c_cc[VMIN] = 1; tcflush(iDev, TCIFLUSH); tcsetattr(iDev, TCSANOW, &stNewState); iRet = read(iDev, cBuff, 255); cBuff[iRet] = 0; printf("[%s]:[%d]\n", cBuff, iRet); tcsetattr(iDev, TCSANOW, &stOldState); close(iDev); //return 0; } | cs |
코드 설명
swrite.c - 송신 RX
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <termios.h> #include <sys/types.h> #include <sys/stat.h> #define SPEED B115200 #define SPORT "/dev/ttyAMA0" int main(void) { char cBuff[255]; int iDev = 0; int iRet = 0; struct termios stOldState; struct termios stNewState; iDev = open(SPORT,O_RDWR | O_NOCTTY); if(0 > iDev) { perror(SPORT); exit(-100); } tcgetattr(iDev, &stOldState); bzero(&stNewState, sizeof(stNewState)); stNewState.c_cflag = SPEED | CRTSCTS | CS8 | CLOCAL | CREAD; stNewState.c_iflag = IGNPAR | ICRNL; stNewState.c_oflag = 0; stNewState.c_lflag = ICANON; bzero(stNewState.c_cc, NCCS); stNewState.c_cc[VMIN] = 1; tcflush(iDev, TCIFLUSH); tcsetattr(iDev, TCSANOW, &stNewState); iRet = write(iDev, "test\n", 5); printf("write complete: %d \n",iRet); tcsetattr(iDev, TCSANOW, &stOldState); close(iDev); return 0; } | cs |
43번 : iRet에 입력 "test\n"
'코스웨어 > 16년 스마트컨트롤러' 카테고리의 다른 글
20160404_장진웅_업무일지_로봇제어_시리얼제어 (0) | 2016.04.05 |
---|---|
20160330-업무일지-허도경-로봇제어-터미널 (0) | 2016.04.05 |
20160404_김도관_업무일지_C언어 기초및 비주얼스튜디오 디버깅모드 (2) | 2016.04.05 |
20160401_김도관_업무일지_C언어 기초및 라즈베리파이_Non-Canonical (0) | 2016.04.05 |
20160330-업무일지-이보원 라즈베리파이 명령어 실습 (0) | 2016.04.05 |
20160329 업무보고 이보원 라즈베리파이 벡업 하기 및 visual studio 실습 (0) | 2016.04.05 |
20160328 업무보고 이보원 라즈베리파이 원격제어 (0) | 2016.04.05 |
20160404_박진한_업무일지_시리얼제어 (0) | 2016.04.05 |