/* cc -o test7 test7.c -lwiringPi */ #include #include #include #include #include #include #include #include #include #include // Define Motion Sensor Pin #define MOTION 4 // rsp board pin:7 // Define Light Sensor Pin #define LIGHT 18 // rsp board pin:12 // Define Button Pin #define BUTTON 23 // rsp board pin:16 // Define LED Pin #define LED 25 // rsp board pin:22 // Define Timeout #define WAITSEC 60 // タイムアウト時間 // Define Hub Control Command #define PROG "/home/pi/hub-ctrl/hub-ctrl" // Define Hub Control Chip #define CHIP "Texas" // Define Hub Port #define PORT 4 int semid; int gpioid=0; //USB-HUBの情報取得 int GetHubInfo (char *cmdline, char *bus, char *device) { FILE *fp; char buf[256]; char *tok; int flag=0; if ( (fp=popen(cmdline,"r")) ==NULL) return(1); while(fgets(buf, sizeof(buf), fp) != NULL) { if (strncmp(buf,"Bus ",4) == 0) { tok=strtok( buf, " :" ); while( tok != NULL ){ if (flag == 1) { strcpy(bus,tok); flag=0; } if (flag == 2) { strcpy(device,tok); flag=0; } if (strcmp(tok,"Bus") == 0) flag=1; if (strcmp(tok,"Device") == 0) flag=2; tok = strtok( NULL, " :" ); /* 2回目以降 */ } } } pclose(fp); return(0); } //USB-HUBの電源ON int HubOn (char *bus, char *device, int port) { char buf[256]; struct stat st; if (stat(PROG,&st) != 0) return(1); sprintf(buf,"sudo %s -b %s -d %s -P %d -p 1",PROG,bus,device,port); return(system(buf)); } //USB-HUBの電源OFF int HubOff (char *bus, char *device, int port) { char buf[256]; struct stat st; if (stat(PROG,&st) != 0) return(1); sprintf(buf,"sudo %s -b %s -d %s -P %d -p 0",PROG,bus,device,port); return(system(buf)); } //排他処理開始(ロック開始) //自分よりも先にロックされていた場合にはロック解除されるまでスリープします 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; char cmdline[50]; char bus[10]; char device[10]; int ret; int ldata; sprintf(cmdline,"sudo lsusb -v | grep ^Bus | grep %s",CHIP); ret=GetHubInfo (cmdline, bus, device); //セマフォを割り付けます 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(MOTION, INPUT); pinMode(BUTTON, INPUT); pinMode(LED, OUTPUT); pinMode(LIGHT, INPUT); digitalWrite(LED, 1); HubOff (bus, device, PORT); //割り込みを設定します wiringPiISR( MOTION, 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) HubOff (bus, device, PORT); break; case 1: // センサからの入力あり ldata=digitalRead(LIGHT); if (ldata == 0) break; if (process_count == 0) HubOn (bus, device, PORT); 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); } HubOff (bus, device, PORT); //セマフォの削除 if((semctl(semid,0,IPC_RMID,0))==EOF){ printf("%s\n","semctl ERR"); exit(1); } digitalWrite(LED, 0); exit(0); }