2.1 시스템 콜
1. 시스템 콜
1) 시스템 콜
- 운영체제가 제공하는 서비스에 대한 프로그래밍 인터페이스
- 보통 C 또는 C++과 같은 고급 언어로 만들어지고, 직접 시스템 콜을 호출하기 보다는 고급 API를 통해 접근한다.
2) 시스템 콜의 절차
① 유저 프로세스에서 라이브러리 (fork())를 호출한다.
② 라이브러리에서 mvl 2가 eax 레지스터에 저장되고, 0x80 인터럽트를 일으킨다.
③ Interrupt Vector Table에 0x80을 찾아가 시스템 콜 주소를 찾는다
④ 시스템 콜에서 인덱스 값을 넣어 시스템 콜 테이블에 있는 sys_fork()를 실행 시킨다.

3) 시스템 콜 추가 절차
① 시스템 호출 번호 할당
- (커널 소스 위치)/arch/(CPU Architecture)/include/asm/unistd_32.h 파일 편집
ㄴ #define __NR_newsyscall XXX
② 시스템 호출 테이블 등록
- (커널 소스 위치)/arch/(CPU Architecture)/kernel/syscall_table_32.S 파일 편집
ㄴ .long sys_newsyscall
③ 시스템 콜 헤더파일 수정
- (커널 소스 위치)/include/linux/syscall.h 파일 편집
ㄴ asmlinkage long newsyscall(int i)
④ 시스템 호출 함수 작성
- (커널 소스 위치)/kernel 내 함수 생성
⑤ 커널 리빌드
- Makefile 수정 및 커널 소스 전체 리빌드
2.2 스레드 동기화
1. 스레드
1) 스레드
- 세미 프로세스 혹은 경량 프로세스라고 불림
- 하나의 프로세스 안에 다수의 스레드를 구성하고 자원을 공유하는 방법이다.
2) 포직스(POSIX) 스레드 라이브러리
① 포직스 스레드 라이브러리
- 대부분의 운영체제가 지원하는 스레드 생성/종료 및 제어 API를 제공하는 라이브러리
- 포직스 스레드를 사용하기 위해서는 pthread.h 헤더 파일을 포함해야한다.
② 라이브러리 지원 함수
- 생성
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
ㄴ thread : 스레드 구분을 위한 식별자 번호. 생성 성공 시 고유번호 부여
ㄴ attr : 생성될 스레드 특성 정의
ㄴ start_routine : 실제 스레드에서 실행될 스레드 함수
ㄴ arg : 스레드에 전달할 인자
- 종료
int pthread_join(pthread_t th, void **thread_return)
ㄴ th : 정리하고자 하는 스레드의 식별자
ㄴ thread_return : 프로세스에게 반환할 값
void pthread_exit(void *retval)
- 분리 : pthread_create 함수로 생성된 스레드를 별도 분리 시켜 종료 즉시 스스로 자원을 해제하게 함
int pthread_detach(pthread_t th)
ㄴ th : 분리 시킬 스레드의 식별자
2. 세마포어
1) 세마포어
- 다중 프로세스 환경에서 자원 사용에 대한 상호배제와 동기화를 구현하는 기술
2) 포직스(POSIX) 세마포어 라이브러리
① 포직스(POSIX) 세마포어 라이브러리
- 포직스 세마포어를 사용하기 위해서는 semaphore.h 헤더 파일을 포함해야한다.
② 라이브러리 지원 함수
- 생성
int sem_int(sem_t* sem, int pshared, unsigned int value)
ㄴ sem : 초기화 할 세마포어
ㄴ pshared : 세마포어의 상태 결정 (0인 경우 thread 만 공유)
ㄴ value : 세마포어 초기 값
- 획득 : 임계영역 진입 후 세마포어 값 감소
int sem_wait(sem_t *sem)
- 반환 : 세마포어 값 증가
int sem_post(sem_t *sem)
- 종료 : 세마포어 리소스 해제
int sem_destroy(sem_t *sem)
3. 뮤텍스
1) 뮤텍스
- 상호 배제의 약어로 여러 쓰레드를 실행하는 환경에서 접근 제한을 위한 동기화 메커니즘
- 특정 영역에 하나의 쓰레드만 진입 할 수 있도록 제어
2) 포직스(POSIX) 뮤텍스 라이브러리
① 포직스 뮤텍스 라이브러리
- 포직스 뮤텍스를 사용하기 위해서는 pthread.h 헤더 파일을 포함해야한다.
② 라이브러리 지원 함수
- 생성
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex_attr *attr)
ㄴ mutex : 초기화 하려는 뮤텍스 객체
ㄴ attr : 뮤텍스 객체에 부가되는 특성
- 종료
int pthread_mutex_destory(pthread_mutex_t *mutex)
- 획득
int pthread_mutex_lock(pthread_mutex_t *mutex)
- 반환
int pthread_mutex_unlock(pthread_mutex_t *mutex)
4. 스핀락
1) 스핀락
- 임계 구역에 진입이 불가할 경우 진입 가능할 때까지 루프를 돌면서 재시도 하는 방식
2) 커널 사용 스핀락 라이브러리
① 커널 사용 스핀락 라이브러리
- 커널에서 스핀락 함수를 사용하기 위해서는 spinlock.h 헤더 파일을 포함해야한다.
② 라이브러리 지원 함수
- 생성
DEFINE_SPINLOCK(spinlock_t sl)
- 획득
ㄴ 인터럽트 상태 저장 & 비활성화
spin_lock_irqsave(spinlock_t *sl, unsigned long flags)
ㄴ 인터럽트 비활성화
spin_lock_irq(spinlock_t *sl, unsigned long flags)
- 반환
ㄴ 인터럽트 상태 복원 & 활성화
spin_unlock_irqrestore(spinlock_t *sl, unsigned long flags)
ㄴ 인터럽트 활성화
spin_unlock_irq(spinlock_t *sl, unsigned long flags)
2.3 네트워크 프로그래밍
1. TCP
1) TCP
- Transmission Control Protocol의 약어로 IP 프로토콜 기반 신뢰성 전송을 제공하는 연결 지향 프로토콜
2) TCP 헤더 구조

- Source Port : 송신자의 연결 포트
- Destination Port : 수신자의 연결 포트
- SEQ # : 순차 전송 포트
- ACK # : 확인 응답 번호
- Data offset : 현재 세그먼트 내의 위치
- Reserved : 예약
- Flags : 통신 제어를 위한 명령 플래그
- Window : 수신자의 버퍼 공간 관리 메커니즘
- Checksum : 헤더 정합성 체크
- Urgent : 긴급 데이터 처리 정보
- Option and Padding : 옵션 및 패딩
3) TCP 통신 절차도
- socket() : 소켓을 생성한다.
- bind() : 생성된 소켓에 로컬 IP와 포트를 바인딩
- listen() : 생성된 소켓에 바인딩 된 IP/Port에서 연결을 기다림
- connect() : 소켓을 통해 통신 대상 호스트에 연결
- accept() : 연결 요청이 온 소켓을 받아들임
- send(), recv() : 전송, 수신
- close() : 소켓 연결 종료

4) TCP 통신 소스 예제
#inclue <sys/socket.h>
#include <arph/inet.h>
int main(){
struct sockaddr_in client_addr, server_addr;
int ssock, csock;
int clen = sizeof(client_addr)
if((ssock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
perror("socket error");
exit(1);
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(7777);
if(bind(ssock, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0){
perror("bind error");
exit(1);
}
if(listen(ssock, 8) < 0 ){
perror("listen error");
exit(1);
}
while(1){
csock = accept(ssock, (struct sockaddr *) &client_addr, &clen);
write(ssock, "hello", 6);
close(csock);
}
return 0;
}
2. UDP
1) UDP
- User Datagram Protocol의 약어로 단방향 통신 프로토콜이다.
- 비연결지향형 프로토콜이다.
2) UDP 헤더 구조

- Source Port Number : 송신자 호스트의 포트 번호
- Destination Port Number : 수신자 호스트의 포트 번호
- Total Length : UDP Header와 Data 길이를 합한 바이트 수
- Checksum : 수신 데이터 오류 검사를 위한 체크섬
3) UDP 통신 절차도
- TCP와 유사하나 클라이언트의 connect 과정이 생략되며, 서버의 listen, accept 과정이 생략된다.

3. TFTP
1) TFTP
- Trival File Transfer Protocol의 약어로 FTP와 마찬가지로 파일을 전송하기 위한 프로토콜이지만, FTP보다 더 단순한 방식으로 파일을 전송
- UDP를 이용하여 작동한다.
- 임베디드 시스템 개발 시 개발 호스트와 타깃 보드 사이에 데이터를 전송할 때 사용한다.
2.4 개발 도구
1. 컴파일
1) 컴파일
- 인간이 이해할 수 있는 언어로 작성된 소스 코드를 CPU가 이해할 수 있는 언어로 번역(변환)하는 작업을 말한다
2) 컴파일 과정

- 전처리 : 소스코드의 주석 및 헤더파일 병합, 매크로를 치환함
- 컴파일러 : 오류처리, 코드 최적화 작업을 하며 어셈블리어로 변환
- 어셈블러 : 어셈블리어를 기계어 코드로 변환하는 도구
- 링커 : 기계어 코드를 하나로 묶고 필요 정보를 재배치
2. 컴파일 옵션
1) Gcc 컴파일러 컴파일 옵션
① -o : output 파일을 지정
② -I : 대문자 아이, 컴파일에 필요한 include 된 header 파일 위치 (디렉토리) 지정
③ -l : 소문자 엘, 컴파일에 필요한 라이브러리 파일 지정
④ -L : 컴파일에 필요한 라이브러리 디렉토리 지정
⑤ -D : 심볼에 대한 값을 지정. #define과 같은 기능
⑥ -c : .o로 오브젝트 파일을 생성
⑦ -O : 컴파일 최적화 단계 지정
# References
- https://wiki.kldp.org/KoreanDoc/html/EmbeddedKernel-KLDP/system-call-table.html
- http://www.ktword.co.kr/test/view/view.php?m_temp1=1889
- https://okky.kr/questions/1392134
- https://dahye-jeong.gitbook.io/til/network/2021-07-11-transport-layer
- https://nenunena.tistory.com/61
- https://blog.naver.com/ehdrhs1004/220336249951
- https://velog.io/@narangke3/%EC%BB%B4%ED%8C%8C%EC%9D%BC-%EA%B3%BC%EC%A0%95
'임베디드 기사 > 실기 - 임베디드 플랫폼' 카테고리의 다른 글
| 임베디드 플랫폼 실기 용어 정리 (0) | 2023.10.09 |
|---|---|
| 1. 임베디드 OS의 이해하기 (0) | 2023.09.26 |