리눅스 프로그램에서 시그널(인터럽트) 처리 방식이 아닌 쓰레드 방식의 타이머를 사용할 수 있다. 쓰레드 방식의 타이머를 사용할 경우, 타이머 만기 시에 해당 이벤트를 처리할 수 있는 쓰레드가 생성되므로, 해당 쓰레드(=타이머 만기 처리루틴) 내에서 뮤텍스 등 프로세스 컨텍스트에서만 허용되는 지연 발생 동작을 수행할 수 있다는 장점이 있다. 타이머를 생성하기 위해 timer_create() 호출 시, 인자로 전달하는 sigevent 구조체의 sigeve_notify 변수의 값을 SIGEV_THREAD로 설정함으로써 쓰레드 기반의 타이머를 사용할 수 있다. 이 경우 타이머 만기 시마다, sigevent 구조체의 sigeve_notify_function 변수에 연결된 쓰레드 함수를 수행하는 쓰레드가 생성되며,..
리눅스에서 타이머 파일 디스크립터를 이용하여 쓰레드 기반의 타이머 이벤트 처리 기능을 구현할 수 있다. 타이머에 대한 파일 디스크립터를 생성한 후, 해당 파일 디스크립터를 읽거나 폴링함으로써 타이머 이벤트를 획득하여 처리할 수 있다. 사용되는 함수는 timerfd_create(), timerfd_settime(), read()이다. 대략적인 절차는 다음과 같다. 1. timerfd_create() 함수를 호출하여 타이머 파일 디스크립터를 생성한다. 2. timerfd_settime() 함수를 호출하여 타이머 만기 주기를 설정한다. 3. 루프를 돌면서 read() 함수를 호출하여 타이머 이벤트를 처리한다. read() 함수 호출 시 블록되며, 타이머 만기 시점이 되면 리턴된다. 타이머를 설정할 때, 최초 ..
어플리케이션을 개발하다 보면, 어플리케이션의 실행을 반복하면서(실행과 종료를 반복) 테스트하고 싶은 경우가 있다. 리눅스에서 이러한 작업이 필요하여, 다음과 같은 두 개의 스크립트 파일을 만들어 테스트를 진행해 보았다. 어플리케이션 실행용 쉘 스크립트 : 주기적으로 어플리케이션이 실행 중인지 여부를 확인하여 실행 중이 아닐 경우 어플리케이션을 실행한다. 어플리케이션 종료용 쉘 스크립트 : 주기적으로 어플리케이션이 실행 중인지 여부를 확인하여 실행 중일 경우 어플리케이션을 종료한다. 어플리케이션 실행용 쉘 스크립트는 다음과 같이 만들었다. 루프를 돌면서 2초마다 my_app이라는 어플리케이션이 실행 중인지를 확인하여, 실행 중이 아니면 실행한다. #!/bin/sh while : do echo "Check ..
nanosleep()은 특정 시간 동안 프로세스/쓰레드를 재우는데(동작을 멈추는데) 사용된다. 개인적으로는 지금까지 마이크로초 단위의 함수인 usleep()을 많이 사용했는데(sleep() 함수가 초단위라서 너무 긴 경우에), 이번 기회에 nanosleep()으로 변경하게 되었다. 찾아보니, usleep() 대신 nanosleep()을 쓰는게 좋은 듯 하고 특히 nanosleep()은 POSIX 함수라고 한다. 인자로 단순히 마이크로초 단위의 시간값을 전달해 주는 usleep() 함수에 비해 nanosleep() 함수의 사용법이 아주 조금 더 복잡하긴 하지만, 사용하기 어려운 수준은 아닌 듯 하다. nanosleep()의 함수 원형은 다음과 같다. #include int nanosleep(const st..
보통 GNSS(GPS) 모듈은 1초에 한번씩 펄스 신호를 출력하는 핀을 가지고 있다. 해당 신호의 출력 시점은 UTC 절대시각과 매우 정밀하게 동기화되어 있기 때문에, 시스템에서는 해당 신호를 이용하여 시간 동기 등의 동작을 보다 정밀하게 수행할 수 있다. 일반적으로, GNSS 모듈을 사용하는 시스템은 GNSS 모듈의 PPS 신호 출력 핀을 프로세서(CPU 등)에 연결하여, PPS 신호 발생 시마다 해당 신호를 프로세서 상에서 동작하는 프로그램에서 사용할 수 있도록 구성한다. 시스템 운영체제가 리눅스일 경우, 리눅스 커널이 PPS 신호를 처리한 후 시스템 콜을 통해 어플리케이션 프로그램이 해당 신호의 발생시점을 받을 수 있도록 하는 Kernel PPS 기능을 제공된다. 따라서 어플리케이션 프로그램에서는 ..
개요 CURL 라이브러리는 URL 기반으로 데이터를 웹으로 전송하는 기능을 제공하는 라이브러리입니다. 웹으로 전송하기 위해 HTTP/TCP/IP 통신을 직접 구현할 수도 있지만, CURL 라이브러리를 사용하면 TCP/IP 소켓 제어 및 HTTP 통신을 직접 제어할 필요 없이 쉽게 수행할 수 있습니다. CURL 라이브러리의 공식 웹사이트는 아래와 같습니다. curl command line tool and library for transferring data with URLs (since 1998) Supports... DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, POP3, POP3S, RTMP, RT..
개요 TUN 과 TAP(Terminal Access Point) 은 가상 네트워크 커널 인터페이스입니다. 위키피디아(https://en.wikipedia.org/wiki/TUN/TAP)에 따르면, 운영체제가 TUN/TAP 디바이스로 전송한 패킷들은 해당 TUN/TAP 디바이스에 연결된 사용자공간 프로그램으로 전달되며, 사용자공간 프로그램이 TUN/TAP 디바이스로 전송한 패킷들은 운영체제 네트워크 스택으로 전달됩니다. TUN 디바이스는 IP 계층에서 이러한 역할을 수행하고, TAP 디바이스는 데이터링크 계층에서 이러한 역할을 수행합니다. 사용법 다음 명령으로 디바이스를 생성합니다. mkdir /dev/net (없을 경우) mknod /dev/net/tun c 10 200 다음 명령으로 디바이스 권한을 설..
개요 리눅스(및 대다수의 운영체제)에서는 시스템에서 함께 동작하는 다수의 어플리케이션 프로세스 간에 정보를 교환하도록 하기 위한 프로세스간 통신 (Inter Process Communication, IPC) 기법을 제공합니다. 본 글에서는 여러 IPC 기법 중 메시지큐를 이용하여 프로세스 간 정보 교환 기능을 구현하는 예제를 소개합니다. 메시지큐 기반 IPC 기법의 대략적인 구조 및 동작 절차는 다음과 같습니다. 임의의 프로세스에서 메시지큐를 생성합니다 - msgget() 시스템 함수 호출 그 외 프로세스에서는 해당 메시지큐를 엽니다 - msgget() 시스템 함수 호출 수신 프로세스에서는 메시지큐로부터 메시지를 수신합니다 - msgrcv() 시스템 함수 호출 송신 프로세스에서는 메시지큐로 메시지를 송신..
GPSd는 다양한 GNSS 모듈로부터 입력되는 각종 정보를 처리하는 오픈소스 데몬으로써, 처리된 GNSS 정보를 다수의 다른 어플리케이션들이 사용할 수 있도록 제공하는 기능을 지원한다. 본 글에서는 GPSd가 제공하는 GNSS 정보들을 획득하여 처리하는 어플리케이션 프로그램을 작성하는 방법에 대해 소개한다. GPSd 데몬을 빌드하고 사용하는 방법에 대해서는 아래 글에서 확인할 수 있다. 2020/01/30 - [개발/임베디드 리눅스] - GPS 모듈을 이용하여 시스템시각을 UTC 시간에 동기화하는 임베디드 장치 구성하기 장치 상에 GNSS 모듈이 내장되어 있고, GPSd 데몬이 GNSS 모듈로부터 입력되는 정보를 정상적으로 처리하는 상태가 되면, 동일한 장치에서 동작하는 다른 어플리케이션들에서는 GPSd..
리눅스 프로그래밍 - 프로세스 종료 신호(SIGINT, SIGTERM) 후킹하기 본 글에서는 리눅스 어플리케이션 프로세스의 종료 신호를 후킹하여 원하는 동작을 수행하도록 하는 방법에 대해 소개한다. 보통 루프를 도는 어플리케이션 프로세스의 경우 Ctrl + C를 입력하여 프로세스를 종료하거나(foreground에서 동작하는 경우), kill 명령을 이용하여 프로세스를 종료한다(background에서 동작하는 경우). Ctrl + C를 입력하거나 kill 명령을 이용하여 프로세스를 종료하고자 할 때, 프로세스가 종료되기 전에 특정 동작을 수행할 필요가 있는 경우가 있다. (예: 시스템에 생성해 놓은 공용 자원 해제, 다른 프로세스와의 정보 교환, 디바이스 드라이버의 상태 변경 등) 이 경우, Ctrl + ..
timer_settime() 타이머를 시작하거나 중지한다. 해당 함수의 원형은 다음과 같다. #include int timer_settime(timer_t timerid, int flags, const struct itimerspec *new_value, struct ittimerspec *old_value); timerid로 식별되는 타이머를 시작하거나 중지한다. timerid는 timer_create()를 통해 생성된 timer 식별자이다. 함수 호출자는 타이머 첫 만기 시점 및 반복주기를 new_value에 설정해야 한다. ittimerspec 구조체의 형식은 다음과 같다. struct timespec { time_t tv_sec; // 초값 long tv_nsec; // 나노초값 } struct ..
리눅스 네트워크 프로그래밍 - CAN(Controller Area Network) 통신 본 글에서는 차량 내부에서 사용되는 CAN(Controller Area Network) 통신을 수행하는 리눅스 어플리케이션 프로그램을 작성하는 방법을 설명한다. 환경은 다음과 같다. CAN 인터페이스에 대한 디바이스 드라이버 등은 BSP 레벨에서 이미 포팅이 되어 있다. CAN 네트워크에서 장치 간 공통으로 사용되는 baudrate 등 타이밍 관련 설정은 완료되어 있다. 어플리케이션 프로그램은 C 언어로 작성된다. CAN 인터페이스 초기화 C 언어로 작성된 어플리케이션 프로그램 상에서 CAN 인터페이스를 초기화하는 절차는 다음과 같다. socket() 함수로 CAN 인터페이스에 대한 소켓 파일 디스크립터를 연다 ioc..