티스토리 뷰

전자회로/임베디드교육

6

쥬브62 2020. 5. 11. 14:01

(월)

- 부트로더 , 커널,  유틸리티

 

- GPL : 리눅스의 커널은 수정시 꼭 공개해야 함

 

- rc(runtime configuration)

 

- 리눅스 명령어

1. cd / : 최상위 디렉토리

2. pwd : 현재 경로

3. cd : root 디렉토리

4. mkdir 폴더명 : 디렉토리 생성

5. cd /mnt/hgfs/ : vmware 설정에서 공유한 폴더

6. tar xzf 파일명 : 압축 풀기

7. cd - : 이전 디렉토리로 이동

8. du -h 폴더명 : 해당 폴더의 용량 확인

 

-

1. 툴체인(2,3,4를 binary로 만들때 사용하는 컴파일러)

2. mds2450 포팅된 커널

3. root file system(root에 마운트되어 있는 file system)

4. 부트로더

 

- ctags

1. $ ctags -R : 태그만들기

2. $ vim -t start_kernel

3. 여러 개 검색된 경우 번호를 눌러서 해당 파일로 이동하기

4. ctrl + ] :  해당 함수로 이동
5. ctrl + t : 다시 돌아가기 

 

6. ctrl + wf : include 헤더파일 열기 
7. crtl + w위아래화살표키 / crtl + ww : 창간이동

8. :q : 종료

 

- cscope

1. $ apt-get install cscope : 설치

2. $ find ./ -name *.[chS] -print > cscope.files : 이름이 .c, .h, .S 인 것을 찾아서 만듬

3. $ cscope

4. ctrl + D : 종료

 

- 인터넷이 끊겼다 연결됬다 반복될때 문제 해결(인터넷을 수동으로 잡아 줌)

1. system settings

2. Network

3. 원인 디바이스의 Options

4. IPv4 Settings

5. Method를 Manual로 변경

6. add하여 192.168.20.90, 255.255.255.0, 192.168.20.1 각각 입력

7. ifconfig로 잘됐는지 확인

 

 

(화)

-

 

1. 시리얼창을 켠채 보드키고 zImage 다운 받아 지면 root로 로그인

2. cd / 

3. ls로 확인

 

- 리눅스 명령어

1. file 파일명 : 속성 확인

2.  

 

- 라이브러리

1. 정적라이브러리

 . 파일 생성시 라이브러리 내용 포함하여서 사용. 

 . 사용빈도가 낮은 거

2. 동적라이브러리

 . 라이브러리를 공유하여 사용.

 . 사용빈도가 높은 거

 . 메모리 효율적으로 사용가능

 

 

- 정적라이브러리 만들기

 

- 동적라이브러리 만들기

 

- 다른 사람의 코드 사용시 makefile의 확인이 우선!

 

- 저수준 입출력 함수

. 리눅스 커널에서 제공하는 파일관련 시스템 콜을 라이브러리 함수로 만든것

. open() : 파일을 열기 위한 역할을 하는 함수

close() : 파일을 닫기 위한 역할을 하는 함수

read() : 파일 기술자에 해당하는 파일이나 장치에서 데이터를 count만큼 읽어 buf가 가리키는 주소에 넣는 함수 

write() : 파일 기술자에 해당하는 파일이나 장치에 buf가 가리키는 주소에 있는 데이터를 count만큼 쓴다.

lseek() : 파일 기술자에 해당하는 파일이나 장치에서 파일 포인터의 위치를 변경한다 

ioctl() : 디바이스 파일제어, 파일 기술자에 해당하는 장치에 read()와 write()함수로 처리하기 힘든 입출력 처리에 사용

 

P1 P2 P3 P1 P2 P3 . . .

. 자기 순서가 지나면 완료하지 못한 정보를 저장하고 있다가 자기 차례가 오면 다시 실행

 

- 리눅스 프로세스

- 프로스세 관련 쉘 명령어

1. top 

2. pstree

3. ps -aux

4. cat /proc/1/status

 

- fork : 프로세스 생성

1. 프로세스 A에서 fork를 호출하여 프로세스 B가 생성

2. 프로세스 A는 부모, 프로세스 B는 자식이 됨.

3. fork 성공시 부모는 자식의 pid값이 리턴, 자식은 0이 리턴된다.

. PC도 복제가 된다.

 

- 명령어에 &를 붙이면 백그라운드로 실행 된다.

- ps -l : 돌아가는 거 확인 가능

- kill -9 pid 로 죽일 수 있다

 

(수)

리눅스 명령어

1. ps -Al : 긴 포맷으로 모든 프로세스를 보여줌

 

예제코드(우선순위)

#include <stdio.h>
#include <sys/types.h>      //getpriority()
#include <sys/resource.h>
#include <unistd.h>         //getpid()

int main(void)
{
    
    pid_t current_pid = getpid(); //현재 프로세스의 ID를 구함 
    
    //현재 프로세스의 우선순위설정 및 가져오기 
    /*  
     * PRIO_PROCESS: 해당 프로세스의 ID 내 
     * PRIO_PGRP: 해당 프로세스가 속한 그룹
     * PRIO_USER: 사용자 ID를 갖는 프로세스
     */
     
    setpriority(PRIO_PROCESS, current_pid, -20);
    nice(2);    // 현재 nice 값에 2를 더함, PRI는 62가 될것 이다.(80-20+2)
    int priority = getpriority(PRIO_PROCESS, current_pid);

    printf("Process: %d, Priority: %d\n", current_pid, priority);

    for(;;)
    	sleep(1); // &을 사용하여 bg를 확인 하려고 사용

    return 0;
}

 

예제코드(쓰레드)

//thread_test.c

#include <stdio.h>
#include <pthread.h>

int thread_args[3] = { 0, 1, 2 };  /* 쓰레드가 사용할 인자 */
//-------------------------------------------------------------
/* 쓰레드로 수행할 함수 */
void* Thread( void *arg )
{
    int i;
    for ( i=0; ; i++ ) //생성한 쓰레드가 계속 반복됨
	{
        printf( "thread %d: %dth iteration\n", *(int*)arg, i );
		sleep(1);
	}
    pthread_exit(0);  /* 쓰레드 종료 함수 */
}
//-------------------------------------------------------------
int main( void )
{
    int i, clock_get;
    pthread_t threads[3]; /* 쓰레드 아이디를 위한 변수 */
    
    for ( i=0; i<3; i++ )  /* 쓰레드 생성 */
       // TODO: 스레드 생성하기
        pthread_create( &threads[i],                /* 쓰레드ID */
                        NULL,                       /* 쓰레드 속성 */
                        ( void* (*)(void*) )Thread, /* 쓰레드 시작 함수 */
                        &thread_args[i] );          /* 생성된 쓰레드에 전달 인자 */
						
	while(1) sleep(1); //쓰레드 생성한 것을 유지
    pthread_exit(0); /*메인 쓰레드 종료 */
}

$ gcc -o thread_test thread_test.c -lpthread

$ ./thread_test.c &

$ ps -alLm : 돌아가는 쓰레드 확인

$ kill -9 LWP : 쓰레드 죽임

 

- 예제코드(세마포어)

#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>

sem_t        sem;  /*TODO: semaphore variable - sem */
pthread_t   task1, task2;
pthread_attr_t attr;
struct sched_param param;
//----------------------------------------

-----------------------------
void get_thread( void ) { 
    int i = 0;
    int val;
  
    while(1) {
        i++;
        sem_wait( &sem ); /* TODO: obtains semaphore, reduce it by 1 */
        sem_getvalue( &sem, &val ); /* obtains the semaphore value */
        printf( "WAIT!\tsem count = %d\n" ,val );
        if ( i > 5 ) break;
    }   
}
//----------------------------------------
void put_thread(void) {
    int i = 0;
    int val;

    while(1) {
        i++;
        sem_post( &sem ); /* TODO: semaphore post */
        sem_getvalue( &sem, &val ); /* obtains the semaphore value */
        printf( "POST!\tsem count = %d\n", val );
		sleep(1);
        if ( i > 5 ) break;
    }   
}
//----------------------------------------
int main( void ) { 
    int i = 0, j, val;

    sem_init( &sem, 0, 3 ); /* TODO: initialize unnamed semaphore */
    sem_getvalue(&sem, &val);
    printf( "INIT!\tsem count = %d\n", val );

    pthread_attr_init(&attr);
    param.sched_priority = 20; 
    pthread_attr_setschedparam(&attr, &param);
    pthread_attr_setschedpolicy( &attr, SCHED_FIFO );

    pthread_create( &task1, &attr, (void*(*)(void*))get_thread, NULL );
    pthread_create( &task2, &attr, (void*(*)(void*))put_thread, NULL );
       
    pthread_exit(0);
}

$ gcc -o posix_sem_test posix_sem_test.c -lpthread

$ ./posix_sem_test

왜 ????????

 

- 예제코드(mutex)

/***************************************
 * Filename: mutex_test.c
 * Title: Mutex
 * Desc: 뮤텍스를 이용한 예제 
 ***************************************/
#include <semaphore.h>
#include <pthread.h>
#include <sys/types.h>

/* TODO: 뮤텍스 변수 선언 mutex, 선언과 동시에 초기화 */
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int val;
int arg1 = 0, arg2 = 1;
//-------------------------------------------
void *Thread( void* arg )
{
    int i, j;

    for( i = 0; ; i++ ) {
        /* TODO: mutex 잠그기 */
        pthread_mutex_lock( &mutex );
        val = *(int*)arg;
        printf( "thread %d: %dth iteration: val = %d\n", *(int*)arg, i, val);
        /* TODO: mutex 풀기 */
        pthread_mutex_unlock( &mutex );
        //for ( j=0; j<1000000; j++ );
        sleep(1);
    }
}
//-------------------------------------------
int main( void ) {
    pthread_t  thread1, thread2;
    pthread_attr_t attr;
    
    struct sched_param param;
    int policy;
    
    pthread_getschedparam( pthread_self(), &policy, &param );
    param.sched_priority = 1;
    policy = SCHED_RR;
    if ( pthread_setschedparam( pthread_self(), policy, &param ) != 0 ) {
        printf("main\n");
        while(1);
    }
    pthread_attr_init( &attr );
    pthread_attr_setschedpolicy( &attr, SCHED_RR );
	
	pthread_create( &thread1, &attr, (void*(*)(void*))Thread, &arg1 );
    pthread_create( &thread2, &attr, (void*(*)(void*))Thread, &arg2 );

    pthread_exit(0);
    return 0;

}

- 예제코드(mutex) 2

#include <semaphore.h>
#include <pthread.h>
#include <sys/types.h>

/* TODO: 뮤텍스 변수 선언 mutex, 선언과 동시에 초기화 */
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int val;
int arg1 = 0, arg2 = 1;
//-------------------------------------------
void *Thread( void* arg )
{
    int i, j;

    for( i = 0; ; i++ ) {
        /* TODO: mutex 잠그기 */
        pthread_mutex_lock( &mutex );
        val = *(int*)arg;
        printf( "%d", val);
        /* TODO: mutex 풀기 */
        pthread_mutex_unlock( &mutex );
        //for ( j=0; j<1000000; j++ );
        
    }
}
//-------------------------------------------
int main( void ) {
    pthread_t  thread1, thread2;
    pthread_attr_t attr;
    
    struct sched_param param;
    int policy;
    
    pthread_getschedparam( pthread_self(), &policy, &param );
    param.sched_priority = 1;
    policy = SCHED_RR;
    if ( pthread_setschedparam( pthread_self(), policy, &param ) != 0 ) {
        printf("main\n");
        while(1);
    }
    pthread_attr_init( &attr );
    pthread_attr_setschedpolicy( &attr, SCHED_RR );
	
	pthread_create( &thread1, &attr, (void*(*)(void*))Thread, &arg1 );
    pthread_create( &thread2, &attr, (void*(*)(void*))Thread, &arg2 );

    pthread_exit(0);
    return 0;

}

 vmware의 processor의 수를 2개 이상으로 했을 경우 동작 비교
 두개의 스레드가 각각돌때 두개의 스레드는 쉬는 시간 없이 계속 돌게 됨.
 블럭은 되지만 계속 실행됨. 

 

결론: 두 스레드의 우선순위는 같지만 공평하게 수행되지는 않음.
thread실행될 때 segmentation fault의 문제 발생하면 thread가 모두 죽어버림.
화면에 출력될 당시에는 이미 그 메세지는 과거의 실행된 부분.
더구나 thread가 시간에 민감할 경우에는 출력문에도 영향을 준다.
  
1. 임계영역 접근하려고 할때 즉시 블럭이 되고 그 때 문맥전환이 일어남.
2. printf문도 블럭시키는 함수.
   출력 버퍼에 계속 넣는 것.
   화면 출력은 버퍼가 찼을 때 블럭되는 것. 
   개행 문자가 왔을때 또는 버퍼가 꽉 찼을 때 출력이 되는 것임.

 

- vi명령어

1. gg : 맨처음으로 이동

2. G : 맨끝으로 이동

 

- 예제코드 (mutex) 3

/***************************************
 * Filename: mutex_signal.c
 * Title: Mutex
 * Desc: 잠금 대기에 관한 예제 
 ***************************************/
#include <stdio.h>
#include <pthread.h>

pthread_t  thread;

/* 뮤텍스 초기화 */
pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER;
/* TODO: 조건 변수의 초기화 */
pthread_cond_t  cond = PTHREAD_COND_INITIALIZER;

/* 전역 변수 */
int count = 0;
//------------------------------------------------
void* Thread ( void* arg ) {
    
    pthread_mutex_lock ( &mutex ); 
    
    /* TODO: count가 5가 될 때까지 기다림, 블록될 경우에는 뮤텍스를 푼다 */
    while ( count < 5 ) {
        printf( "count = %d: wait...\n", count );
        pthread_cond_wait ( &cond, &mutex ); 
    }
    printf( "count = %d: condition true.\n", count );
    
    pthread_mutex_unlock ( &mutex );
}
//------------------------------------------------
void main ( void ) {
    int i;
    pthread_create( &thread, NULL, (void*(*)(void*))Thread, NULL );
    
    for ( i = 0; i < 10; i++ ) {
        sleep(1);
        pthread_mutex_lock( &mutex );

        count++;
        
        pthread_cond_signal( &cond ); //쓰레드에 시그널 보내기
        printf( "condition signal %d\n", i );

        pthread_mutex_unlock( &mutex );
    }
    pthread_exit(0);
}

 

- 예제코드 ( 파이프)

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#define BUFSIZE 15000

//--------------------------------------
// Create a pipe, write to it, and read from it.
int main( int argc, char **argv )
{
	static const char mesg[] = "Don't Panic!";
	char buf[BUFSIZE];
	ssize_t rcount, wcount;
	int pipefd[2]; /*pipe에서사용할파일기술자*/
	size_t len;/* TODO: pipe 를생성한다. (에러처리할것) */
	int pid;

	if ( pipe(pipefd) < 0 ) 
	{
		fprintf(stderr, "%s: pipe failed : %s\n", argv[0], strerror(errno));
		exit(1);
	}
	printf( "Read end = fd %d, write end = fd %d\n",pipefd[0], pipefd[1]);/* write에사용할message의길이*/
	len = strlen(mesg);

	pid=fork();	
	if(pid<0){ // fork failed!
		fprintf(stderr,"fork failed");
		exit(-1);
	}
	else if(pid==0){ // child process
		
	
		if(read(pipefd[0],buf,BUFSIZE)<0)
		{
			fprintf(stderr, "%s: read filed : %s\n", argv[0], strerror(errno));
			exit(1);
		}
			buf[len]='\0';
			printf("i'm child process. Read <%s> from pipe \n", buf);
			exit(0);
	}
	else{  // parent process

#if 1
		if (write( pipefd[1], mesg, len)<0 ) {
			fprintf(stderr, "%s: write failed : %s\n", argv[0], strerror(errno));
		exit(1);
		}
#endif
		close(pipefd[0]);
		close(pipefd[1]);
		wait(NULL);
		exit(0);
	}

	return 0;
}

 

- 예제코드(메시지 큐)

/***************************************
 * Filename: sysv_msg_test_a.c
 * Title: Periodic Thread
 * Desc: System V Message Queue Example
 * Revision History & Comments
 *
 * ***************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
//#include <sys/wait.h>
#include <wait.h>

#include <time.h>


/* Redefines the struct msgbuf */
typedef struct mymsgbuf
{
	long mtype;
	int int_num;
	float float_num;
	char ch;
} mess_t;

int main()
{
	int qid;
	key_t msgkey;
	mess_t sent;
	mess_t received;
	int length;
	int pid;

	/* Initializes the seed of the pseudo-random number generator */
	srand (time (0));
	/* Length of the message */
	length = sizeof(mess_t) - sizeof(long);
	msgkey = ftok(".",'m');

	/* Creates the queue*/
	qid = msgget(msgkey, IPC_CREAT | 0660);
	printf("QID = %d\n", qid);

		/* Builds a message */
		sent.mtype = 3;
//		sent.int_num = rand();
		sent.int_num = 13;
//		sent.float_num = (float)(rand())/3;
		sent.float_num = 0.15;
		sent.ch = 'f';

	pid=fork();

	if(pid > 0 ){
		/* Sends the message */
		msgsnd(qid, &sent, length, 0);
		msgsnd(qid, &sent, length, 0);
		printf("MESSAGE SENT..., qid=%d\n", qid);
		wait(NULL);
	} else if(pid == 0){  //child process
//		sleep(1);
		/* Receives the message */
#if 1
		msgrcv(qid, &received, length, sent.mtype, 0);
		printf("MESSAGE RECEIVED..., qid=%d, mtype=%d\n", qid, sent.mtype);
		printf("MESSAGE RECEIVED..., qid=%d\n", qid);
		

		/* Controls that received and sent messages are equal */
		printf("Integer number = %d (sent %d) -- ", received.int_num, sent.int_num);

		if(received.int_num == sent.int_num) printf(" OK\n");
		else printf("ERROR\n");

		printf("Float numero = %f (sent %f) -- ", received.float_num, sent.float_num);

		if(received.float_num == sent.float_num) printf(" OK\n");
		else printf("ERROR\n");

		printf("Char = %c (sent %c) -- ", received.ch, sent.ch);
	
		if(received.ch == sent.ch) printf(" OK\n");
		else printf("ERROR\n");
#endif
	} else
		printf("fork error \n");
	/* Destroys the queue */
	//msgctl(qid, IPC_RMID, 0);
}

 

(목)

- 예제코드 (시그널)

//#define _SIGNAL_DISABLE_IFDEF //활성화시 시그널 무시함
//#define _SIGNAL_ENABLE_IFDEF //활성화시 ^C 누르면 바로 종료
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

void catchint(int signo);

int main(void)
{
	int i;

	signal(SIGINT, catchint);

#ifdef _SIGNAL_DISABLE_IFDEF
	signal(SIGINT, SIG_IGN);
#endif // _SIGNAL_DISABLE_IFDEF

#ifdef _SIGNAL_ENABLE_IFDEF
	signal(SIGINT, SIG_DFL);
#endif // _SIGNAL_ENABLE_IFDEF

	for(i=10; i>0; i--)
	{
		printf("%d seconds remain till process's terminated\n", i);
		sleep(1);
	}

	printf("Exiting\n");
	return(0);
}

// trivial function to handle SIGINT
void catchint(int signo)
{
	printf("\nCATCHINT: signo=%d\n", signo);
	printf("CATCHINT: returning\n\n");
}

- 예제코드 (시그널 ) 2

#define _SIGNAL_MASK_IFDEF
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

int entered= 0;

void interrupt(int signo)
{
	// SIGINT 
#ifdef _SIGNAL_MASK_IFDEF
	signal(SIGINT, SIG_IGN);
#endif // _SIGNAL_MASK_IFDEF
	entered++;
	printf("Interrupt entered(%d)\n", entered);
	sleep(2);
	printf("Interrupt exit(%d)\n", entered);
	// SIGINT 
#ifdef _SIGNAL_MASK_IFDEF
	signal(SIGINT, interrupt);
#endif // _SIGNAL_MASK_IFDEF
}

int main(void)
{
	signal(SIGINT, interrupt);
	printf("Interrupt set for SIGINT\n");
	while(1);

	return 0;
}

 

- 예제코드 (시그널 ) 3

//03_sigusr.c
/*
1)SIGUSR1/SIGUSR2( using this command $kill -12 PID )
*/
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

static void	sig_usr(int);	/* one handler for both signals */

int main(void)
{
	if (signal(SIGUSR1, sig_usr) == SIG_ERR)
		perror("can't catch SIGUSR1");
	if (signal(SIGUSR2, sig_usr) == SIG_ERR)
		perror("can't catch SIGUSR2");

	for ( ; ; )
		pause();
}

static void
sig_usr(int signo)		/* argument is signal number */
{
	if (signo == SIGUSR1)
		printf("received SIGUSR1\n");
	else if (signo == SIGUSR2)
		printf("received SIGUSR2\n");
	else
		printf("received signal %d\n", signo);
	return;
}

$ ./03_sigusr.c &

$ ps -l

 

- 예제코드 (시그널) 4

#include <stdio.h>     /* standard I/O functions                         */
#include <unistd.h>    /* standard unix functions, like alarm()          */
#include <signal.h>    /* signal name macros, and the signal() prototype */

char user[40];		/* buffer to read user name from the user */

/* define an alarm signal handler. */
void catch_alarm(int sig_num)
{
    printf("Operation timed out. Exiting...\n\n");
    exit(0);
}

int main(int argc, char* argv[])
{
    /* set a signal handler for ALRM signals */
    signal(SIGALRM, catch_alarm); 

    /* prompt the user for input */
    printf("Username: ");
    fflush(stdout);
    /* start a 5 seconds alarm */
    alarm(5);
    /* wait for user input */
    gets(user);
    /* remove the timer, now that we've got the user's input */
    alarm(0); // 5초 알람전에 입력 들어오면 알람을 끔

    printf("User name: '%s'\n", user);

    return 0;
}

5초 전에 입력시
미입력시

 

- udp_simple_msg_transfer

1. udp_svr.c 와 udp_cli.c를 gcc 또는 (arm용 gcc)로 빌드
   svr, svr_arm,  cli, cli_arm
2. host에서 svr을 백그라운드 실행
    $ ./svr &
3. Target 에서 cli로 서버에 연결
    # ./cli_arm 서버ip
    [input_msg] 전달할 메세지 입력(영문만 가능) 
4. host에서 돌고있는 svr 프로그램이 수신한 메세지 출력
* Target에서 # ./svr_arm &   //서버 실행하여 놓고
  Host에서 $ ./cli 서버ip  //접속하여 메세지 전송 테스트
* 소스파일 분석하여 필요에 따라 변경하여 사용

//udp_cli.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>

#define  BUFF_SIZE   1024

int   main( int argc, char **argv)
{
   int   sock;
   int   server_addr_size;

   struct sockaddr_in   server_addr;

   char   buff_rcv[BUFF_SIZE+5];


   sock  = socket( PF_INET, SOCK_DGRAM, 0);
   
   if( -1 == sock)
   {
      printf( "socket create fail\n");
      exit( 1);
   }

   memset( &server_addr, 0, sizeof( server_addr));
   server_addr.sin_family     = AF_INET;
   server_addr.sin_port       = htons( 4000);
   server_addr.sin_addr.s_addr= inet_addr( argv[1]);

	while(1){
		printf("[input msg] :");
		fgets(buff_rcv,BUFF_SIZE,stdin);
		sendto( sock, buff_rcv, strlen( buff_rcv), 0,    // +1: send include NULL
        	( struct sockaddr*)&server_addr, sizeof( server_addr));          
	}  
	close( sock);
	return 0;
}
//udp_svr.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>

#define  BUFF_SIZE   1024

int   main( void)
{
   int   sock;
   int   client_addr_size, cnt;

   struct sockaddr_in   server_addr;
   struct sockaddr_in   client_addr;

   char   buff_rcv[BUFF_SIZE+5];
   char   buff_snd[BUFF_SIZE+5];



   sock  = socket( PF_INET, SOCK_DGRAM, 0);
   
   if( -1 == sock)
   {
      printf( "socket create fail\n");
      exit( 1);
   }

   memset( &server_addr, 0, sizeof( server_addr));
   server_addr.sin_family     = AF_INET;
   server_addr.sin_port       = htons( 4000);
   server_addr.sin_addr.s_addr= htonl( INADDR_ANY);

   if( -1 == bind( sock, (struct sockaddr*)&server_addr, sizeof( server_addr) ) )
   {
      printf( "bind() execute error\n");
      exit( 1);
   }
	printf("\nwaiting...\n");
   while( 1)
   {
		client_addr_size  = sizeof( client_addr);
		cnt=recvfrom( sock, buff_rcv, BUFF_SIZE, 0 , 
                     ( struct sockaddr*)&client_addr, &client_addr_size);
		buff_rcv[cnt]='\0';
		printf("[%s] %s\n",inet_ntoa(client_addr.sin_addr),buff_rcv);
   }
}

host (리눅스)
target (보드)

- 예제코드(공유메모리)

//server.c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define SHMSZ 27
char SEM_NAME[]= "vik";

int main()
{
	char ch;
	int shmid;
	key_t key;
	char *shm,*s;
	sem_t *mutex;	//name the shared memory segment
	key = 1000;

	mutex = sem_open(SEM_NAME,O_CREAT,0644,1);
	if(mutex == SEM_FAILED){
		perror("unable to create semaphore");
		sem_unlink(SEM_NAME); 
		exit(-1);
	}
	// key로 공유메모리 생성
	shmid = shmget(key,SHMSZ,IPC_CREAT|0666);
	if(shmid<0){
		perror("failure in shmget"); 
		exit(-1);
	}
	// 이 조각을 가상메모리에 덧붙인다
	shm = shmat(shmid,NULL,0);

	// 메모리에 쓰기 시작
	s = shm;
	for(ch='A';ch<='Z';ch++){
		sem_wait(mutex);
		*s++ = ch;
		sem_post(mutex);
	}
	// 이진 세마포어로 대체 가능
	while(*shm != '*'){
		sleep(1);
	}
	sem_close(mutex);
	sem_unlink(SEM_NAME);
	shmctl(shmid, IPC_RMID, 0); //공유메모리 삭제
	exit(0);
}
//client.c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define SHMSZ 27

char SEM_NAME[]= "vik";
int main()
{
	char ch;
	int shmid;
	key_t key;
	char *shm,*s;
	sem_t *mutex;	//name the shared memory segment
	
	key = 1000; //서버과 같은 key값

	//세마포어 생성 초기화
	mutex = sem_open(SEM_NAME,0,0644,0);
	if(mutex == SEM_FAILED){
		perror("reader:unable to execute semaphore");
		sem_close(mutex);
		exit(-1);
	}
	// key를 사용하여 공유메모리 생성
	shmid = shmget(key,SHMSZ,0666);
	if(shmid<0){
		perror("reader:failure in shmget");
		exit(-1);
	}
	// 이 조각을 가상메모리에 덧붙인다.
	shm = shmat(shmid,NULL,0);
	//start reading
	s = shm;
	for(s=shm;*s!=NULL;s++){
		sem_wait(mutex);
		putchar(*s);
		sem_post(mutex);
	}
	
	*shm = '*';
	sem_close(mutex);
	shmctl(shmid, IPC_RMID, 0);
	exit(0);
}

$ ./server

$ ./client

서버의 글자를 클라이언트가 읽어들인 후에는 *로 바꾸기 때문에..(다시 소스코드 보기)
서버는 다 쓴 뒤에 계속 폴링을 해서 * 표시 읽힐 때까지 기다리고 종료함.

 

shmctl를 비활성화 하고 $ ipcs 로 확인

 

- cat /proc/sys/kernel/shmmax : 공유메모리 크기 확인

cat /proc/sys/kernel/msgax : 메시지큐 크기확인

cat /proc/sys/kernel/pid_max : pid 크기확인

 

- 예제코드 (모듈)

//Makefile

obj-m += hello.o   

#KDIR	:= /lib/modules/$(shell uname -r)/build
KDIR	:= /work/G2450_bsp/01_bsp/kernel-mds2450-3.0.22

all:
	make -C $(KDIR) SUBDIRS=$(PWD) modules

clean:
	make -C $(KDIR) SUBDIRS=$(PWD) clean

$ cd /work/G2450_bsp/01_bsp/kernel-mds2450-3.0.22 

$ make

중단하고 돌아와서 hello.c를 make 하면 hello.ko 만들어짐

$ cp hello.ko /nfs/rootfs/root/ 

 

# insmod hello.ko

Hello, world 4.

# lsmod

Module                  Size  Used by    Not tainted
hello                      660  0

# rmmod hello.ko

Goodbye, world 4.

 

//hello.c

#include <linux/module.h>	/* Needed by all modules */
#include <linux/kernel.h>	/* Needed for KERN_INFO	*/
#include <linux/init.h>		/* Needed for the macros */

#define	DRIVER_AUTHOR	"Taek Ki, Kim <taekki@mdstec.com>"
#define	DRIVER_DESC		"A sample driver"

static int __init init_hello_4(void)
{
	printk(KERN_INFO "Hello, world 4.\n");
	return 0;
}

static void __exit cleanup_hello_4(void)
{
	printk(KERN_INFO "Goodbye, world 4.\n");
}

module_init(init_hello_4);
module_exit(cleanup_hello_4);
/* Get rid of taint message by declaring code as GPL. */
MODULE_LICENSE("GPL");
MODULE_AUTHOR(DRIVER_AUTHOR);		/* Who wrote this module? */
MODULE_DESCRIPTION(DRIVER_DESC);	/* What does this module do */
MODULE_SUPPORTED_DEVICE("testdevice");

 

- git 실습

 

 

 

'전자회로 > 임베디드교육' 카테고리의 다른 글

8주차  (0) 2020.05.25
7주차  (0) 2020.05.18
5  (0) 2020.05.04
4  (0) 2020.04.27
MMU(memory management unit) -수정중  (0) 2020.04.21
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
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
글 보관함