최초 작성
./Makefile
, ./Makefile.inc
: cpp코드와 같이 컴파일 할 수 있도록 수정include Makefile.inc
DIRS = system \ ui \ web_server
DIRS = system \ ui \ web_server \ hal
BUILD_DIRS = ${DIRS}
SYSTEM = ./system
TARGET = toy_system
CC = gcc
CPP = g++
FILENAME = main
MAINo = $(FILENAME).o
@@ -16,12 +18,13 @@ MAINh = $(SYSTEM)/system_server.h $(UI)/gui.h $(UI)/input.h $(WEB_SERVER)/web_se
MAINf = -I$(SYSTEM) -I$(UI) -I$(WEB_SERVER) -c -g -o
DIROBJ = ./system/system_server.o ./ui/gui.o ./ui/input.o ./web_server/web_server.o
HALOBJ = ./hal/camera_HAL.o ./hal/ControlThread.o
$(TARGET): $(MAINo)
@ echo ${BUILD_DIRS}
@ for dir in ${BUILD_DIRS}; do (cd $${dir}; ${MAKE}); \
if test $$? -ne 0; then break; fi; done;
$(CC) -g -o $(TARGET) $(MAINo) $(DIROBJ)
$(CPP) -o $(TARGET) $(MAINo) $(DIROBJ) $(HALOBJ) $(CPPLIBS)
$(MAINo): $(MAINh) $(MAINc)
$(CC) $(MAINf) $(MAINo) $(MAINc)
-------------------------------------------------------------------------------------
PL_CFLAGS = -I../$(SYSTEM) -I../$(UI) -I../$(WEB_SERVER) -I../$(HAL) -g -o
PL_CPPFLAGS = -lpthread -lm -lrt
CPPLIBS = -lpthread -lm -lrt
SYSTEM = system
UI = ui
WEB_SERVER = web_server
HAL = hal
CC = gcc
CPP = g++
HEADERS = ../$(SYSTEM)/system_server.h\
../$(UI)/gui.h\
../$(UI)/input.h\
../$(WEB_SERVER)/web_server.h
../$(WEB_SERVER)/web_server.h\
../$(HAL)/ControlThread.h\
../$(HAL)/camera_HAL.h\
CPPINCLUDES = -l${SYSTEM} -l${UI} -l${WEB_SERVER} -l${HAL}
CFLAGS = ${IMPL_CFLAGS}
CFLAGS = ${PL_CFLAGS}
CPPFLAGS = ${CPPINCLUDESDIRS} -g -O0 -std=c++14
RM = rm -f
/hal/ControlThread.cpp
, ./hal/camera_HAL.cpp
: 카메라 객체와 카메라를 조작할 cpp 코드 #ifndef _CONTROL_THREAD_H_
#define _CONTROL_THREAD_H_
class ControlThread {
public:
ControlThread();
~ControlThread();
public:
// 사진 찍는 메소드
int takePicture();
private:
}; // class ControlThread
#endif /* _CONTROL_THREAD_H_ */
--------------------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <errno.h>
#include <iostream>
#include <cstdio>
#include <unistd.h>
#include "camera_HAL.h"
#include "ControlThread.h"
static ControlThread *control_thread;
using std::cout;
using std::endl;
int toy_camera_open(void)
{
cout << "toy_camera_open" << endl;
control_thread = new ControlThread();
if (control_thread == NULL) {
cout << "Memory allocation error!" << endl;
return -ENOMEM;
}
return 0;
}
int toy_camera_take_picture(void)
{
return control_thread->takePicture();
}
/hal/Makefile
: cpp코드를 컴파일하기 위한 makefileinclude ../Makefile.inc
FILENAME1 = ControlThread
FILENAME2 = camera_HAL
GEN_EXE1 = $(FILENAME1).o
GEN_EXE2 = $(FILENAME2).o
SRC1 = $(FILENAME1).cpp
SRC2 = $(FILENAME2).cpp
EXE = $(GEN_EXE1) $(GEN_EXE2)
all: $(EXE)
$(GEN_EXE1): $(HEADERS) $(SRC1)
$(CPP) -g $(CPPINCLUDES) $(CPPFLAGS) -c $(GEN_EXE1) $(SRC1)
$(GEN_EXE2): $(SRC2)
$(CPP) -g $(CPPINCLUDES) $(CPPFLAGS) -c $(GEN_EXE2) $(SRC2)
allgen : ${GEN_EXE}
clean:
${RM} ${EXE} *.o
/system/system_server.c
: cpp로 구현한 카메라 기능을 호출하고 일정 시간마다 시간을 출력하는 타이머 코드 추가#include <camera_HAL.h>
#include <bits/sigevent-consts.h>
pthread_mutex_t system_loop_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t system_loop_cond = PTHREAD_COND_INITIALIZER;
bool system_loop_exit = false; ///< true if main loop should exit
static int toy_timer = 0;
...
int system_server()
{
...
signal(SIGALRM, timer_expire_signal_handler);
...
if(pthread_mutex_lock(&system_loop_mutex) < 0){
perror("System server mutex lock error");
exit(0);
}
while (system_loop_exit == false) {
int result = pthread_cond_wait(&system_loop_cond, &system_loop_mutex);
if(result == ETIMEDOUT){
printf("System exit timed out!\n");
}
}
if(pthread_mutex_unlock(&system_loop_mutex) < 0){
perror("System server mutex unlock error");
exit(0);
}
while (system_loop_exit == false) {
sleep(1);
}
}
...
void timer_sighandler(){
static int timer = 0;
timer ++;
printf("System timer : %d sec\n", timer );
toy_timer ++;
signal_exit();
//printf("System timer : %d sec\n", timer );
}
...
void signal_exit(void)
{
if(pthread_mutex_lock(&system_loop_mutex) < 0){
perror("Signal exit mutex lock error");
exit(0);
}
system_loop_exit = true;
pthread_cond_signal(&system_loop_cond);
if(pthread_mutex_unlock(&system_loop_mutex) < 0){
perror("Signal exit mutex unlock error");
exit(0);
}
}
static void timer_expire_signal_handler()
{
toy_timer++;
signal_exit();
}
/ui/input.c
: 메시지를 번갈아가며 한 글자 씩 번갈아가며 출력하는 코드#define TOY_TOK_BUFSIZE 64
#define TOY_TOK_DELIM " \t\r\n\a"
#define TOY_BUFFSIZE 1024
#define MAX 30
#define NUMTHREAD 3 /* number of threads */
static pthread_mutex_t global_message_mutex = PTHREAD_MUTEX_INITIALIZER;
static char global_message[TOY_BUFFSIZE];
char buffer[TOY_BUFFSIZE];
int read_count = 0, write_count = 0;
int buflen;
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t empty = PTHREAD_COND_INITIALIZER;
int thread_id[NUMTHREAD] = {0, 1, 2};
int producer_count = 0, consumer_count = 0;
int toy_mutex(char **args);
char *builtin_str[] = {
"send",
"mu",
"sh",
"exit"
};
int (*builtin_func[]) (char **) = {
&toy_send,
&toy_mutex,
&toy_shell,
&toy_exit
};
int input()
{
...
int i;
pthread_t thread[NUMTHREAD];
pthread_mutex_lock(&global_message_mutex);
strcpy(global_message, "hello world!");
buflen = strlen(global_message);
pthread_mutex_unlock(&global_message_mutex);
pthread_create(&thread[0], NULL, (void *)toy_consumer, &thread_id[0]);
pthread_create(&thread[1], NULL, (void *)toy_producer, &thread_id[1]);
pthread_create(&thread[2], NULL, (void *)toy_producer, &thread_id[2]);
for (i = 0; i < NUMTHREAD; i++) {
pthread_join(thread[i], NULL);
}
...
}
int toy_mutex(char **args)
{
if (args[1] == NULL) {
return 1;
}
printf("save message: %s\n", args[1]);
pthread_mutex_lock(&global_message_mutex);
strcpy(global_message, args[1]);
pthread_mutex_unlock(&global_message_mutex);
return 1;
}
/* consumer & producer */
void *toy_consumer(int *id)
{
pthread_mutex_lock(&count_mutex);
while (consumer_count < MAX) {
pthread_cond_wait(&empty, &count_mutex);
// get from queue
printf(" 소비자[%d]: %c\n", *id, buffer[read_count]);
read_count = (read_count + 1) % TOY_BUFFSIZE;
fflush(stdout);
consumer_count++;
}
pthread_mutex_unlock(&count_mutex);
}
void *toy_producer(int *id)
{
while (producer_count < MAX) {
pthread_mutex_lock(&count_mutex);
strcpy(buffer, "");
buffer[write_count] = global_message[write_count % buflen];
// push at queue
printf("%d - 생산자[%d]: %c \n", producer_count, *id, buffer[write_count]);
fflush(stdout);
write_count = (write_count + 1) % TOY_BUFFSIZE;
producer_count++;
pthread_cond_signal(&empty);
pthread_mutex_unlock(&count_mutex);
sleep(rand() % 3);
}
}