#include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/sem.h> #include <string.h> #include <time.h> #include <signal.h> #include <wiringPi.h> // Define Button Pin #define button1 14 // rsp board pin:8 #define button2 15 // rsp board pin:10 #define DEBUG 0 int semid; int gpioid=0; int inProc; //排他処理の開始するためのロック //自分よりも先にロックされていた場合にはロック解除されるまでスリープします void lock(int semid){ struct sembuf sb[1]; sb[0].sem_num=0; sb[0].sem_op=-1; sb[0].sem_flg=0; if(EOF==semop(semid,sb,1)){ printf("%s\n","lock ERR"); exit(1); } } //排他処理の終了のためのロック解除 void unlock(int semid){ struct sembuf sb[1]; sb[0].sem_num=0; sb[0].sem_op=1; sb[0].sem_flg=0; if(EOF==semop(semid,sb,1)){ printf("%s\n","unlock ERR"); exit(1); } } //セマフォ値のセット void SemSetValue(int semid, int semnum, int semval) { union semun { int val; /* SETVAL の値 */ struct semid_ds *buf; /* IPC_STAT, IPC_SET 用のバッファ */ unsigned short *array; /* GETALL, SETALL 用の配列 */ } ctl_arg; ctl_arg.val = semval; if((semctl(semid,semnum,SETVAL,ctl_arg))==EOF){ printf("%s\n","semctl ERR"); exit(1); } } //ボタン1が押されたときの対応 void signal1(void){ if(inProc == 0) { gpioid=1; unlock(semid); } } //ボタン2が押されたときの対応 void signal2(void){ if(inProc == 0) { gpioid=2; unlock(semid); } } int main(int argc, char **argv) { int EndFlag=1; pid_t result_pid1; pid_t result_pid2; int kill_status; int wait_status; time_t now; struct tm *pnow; int sem_value1=0; int sem_value2=0; //セマフォを割り付けます semid=semget(IPC_PRIVATE,3,0666); if(semid==EOF){ printf("%s\n","semget ERR"); exit(1); } //セマフォに初期値を書き込みます SemSetValue(semid,0,1); result_pid1 = fork(); if (result_pid1 == 0) { // 子プロセス1開始 // // 1秒毎にセマフォをunlockする while (1) { sleep(1); SemSetValue(semid,1,1); unlock(semid); } } result_pid2 = fork(); if (result_pid2 == 0) { // 子プロセス2開始 // // 5秒毎にセマフォをunlockする while (1) { sleep(5); SemSetValue(semid,2,1); unlock(semid); } } if (wiringPiSetupGpio() == -1){ printf("wiringPiSetup init error\n"); exit(1); } if(button1) pinMode(button1, INPUT); if(button2) pinMode(button2, INPUT); if(button1) pullUpDnControl(button1, PUD_DOWN); if(button2) pullUpDnControl(button2, PUD_DOWN); if(button1) wiringPiISR( button1, INT_EDGE_FALLING, signal1 ); if(button2) wiringPiISR( button2, INT_EDGE_FALLING, signal2 ); while(EndFlag){ inProc=0; lock(semid); // Wait Unlock inProc=1; switch (gpioid) { case 0: // 子プロセスのタイムアウト sem_value1 = semctl(semid, 1, GETVAL, 0); sem_value2 = semctl(semid, 2, GETVAL, 0); if(sem_value1 == 1) { now = time(NULL); pnow = localtime(&now); printf("%02d:%02d:%02d\n",pnow->tm_hour,pnow->tm_min,pnow->tm_sec); SemSetValue(semid,1,0); } if(sem_value2 == 1) { now = time(NULL); pnow = localtime(&now); printf("%s",asctime(pnow)); SemSetValue(semid,2,0); } break; case 1: // ボタン1が押された printf("Button %d Push!!\n",gpioid); break; case 2: // ボタン2が押された printf("Button %d Push!!\n",gpioid); EndFlag=0; break; default: break; } gpioid=0; } //子プロセスをKILL kill_status = kill( result_pid1, SIGKILL ); wait(&wait_status); kill_status = kill( result_pid2, SIGKILL ); wait(&wait_status); //セマフォの削除 if((semctl(semid,0,IPC_RMID,0))==EOF){ printf("%s\n","ERR"); exit(1); } exit(0); } |
$ cc -o Sample4 Sample4.c -lwiringPi -lwiringPiDev |
$ sudo ./Sample4 11:17:29 11:17:30 11:17:31 11:17:32 Sun Aug 10 11:17:33 2014 11:17:33 11:17:34 11:17:35 11:17:36 11:17:37 Sun Aug 10 11:17:38 2014 11:17:38 11:17:39 11:17:40 Button 1 Push!! → ボタン1が押された 11:17:41 11:17:42 Sun Aug 10 11:17:43 2014 11:17:43 11:17:44 11:17:45 Button 2 Push!! → ボタン2が押された $ |