728x90


라즈베리 파이, WiringPi를 이용한 GPIO 제어



WiringPi 설치하기전 Git 설치


sudo apt-get install git-core



라즈베리 파이 업데이트

sudo apt-get update

sudo apt-get upgrade



Git을 통해 WiringPi 내려받기

git clone git://git.drogon.net/wiringPi



다운로드 완료 후, 빌드 수행

cd wiringPi

./build




gpio 유틸리티 실행



GPIO 확장보드의 28과 29핀을 쓸 것. (BCM 20, 21)



라즈베리파이 GPIO (General purpose input/output)







74HC08N, Quad 2-input AND gate







LED켜기 

#include <wiringPi.h>
#include <stdio.h>

#define         A       28
#define         B       29

int main(void)
{
        wiringPiSetup();

        pinMode(A,OUTPUT);
        pinMode(B,OUTPUT);

        while(1)
        {
                printf("A = Lo, B = Lo: Out = ?\n");
                digitalWrite(A,LOW);
                digitalWrite(B,LOW);
                delay(1000);

                printf("A = Lo, B = Hi: Out = ?\n");
                digitalWrite(A,LOW);
                digitalWrite(B,HIGH);
                delay(1000);

                printf("A = Hi, B = Lo: Out = ?\n");
                digitalWrite(A,HIGH);
                digitalWrite(B,LOW);
                delay(1000);

                printf("A = Hi, B = Hi: Out = ?\n");
                digitalWrite(A,HIGH);
                digitalWrite(B,HIGH);
                delay(1000);
        }
        return 0;
}



컴파일시 -lwiringPiDev 붙여줘야 함


 pi@raspberrypi:~/wiringPi $ gcc -o Gpio GPIO_RPi.c -l wiringPi 


실행

pi@raspberrypi:~/wiringPi $ sudo ./Gpio



실행결과



 AND GATE이므로 28,29핀에 HIGH 신호가 들어올 때(4번째 PRINTF문) 불이 켜지는 것을 볼 수 있다.

digitalWrite(A,HIGH); digitalWrite(B,HIGH);




LED없이 출력값 보기

#include <wiringPi.h>
#include <stdio.h>

#define    IN  27
#define         A       28
#define         B       29

int main(void)
{
        wiringPiSetup();

  pinMode(IN,INPUT);
        pinMode(A,OUTPUT);
        pinMode(B,OUTPUT);

        while(1)
        {
                printf("A = Lo, B = Lo: Out = ");
                digitalWrite(A,LOW);
                digitalWrite(B,LOW);
    if(digitalRead(IN))
    {
      printf("Hi\n");
    }
    else
    {
      printf("Lo\n");
    }
                delay(1000);

                printf("A = Lo, B = Hi: Out = ");
                digitalWrite(A,LOW);
                digitalWrite(B,HIGH);
    if(digitalRead(IN))
    {
      printf("Hi\n");
    }
    else
    {
      printf("Lo\n");
    }
                delay(1000);

                printf("A = Hi, B = Lo: Out = ");
                digitalWrite(A,HIGH);
                digitalWrite(B,LOW);
    if(digitalRead(IN))
    {
      printf("Hi\n");
    }
    else
    {
      printf("Lo\n");
    }
                delay(1000);

                printf("A = Hi, B = Hi: Out = ");
                digitalWrite(A,HIGH);
                digitalWrite(B,HIGH);
    if(digitalRead(IN))
    {
      printf("Hi\n");
    }
    else
    {
      printf("Lo\n");
    }
                delay(1000);
        }
        return 0;
}



위 소스 if 문에 대한 설명


1 == digitalRead(IN))             // 1은 참을 의미, 디지털 신호가 들어올 때.

1 =! digitalRead(IN))               // 1이 아닐때는 왼쪽과 같이 소스를 짤 수 있음.



결과 : 두 핀 모두 HIGH일 때, Hi라는 문장이 출력된다.

 printf("A = Hi, B = Hi: Out = ");

digitalWrite(A,HIGH); digitalWrite(B,HIGH); if(digitalRead(IN)) { printf("Hi\n"); }




728x90

analog 연속 -> noise에 약함, 데이터량에 많음, 원래 신호에 가까움, 보안성 약함



digital 불연속 -> noise에 강함



ADC 

:표본화, 양자화, 부호화를 거쳐 digital화 함



충전을 위해선 20%이상의 전압을 걸어줘야 함




전류 Current    A

전압 Voltage    V

저항 Resistor    R   



DC 직류 - 주파수 0 Hz



AC 교류 - 주파수 60 Hz




SMPS(Switched-Mode Power Supply) 

AC Line 주파수(50㎐~60㎐)를 DC로 변환하여 높은 주파수로 변경 (수십 ㎑~수백 ㎑)하여 사용





AC 단상 3선식 (일명 돼지코)

Live(Hot), Neutral(Cold) // N, L이라고 쓰여있음

  아래위엔 접지(Earth)가 있음



회로 설계시

1. 전자부품의 스펙 확인

구동전압 확인


2. 회로 설계

3. Artwork

4. Debugging

5. Artwork


싱크/ 소스타입 조사하기





풀업&풀다운 저항


어정쩡한 요인을 제거하기 위해 풀업이나 풀다운 저항을 사용함. 확실한 high와 low로 만들어줌

풀업 풀다운을 위해하기전에 플로팅에 대해 알 필요가 있다.



 플로팅 (floating)


 칩에 입력을 5V 또는 0V를 가한다. 하지만 입력을 가하지 않는 경우는 칩 자체에서는 5V를 입력하였는지 1V를 입력하였는지 모른다. 이런 문제에 의하여 오작동이 발생할 수 있다. 이런 상태를 플로팅되었다라고 한다. 플로팅 상태는 잡음에 매우 취약해지므로 시스템이 불안정해진다. 이를 해결 하기 위해서 풀업 / 풀다운 저항을 사용하게 된다



풀업 저항 (Pullup resistor)


풀업 저항을 사용한다면 스위치가 열려 있을 때 칩에는 항상 5V의 전압이 가해진다. 
따라서 회로에 입력을 몰라도 항상 5V의 전압을가진 상태가 된다. 스위치를 닫는다면 그라운드 쪽으로 전류가 흐르게 되며 회로의 전압은 0V가 되며, 1을 입력한 것으로 인식하게 된다. 핀을 높은 저항에 매달아 둔다는 뜻에서 '풀 업 저항'이라 한다.


풀다운 저항 (Pulldown resistor)


회로는 5V의 전압을 받으면 1로 인식하고, 0V의 전압을 받으면 0으로 인식한다. 
스위치가 열려있는 상태에서 그라운드와 연결되어 있으므로 전류가 항상 그라운드로 흐르게 되어 0V가 된다. 스위치를 닫게되면 소량의 전류가 저항을 통해 그라운드로 흘러 나가지만 많은 양의 전류가 회로(핀)로 흘러 5V가 된다. 따라서 1이 입력된 것으로 인식한다. 항상 그라운드에 묶어둔다는 의미에서 '풀 다운 저항' 이라 한다.




http://air802.tistory.com/2


슈미트 트리거 회로

Schmitt Trigger는 미국의 과학자 Otto H. Schmitt에 의해 발명된 일종의 비교기로써, 하나의 입력 전압과 출력 전압, 두 개의 threshold를 가진다. positive feedback을 사용하는 비교기로, OP Amp의 구조를 가지며 대부분 inverter로 사용된다.


 

 

 즉, input 신호로 low threshold 보다 낮은 전압이 인가되면 출력은 high로, high threshold 보다 높은 전압이 인가되면 출력은 low가 되며, 두 개의 threshold 사이의 전압이 인가되면 그 값을 유지한다.


 threshold가 하나인 유사한 시스템의 경우, 입력 신호에 noise가 섞여 threshold에 비슷한 전압이 인가되면 스위치를 순식간에 on/off 시킬 수 있기 때문에 두 개의 threshold를 사용하는 Schmitt Trigger가 더 안정적이다. 그러므로 사람의 손 떨림으로 인해 값이 여러번 입력되는 등의 switch noise를 제거할 수 있다.




http://blog.naver.com/PostView.nhn?blogId=davidsbkim&logNo=150031720819




임베디드 레시피

http://recipes.egloos.com/


도쳬 : 금속, 흑연 ...

부도체: 전류가 흐르지 않음


반도체 - 다이오드 : 한쪽 방향으로만 전류 흐름.


순방향


순방향 전압


역방향


역방향 전압



트랜지스터

http://www.mully.net/lee/2015/transistor/



대부분의 트랜지스터는 3개의 다리를 가지고 있습니다. 각각 베이스(Base), 컬렉터(Collector), 이미터(Emitter)라고 부릅니다.

  • 베이스(B): 트랜지스터를 작동시키기 위해 약한 전기신호를 가하는 단자입니다.
  • 컬렉터(C): 베이스에(B) 약한 전기신호가 들어오면 막혀 있던 컬렉터(C)에 큰 전류가 흐르게 됩니다.
  • 이미터(E): 베이스(B)와 컬렉터(C)에서 흐르는 전류가 합쳐지는 단자입니다.



Trans-Resistor :  Resistor값을 변화 시킬 수 있다는 의미로 전류의 양을 조절하는 것.







 B에 넣어주는 전압(전류)량의 미묘한 변화에도 저항값이 휙휙 많이 바뀐며, 결국 EC간의 전류 값도 휙휙 변하게 된다.





주파수






디지털 샘플링  Digital Sampling

http://www.mully.net/lee/2015/digital_sampling/


자연의 모든 소리는 아날로그 신호입니다.

아날로그 정보는 연속적인 모든 시간에서의 정보를 가지고 있습니다. 모든 시간의 값을 전부 기록할 수는 없으므로 보통은 일정한 시간 간격마다 값만 기록을 할 수 밖에 없습니다. 즉, 값을 추출하는 적당한 시간 간격을 정해야 합니다.

아날로그 정보를 디지털 정보로 정확하게 기록하기 위해서는 기록을 하는 시간 간격도 충분히 작게 해야 합니다. 즉, 아날로그 정보가 변하는 특정 시간 보다 더 촘촘한 시간 간격으로 기록을 해야 합니다.




접지(Earthing, Grounding) : 각종 전기, 전자, 통신 설비들을 전기적으로 대지와 연결하여 전위를 대지와 같은 기준전위(0 v)로 만드는 것






74 HC 시리즈 각 칩의 기능과 구성


http://donghwada.tistory.com/entry/74HC-%EC%8B%9C%EB%A6%AC%EC%A6%88-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%8B%9C%ED%8A%B8-%EB%B3%B4%EB%8A%94-%EB%B2%95-%EB%B0%8F-%EC%A0%95%EB%A6%AC74HC00-74HC02-74HC04-74HC08-74HC32-74HC86




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

2016 04 28 디코더  (0) 2016.04.28
2016 04 27 논리회로  (0) 2016.04.27
20160324_펌웨어(써미스터,PWM)  (0) 2016.03.24
20160323_펌웨어(ADC)  (0) 2016.03.23
20160322_펌웨어(USART)  (0) 2016.03.22
728x90

TCP의 특징: 신뢰

모든 패킷 전송에 대한 응답확인

패킷마다 일련 번호가 붙음




최대 전송 단위(maximum transmission unit, MTU)란 해당 레이어가 전송할 수 있는 최대 프로토콜 데이터 단위의 크기(바이트)이다.


Eternet환경에서 MTU는 1500 (실제 사용제 data는 최대 1460까지 하나의 패킷으로 전송가능)





TCP/IP 4 계층





• bind : socket을 소프트웨어 Port와 IP로 묶음


커뮤니케이션 - accept가 반환하는 값은 커뮤니케이션의 값



유닉스 고급 프로그래밍 p.385

시그널 - 소프트웨어 인터럽트


자바에서는 이벤트


SIGINT : 터미널 인터럽트 문자, 기본동작은 종료 (p. 393)



foreground process <-> background process


폭주한 프로그램을 종료할 때, 특히 원치않은 대량의 출력을 화면에 표시하는 프로그램 종료시 흔히 쓰임 (예: 무한 while문에서 Ctrl + C)




리눅스 멀티채팅 프로그램


multi chat.7z








728x90

공장내 네트워크



블록킹함수  scanf

논블록킹     printf


연결 지향 : 전용 선로 개설

• Three-way handshake

• 3번의 패킷 교환으로 세션 개설


#include <stdio.h> 
int main()

{
	fprintf(stdout, "TEST \n");
	write(1,"TEST \n", 5);
	char caBuff[250];
	
//	fclose(stdout);

	fprintf(stdout, "TEST \n");
	write(1,"TEST \n", 5);


//	write(1, "\033[1;1H/033[2]", 10);
	read(0, caBuff, 250);
	printf("%s", caBuff);

	return 0;
}


Output :  //주석을 가지고 출력값을 테스트


TEST

TEST TEST

TEST (안녕하세요 입력)

안녕하세요



클라이언트 테스트





main.c  // 네트워크 소켓생성 활용 소스

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>


int main()
{
	int iSock; // socket 함수의 반환값 받아냄
	struct sockaddr_in stServer; //network에 사용될 ip, port번호 저장

 	int iLen;	// 구조체 길이 저장
	char caBuff[250];	// 최대로 읽어들일 버퍼 크기
	int iRet; // 키보드 입력을 읽어들여 저장, iRet=read	 


	//char *inet_ntoa 숫자 입력하면 문자열 반환

	iSock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	
	if(iSock<0)
	{	
		printf("소켓 생성불가 \n");
		return;
	}
	memset(&stServer,0, sizeof(stServer)); //구조체 초기화(bzero와 같은 효과)
    
	stServer.sin_family=AF_INET;	
	stServer.sin_addr.s_addr = inet_addr("192.168.1.55"); //ip 설정
	stServer.sin_port = htons(9999); // 포트번호 설정, 구조체 설정 끝, le->big endian
	
	iLen=sizeof(stServer); // iRen에 구조체 길이 넣어줌
	printf("메시지를 입력하세요 \n");	// app사용자에게 입력상태임을 알려줌
	fflush(stdout);		    
 	iRet=read(0, caBuff, 250);  
	// 첫번째 인자0이면 키보드 입력을 받음, 입력받는 주소 caBuff, 최대 크기 250)
	
	sendto(iSock, caBuff, iRet, 0, (struct sockaddr*)&stServer, iLen);
    // 소켓번호, 데이터가 든곳, 보낼 바이트수, 0, 보내는곳의 정보(구조체 주소), 길이
	// udp로 통신
	close(iSock); // 네트워크 끊김
	return 0;
}


728x90

구조체와 배열


연관되었지만 타입이 다른 자료형의 경우는 구조체, 

같은 경우는 배열 사용



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <string.h>

struct person
{
    char name[20];
    char phoneNum[20];
    int age;
};

int main()
{
    struct person man1, man2;
    strcpy(man1.name, "안성준");
    strcpy(man1.phoneNum, "010'1122-3344");

    return 0;
}


위의 소스를 아래와 같이 비유할 수 있다.



 붕어빵 기계 틀

 struct person

 타입

 붕어빵

 man

 변수 (메모리를 차지)


  


atoi 함수 예제 소스 // a to i            ascii->int 문자열을 정수형으로 변환

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

#include <stdio.h> #include <stdlib.h> //atoi함수를 사용하기 위한 헤더 int main() { char str[20]; printf("정수 입력: "); scanf("%s", str); printf("%d \n", atoi(str)); printf("실수 입력: "); scanf("%s", str); printf("%g \n", atof(str)); return 0; }


실수 15.0을 입력하면 정수 15로 출력된다.




typedef을 쓰는 두가지 이유 


typedef unsigned int     size_t;   // 범용의 효과 : int나 short만 바꿔도 모든 size_t의 type이 바뀐다.

typedef unsigned short  size_t;



축약의 효과 

typedef unsigned in uInt;    // ulnt





#include <stdio.h>

int main()
{
    int iNum1=1;
    char str[5];
    int iNum2=2;

    printf("iNum1 : %d \n", iNum1); 
    printf("iNum2 : %d \n", iNum2);

    printf("iNum1 address : %x \n", &iNum1); 
    printf("str address : %x \n", &str);
    printf("iNum2 address : %x \n", &iNum2);

    scanf("%s", str);

    printf("[%s]\n", str); // 문자열 값 그대로 출력 문자열 %s에는 []를 씌우는 것이 좋다. 
    printf("iNum1 : %d \n", iNum1);  // 
    printf("iNum2 : %d \n", iNum2);

    return 0;
}



Output:

1
2
3
4
5
6
7
8
iNum1 : 1 
iNum2 : 2 
iNum1 address : ff9066b0 
str address : ff9066b7 
iNum2 address : ff9066ac 
[]
iNum1 : 1 
iNum2 : 2 


지역변수와 메모리 Stack


가장 최근의 지역변수가 재사용할 확률이 높다.

메모리의 stack에는 일반적으로 값이 밑에서부터 위로 만들어진다.



넣어진 종이컵을 꺼내려면 나중에 넣은 종이컵부터 꺼내게 되는 것과 같다.


  1. iNum2    //  address : ff9066ac 
  2. str          // ff9066b7
  3. iNum1    // ff9066b0





fgets 함수

scanf와 gets는 입력할 수 있는 문자에 제한이 없기에 오버플로우에 취약하다.



가급적이면 fgets를 쓰는 것이 좋다. (int size : 입력받는 값을 제한)


 char *fgets(char *s, int size, FILE *stream);



fgets 예제소스


#include <stdio.h>

void ClearLineFromReadBuffer(void)
{
    while(getchar()!='\n');
}

int main(void)
{
    char perID[7];
    char name[10];

    fputs("주민번호 앞 6자리 입력: ", stdout);
    fgets(perID, sizeof(perID), stdin);
    ClearLineFromReadBuffer();      // 입력버퍼 비우기

    fputs("이름 입력: ", stdout);
    fgets(name, sizeof(name), stdin);

    printf("주민번호: %s\n", perID);
    printf("이름: %s\n", name);
    return 0;
}
       



Output :





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

c 복습-문제풀이2  (0) 2016.08.22
섭씨->화씨 변환, 최대 공약수 구하기  (0) 2016.05.03
2016-04-06-업무일지_포인터 및 함수  (0) 2016.04.06
20160405_포인터와 배열  (0) 2016.04.05
20160401_전역변수와 포인터  (0) 2016.04.04
728x90

배열


2차원에서 가로의 크기는 정해줘야 함






이중 포인터와 다중포인터



 PPP 

 PP

 P

  num A=100

 int***

  int**

 int*

  int


 



 대상의 type 

 자기자신의 type 

 int  

 (포인터)

     


 가리키는 대상

 포인터

 PP 

 *PPP

 

  **PPP

 B    

  ***PPP




 int * whoA[4]={&num1, &num2, &num3, &num4};  // 포인터 배열이고 16byte

 int (*whoB)[4]=arr2d;                                        // 배열 포인터이고 4byte


이중 포인터 예제


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>

int main(void)
{
    double num = 3.14;
    double *ptr = &num;
    double **dptr = &ptr;
    double *ptr2;

    printf("%9p %9p \n", ptr, *dptr);
    printf("%9p %9p \n", num, **dptr);
    ptr2 = *dptr;
    *ptr2 = 10.99;
    printf("%9g %9g \n", num, **dptr);
 
    return 0;
}



Output:

1
2
3
0xffb30790 0xffb30790 
0x51eb851f 0x40091eb8 
    10.99     10.99 






포인터 변수에 const 선언 // const를 붙이면 해당 변수를 상수로 취급하게 된다.

#include <stdio.h>

int main()
{
    char *P1="TEST";
    const char *P2="TEST";
    char const *P3="TEST";
    char * const P4="TEST";
    const char * const P5="TEST";
    char const * const P6="TEST";

    printf("P1=[%s], [%p]\n", P1, P1);
    printf("P2=[%s], [%p]\n", P2, P2);
    printf("P3=[%s], [%p]\n", P3, P3);
    printf("P4=[%s], [%p]\n", P4, P4);
    printf("P5=[%s], [%p]\n", P5, P5);
    printf("P6=[%s], [%p]\n", P6, P6);

    printf(P1="zest\n");
    printf(P1="zest\n");
    printf(P1="zest\n");
   
    //printf(P4=zest);
    //printf(P5=zest);
    //printf(P6=zest);
    return 0;
}



리눅스에서는 주소가 모두 같게 나온다.

Output:

1
2
3
4
5
6
7
8
9
P1=[TEST], [0x8048698]
P2=[TEST], [0x8048698]
P3=[TEST], [0x8048698]
P4=[TEST], [0x8048698]
P5=[TEST], [0x8048698]
P6=[TEST], [0x8048698]
zest
zest
zest





메인 함수를 통한 인자 전달 // gcc 흉내내기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

#include <stdio.h> int main(int argc, char *argv[]) // argc = 지정해준 명령행 인자의 개수 저장, argv = 문자열 배열 포인터 { int i=0; if(1==argc) { printf("gcc: fatal error: no input files \n"); return 0; } printf("전달 문자열 수: %d \n", argc); for(i=0; i<argc; i++) printf("%d번째 문자열: %s \n", i+1, argv[i]); return 0; }


전달된 문자열이 하나이므로 조건에 맞는 아래 문장이 출력된다.


Output:

1
gcc: fatal error: no input files 






EOF (End Of File) // 파일의 끝


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>

int main()
{
    int ch;

    while(1)
    {
        ch=getchar(); 
        if(ch==EOF)  
            break;
        putchar(ch); 
    }
        return 0;
}


getchar를 통해 입력버퍼의 문자를 읽어들임

enter가 입력될때까지 키보드 입력값들을 계속해서 버퍼에 저장. enter가 파일의 끝이 된다.






fprintf 함수 //  특정한 스트림에 일련의 데이터를 특정한 형식에 맞추어 쓰게 된다.   리눅스 man 3 fprintf 참조

1
2
3
4
5
6
7
#include <stdio.h>

int main()
{
    fprintf(stdout, "test \n");
    return 0;
}


stdout(표준출력)을 통해 test라는 글자가 출력.

printf 함수가 실제로 출력하는 것이 없고 fprintf에 지시해서 출력하는 것이라고 할 수 있다.


Output:

1
test 


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

섭씨->화씨 변환, 최대 공약수 구하기  (0) 2016.05.03
2016-04-07-업무일지_구조체 및 함수  (0) 2016.04.07
20160405_포인터와 배열  (0) 2016.04.05
20160401_전역변수와 포인터  (0) 2016.04.04
20160329_C기초, 디버깅  (0) 2016.03.29
728x90

배열의 이름은 포인터이다.

int형 배열의 주소값 차는 4바이트이며, 주소값의 변경은 불가능하다. (값을 바꿀 수 없는 상수형)


포인터 변수와 배열의 이름 모두, 메모리의 주소값을 나타내고 저장한다.


1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

int main()
{
	int arr[3] = { 0, 1, 2 };
	printf("배열의 이름: %p \n", arr);
	printf("첫번째 요소: %p \n", &arr[0]);
	printf("두번째 요소: %p \n", &arr[1]);
	printf("세번째 요소: %p \n", &arr[2]);
	// arr = &arr[i];  // 이 문장은 컴파일 에러를 일으킨다.
	return 0;
}



Output:

1
2
3
4
배열의 이름: 0xff920370 
첫번째 요소: 0xff920370 
두번째 요소: 0xff920374 
세번째 요소: 0xff920378 


 


#include <stdio.h>

int main()
{
    char *cpStr="hello world \n";
    
  char caStr[20];
    printf("Hello world \n");
    printf(cpStr);

    caStr[0]='h';
    caStr[1]='e';
    caStr[2]='l';
    caStr[3]='l';
    caStr[4]='0';

    printf(caStr);
    putchar('\n');
    return 0;

}

castr의 배열에 저장된값 출력 배열의 경우 마지막에 null을 넣지 않으면 특수문자 \0 이 자동으로 붙음 그래서 castr[4]는 0을 넣음



임베디드

7F 45 4C // ELF파일임을 나타내는 아스키 코드







#include <stdio.h>

 int main(void) 
{
     char str1[] = "My String";
     char *str2 = "Your String";
     printf("%s %s \n", str1, str2);
     printf("str1 address : %p \n", str1);

     printf("main address", main);
     printf("str address", str2);

     printf("str2 address : %p \n", str2);
     str2 = "Our String";
     printf("%s %s \n", str1, str2);

     str1[0] = 'X';
     //str2[0] = 'X';
     printf("%s %s \n", str1, str2);
	    
     return 0;	
}




단순하게 화면을 출력할꺼면 포인터를 쓰는 것이 좋다.   // char *str2 = "";

위의 예제에서 포인터는 stack 영역에서 4byte를 차지하고 문자열은 10바이트를 차지한다. (M/y/_/S/t/r/i/n/g/null)



문자를 수정하려면 문자열을 쓴다.  // char str1[] = "";


메모리의 code영역은 Read only라 쓰면 안됨. (위의 소스에서 18행을 주석처리한 이유)

도스에서 허용하지만 리눅스에선 안되며 원래 쓰지 않는 것이 맞다.





포인터를 활용한 printf문

1
2
3
4
5
6
7
8
9
#include <stdio.h>

int main(void)
{
	char *cpStr = "A=%d \n";
	int A = 100;
	printf(cpStr, A);
	return 0;
}



Output:

1
A=100 



728x90

전역변수

 

어디서든 접근이 가능한 변수

전역변수와 지역변수의 이름을 달리하는 것이 좋다.

 



 

전역변수 아래와 같이 선언했을 때, 만들어진 파일의 용량이 엄청 커진다.

 

int A[1024*1024]={1, };

 

 


전역변수의 선언은 신중해야 한다.

프로그램이 복잡해지고 크기가 증가한다.

 

 

int A;

전역변수 A의 값은 0

 

 

 

 

지역변수에 static 선언하면?


: 전역변수의 성격을 지니게 됨


처음 1회만 초기화, 프로그램 종료시까지 메모리 상주(전역변수의 특성)

선언된 함수내에서만 접근 가능(지역변수의 특성)

 




전역변수에 static 선언하면?


분할 컴파일시, 파일간에 접근 불가능 (개별화됨)

 

 

 

// main.c 소스

#include <stdio.h>

int a;
int main(void)
{   
    printf("main: A = %d \n", a);
    test();
    printf("main: A = %d \n", a);
    return 0;
}

 

 

// test.c 소스

#include <stdio.h>

int a;
void test(void)
{
    printf("test : a = %d \n",a);
    a = 777;
    printf("test : a = %d \n",a);
    return;
}

 

 

 

test.c 소스 3행의 int a;에 static을 붙였을 때의 출력결과

 

 

 

 

 

 

비쥬얼 스튜디오 실습

 

 

위의 소스를 작성후 6행에 중단점 설정

 


주소를 고정하고 메모리의 값을 알기 위해 아래의 과정을 따라한다.


 

DYNAMIC BASE를 NO로 설정하면 주소가 고정된다.

 

디버그할 때 메모리의 내용보기

 

바로 위와 같이 설정하면 디버그시, 주소와 함께 메모리의 정보가 표시된다.


조사식에 &iNum을 넣으면 주소를 알 수 있고, 메모리란의 주소에 값을 넣으면 내용을 볼 수 있다. 

 

 

iNum의 주소 0x 00 19  fe  fc


메모리에 Little Endian 으로 fc  fe  19  00 이 올라가있음을 볼 수 있다.

 

 


포인터 변수의 크기

32bit system : 포인터 변수의 크기가 4byte

64bit system : 포인터 변수의 크기가 8byte




어셈블리 코드에서 dword ptr은 4byte pointer,

word ptr은 2byte pointer를 가리킨다.



 마찬가지로 포인터의 주소를 통해 값을 볼 수 있다. 



메모리의 TEXT 부분에 현재 실행중인 명령을 담고 있는 것이 Instruction Pointer이다.

EIP는 IP가 16비트에서 32비트 시스템으로 오면서 Extended 된것으로, 디버그시 EIP 레지스터도 확인 가능하다.





포인터 주소(0x 0019 FEF8)를 따라가서 메모리에 든 값 51EB 851F를 10진수로 바꿔보면, 

1,374,389,535라는 값이 나온다.


  

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

2016-04-06-업무일지_포인터 및 함수  (0) 2016.04.06
20160405_포인터와 배열  (0) 2016.04.05
20160329_C기초, 디버깅  (0) 2016.03.29
20160308_업무일지_그 밖의 기초 학습  (0) 2016.03.08
20160307_업무일지_파일 입출력  (0) 2016.03.07
728x90


리눅스와 윈도우간 c언어 파일은 호환되나, 실행파일은 그 운영체제에서만 호환된다.

 

c언어의 호환성

*.c파일을 열어보면 개행문자는 메모장에서는 제대로 처리되지 않지만, 

visual studio 등의 프로그램으로 열면 개행문자가 제대로 처리된 소스를 볼 수 있다.



도스창 명령어


dir >>1.txt

redirection : 출력방향을 1.txt파일로 보냄.  파일을 열어보면 dir의 내용이 들어가있는 걸 볼 수 있다.



copy main.c smart.c     // main.c파일을 smart.c파일로 복사한다.

copy main.c + smart.c  // main.c파일과 smart.c 파일을 합친다. 



type 명령어 : 파일의 내용을 화면에 텍스트로 출력한다. 

type main.c    // main.c의 내용을 화면에 출력

type *.c        // 디렉토리에 있는 모든 *.c파일의 내용을 화면에 출력





리눅스에서 터미널 명령어


리눅스는 명령어가 틀리다. type대신에 cat명령어를 통해 파일의 내용을 화면에 출력한다.




>는 리다이렉션 명령어.


cat a.c b.c > c.c

 cat test2.c>>test.c


cat test2.c >> test.c 명령을 하면 test2.c의 텍스트가 test.c 텍스트 최하단으로 복사된다. 



visual editor 명령어 


J 하면 아래위의 줄이 붙는다. (join)



/ 찾고싶은 키워드


n  다음 찾기


shift n  이전 찾기


:noh  하이라이트 꺼짐




라즈베리파이를 통한 터미널 통신 (non-canonical)



#include <stdio.h>
#include <stdlib.h>
#include <strings.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);
    //iRet = read(iDev, cBuff, 255);
    //cBuff[iRet] = 0;
    //printf("[%s]:[%d]\n", cBuff, iRet);
    printf("write complete : %d\n", iRet);

    tcsetattr(iDev, TCSANOW, &stOldState);
    close(iDev);

    return 0;
}



gpio 도면을 보면 8, 10번 핀이 각각 TX, RX임을 알 수 있다.




라즈베리 파이 8,10번핀에 꼽아준다.


결과 : 



test라는 글자를 발신하면 받는 쪽에서 test라는 글자와 함께 글자수가 출력된다. (test\n까지 5글자)

발신이 완료되면 발신완료 문자와 함께 글자수가 출력된다. (write complete : 5)



728x90

지역변수

 

 

 

오른쪽의 예제에서 10번째 행을 주석처리 않았을 때는 if문 내 지역변수 값은 17, main함수내 지역변수 값은 1이 나온다.

6행의 num은 main 함수내에서만 접근 가능한데, if문 내에서 새로운 변수 num이 선언되었기 때문에 if문 내 지역변수 값은 17이 된다. (7+10)

 

주석처리시에는 각각 각각 11, 11이 나온다.

 

 

 

 

위의 예제를 수정해서 각각의 num의 주소를 알아보자.

 

위와 같은 결과가 나온다.

 

 

 

Linux gcc ASLR 해제 ( 랜덤 스택 Random Stack )

 

주소를 고정할때는 다음의 명령어를 친다.

sysctl -w kernel.randomize_va_space=0


이후 출력 되는 메시지

kernel.randomize_va_space = 0  // 0 대신 1을 넣으면 활성화

 

 

unix, linux - 장치를 파일로 간주

/dev 안에 장치들이 모여있음

 

 

리눅스 tty, TeleTYpewriter; TTY리눅스 텔레타이프라이터, 원격타자기

 

c - character 1 바이트

stream 데이터의 크기가 정해지지 않음(최소크기 1바이트)

 

두 가지로 나뉨

character device

block device

 

l - link (바로가기)

심볼릭 링크

하드 링크

 

man ( 알고 싶은것  )  : 리눅스 메뉴얼  // man printf, man fopen

// 섹션3 보려면 man 3 printf

빠져나오려면 q

 

 

vi 자동 정렬

1. 명령모드(esc)로 감
2. gg=G

 

 

'Linux & Network' 카테고리의 다른 글

2016 04-14 소켓  (0) 2016.04.15
20160401_리눅스 터미널 및 통신  (0) 2016.04.01
20160330_리눅스 터미널  (0) 2016.03.30
라즈베리 파이 원격제어와 C언어  (0) 2016.03.28
라즈베리파이 기본 설정  (0) 2016.03.25

+ Recent posts