/*
cc -o test7 test7.c -lwiringPi
*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#include <wiringPi.h>
// 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);
}
|