리눅스 프로그램에서 시그널(인터럽트) 처리 방식이 아닌 쓰레드 방식의 타이머를 사용할 수 있다. 쓰레드 방식의 타이머를 사용할 경우, 타이머 만기 시에 해당 이벤트를 처리할 수 있는 쓰레드가 생성되므로, 해당 쓰레드(=타이머 만기 처리루틴) 내에서 뮤텍스 등 프로세스 컨텍스트에서만 허용되는 지연 발생 동작을 수행할 수 있다는 장점이 있다. 타이머를 생성하기 위해 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..
__attribute__((visibility(""))) 매크로를 활용하면 라이브러리 내에 구현된 함수를 라이브러리 외부에서 호출할 수 있을지 여부를 결정할 수 있다. 라이브러리 내 함수를 구현할 때, 아래와 같이 __attribute__((visibility("default"))) 속성을 부여하면 해당 함수가 라이브러리 외부에 노출되어, 해당 함수를 라이브러리 외부에서 호출할 수 있다. 즉, 라이브러리를 링크하는 어플리케이션에서 해당 함수를 호출할 수 있다. void __attribute__((visibility("default"))) do_something() { ... } 반대로, 아래와 같이 __attribute__((visibility("hidden"))) 속성을 부여하면 해당 함수가 라이브러리..
보통 GNSS(GPS) 모듈은 1초에 한번씩 펄스 신호를 출력하는 핀을 가지고 있다. 해당 신호의 출력 시점은 UTC 절대시각과 매우 정밀하게 동기화되어 있기 때문에, 시스템에서는 해당 신호를 이용하여 시간 동기 등의 동작을 보다 정밀하게 수행할 수 있다. 일반적으로, GNSS 모듈을 사용하는 시스템은 GNSS 모듈의 PPS 신호 출력 핀을 프로세서(CPU 등)에 연결하여, PPS 신호 발생 시마다 해당 신호를 프로세서 상에서 동작하는 프로그램에서 사용할 수 있도록 구성한다. 시스템 운영체제가 리눅스일 경우, 리눅스 커널이 PPS 신호를 처리한 후 시스템 콜을 통해 어플리케이션 프로그램이 해당 신호의 발생시점을 받을 수 있도록 하는 Kernel PPS 기능을 제공된다. 따라서 어플리케이션 프로그램에서는 ..
현상 프로그램 빌드 시 다음과 같은 에러가 발생하는 경우가 있습니다. 이는 링크 에러로써, 각 mp_* 함수를 찾을 수 없다는 의미입니다. undefined reference to `mp_prime_is_prime' undefined reference to `mp_sqrmod' undefined reference to `mp_lcm' undefined reference to `mp_gcd' undefined reference to `mp_mod_d' undefined reference to `mp_toradix' undefined reference to `mp_set_int' undefined reference to `mp_get_int' undefined reference to `mp_get_int' ..
현상 프로그램 실행 중 다음과 같은 에러가 발생하며 프로그램이 종료되는 경우가 있습니다. free(): invalid size Aborted 원인 이는 메모리 관련 에러가 발생했음을 나타냅니다. 다음 중 하나의 문제일 수 있습니다. 할당되지 않은 메모리 포인터를 해제(free())하고자 하는 경우 이미 해제된 메모리 포인터를 다시 해제하고자 하는 경우 위와 같이 코드를 작성하지 않았음에도 이러한 현상이 발생하는 경우, 버퍼 오버플로우가 발생했거나 써서는 안 될 메모리에 무언가를 써서 heap corruption이 발생했을 수 있습니다. 해결 방안 디버거 등을 사용하여 에러 발생 시점에 프로그램이 무엇을 하고 있었는지 확인해 봅니다. 해당 시점에서 문제점을 찾지 못할 경우, 그보다 이전 시점 어딘가에서 문..
현상 프로그램 빌드 시 다음과 같은 에러가 발생하는 경우가 있습니다. 이는 링크 에러로써, log10f 함수를 찾을 수 없다는 의미입니다. undefined reference to log10f 해결 방법 "-lm" 옵션으로 math 라이브러리를 링크해 주면 해결됩니다.
개요 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..
OBJECT IDENTIFIER 데이터 유형은 0x06의 값을 갖는 Tag 값으로 시작되는 TLV 형태로 인코딩됩니다. Object Identifier(OID) 내에서 각 점으로 구분되는 각 정수(=노드)는 다음 규칙에 따라 인코딩됩니다. OID의 첫 두 노드는 1 바이트로 함께 인코딩됩니다. 첫번째 노드에 40을 곱한 값에 두번째 노드의 값을 더합니다. 127 이하의 노드 값은 1 바이트로 인코딩됩니다. 128 이상의 노드 값은 다수의 바이트로 인코딩됩니다. leftmost 바이트의 Bit 7이 1로 인코딩되며, 각 바이트의 Bit 0~6에 인코딩된 값이 포함됩니다. 다음은 인증서 요청(Certificate request) 메시지 내에 포함된 ClientId를 인코딩하는 예제입니다. 1.3.6.1.4...
개요 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 다음 명령으로 디바이스 권한을 설..