/*
cc -o test1 test1.c -lwiringPi
*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#include <wiringPi.h>
// Define Senser Pin
#define SENSER 25
// rsp board pin:22
// Define LED Pin
#define LED
24 // rsp board pin:18
// Define Button Pin
#define BUTTON
23 // rsp board pin:16
// Define Timeout
#define WAITSEC
15 // タイムアウト時間
int semid;
int gpioid=0;
//排他処理開始(ロック開始)
//自分よりも先にロックされていた場合にはロック解除されるまでスリープします
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);
}
}
//センサーが反応したときの対応
void signal1(void){
gpioid=1;
unlock(semid);
}
//ボタンが押されたときの対応
void signal9(void){
gpioid=9;
unlock(semid);
}
int main(int argc, char **argv) {
int endFlag=1;
pid_t result_pid;
int status;
int process_count=0;
//セマフォを割り付けます
semid=semget(IPC_PRIVATE,1,0666);
if(semid==EOF){
printf("%s\n","semget ERR");
exit(1);
}
//セマフォに初期値を書き込みます
SemSetValue(semid,0,0);
if (wiringPiSetupGpio() == -1){
printf("wiringPiSetup init error\n");
exit(1);
}
pinMode(SENSER, INPUT);
pinMode(BUTTON, INPUT);
pinMode(LED, OUTPUT);
digitalWrite(LED,0);
//割り込みを設定します
wiringPiISR( SENSER, INT_EDGE_FALLING,
signal1 );
wiringPiISR( BUTTON, INT_EDGE_FALLING,
signal9 );
while(endFlag){
lock(semid); //
Wait Unlock
switch (gpioid)
{
case 0: // 子プロセス終了
process_count--;
if (process_count == 0) digitalWrite(LED,0);
break;
case 1: // センサからの入力あり
if (process_count == 0) digitalWrite(LED,1);
process_count++;
result_pid = fork();
if (result_pid == 0) { // 子プロセス開始
sleep(WAITSEC);
unlock(semid);
exit(0);
}
break;
case 9: // ボタンが押された
endFlag=0;
break;
default: //
break;
}
gpioid=0;
}
if (process_count != 0) { // 子プロセス終了待ち
waitpid(
result_pid,&status,0);
}
digitalWrite(LED,0);
//セマフォの削除
if((semctl(semid,0,IPC_RMID,0))==EOF){
printf("%s\n","semctl ERR");
exit(1);
}
exit(0);
} |