1 系统功能
通过web界面,对灯光系统进行控制与管理,与传统灯光系统相比,具有一键设置、远程控制、定时等功能,更加智能、便于管理。
2 系统硬件
主控模块:Mini6410开发板(ARM11)
外围模块:继电器模块(控制LED)、光感模块、声控模块、人体红外模块、LED灯
3 管理界面展示
Web服务器通过调用CGI程序与浏览器进行交互,并通过消息队列与共享内存与主控程序进行交互。
设备管理界面:
设备控制界面:
4 驱动程序设计
光感模块驱动:
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#include<linux/module.h>
#include<linux/init.h>
#include<linux/fs.h>
#include<linux/kernel.h>
#include<linux/errno.h>
#include<linux/ioctl.h>
#include<linux/types.h>
#include<linux/poll.h>
#include<linux/moduleparam.h>
#include<linux/delay.h>
#include<linux/slab.h>
#include<linux/sched.h>
#include<linux/miscdevice.h>
#include<linux/clk.h>
#include<linux/io.h>
#include<linux/gpio.h>
#include<mach/hardware.h>
#include<mach/map.h>
#include<mach/regs-gpio.h>
#include<mach/gpio-bank-k.h>
#include<plat/gpio-cfg.h>
#include<asm/uaccess.h>
#include<asm/io.h>
#define DEVICE_NAME "project_2_light"
static ssize_t light_read(struct file* filp, char* buffer, size_t count, loff_t* ppos)
{
unsigned int tmp;
unsigned long err;
tmp = gpio_get_value(S3C64XX_GPE(1));
err = copy_to_user(buffer,&tmp,1);
return 1;
}
static struct file_operations light_fops = {
.read = light_read,
};
static struct miscdevice light_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &light_fops,
};
static int __init light_init(void)
{
int ret;
s3c_gpio_cfgpin(S3C64XX_GPE(1),S3C_GPIO_SFN(0));
s3c_gpio_setpull(S3C64XX_GPE(1),S3C_GPIO_PULL_DOWN);
ret = misc_register(&light_misc);
if(ret < 0)
{
return ret;
}
printk(KERN_ALERT"initialized!\n");
return ret;
}
static void __exit light_exit(void)
{
misc_deregister(&light_misc);
printk(KERN_ALERT"unloaded!\n");
}
module_init(light_init);
module_exit(light_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yumin");
继电器模块驱动:
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#include<linux/module.h>
#include<linux/init.h>
#include<linux/fs.h>
#include<linux/kernel.h>
#include<linux/errno.h>
#include<linux/types.h>
#include<linux/ioctl.h>
#include<linux/poll.h>
#include<linux/slab.h>
#include<linux/sched.h>
#include<linux/moduleparam.h>
#include<linux/uio.h>
#include<linux/delay.h>
#include<linux/device.h>
#include<linux/miscdevice.h>
#include<linux/gpio.h>
#include<mach/hardware.h>
#include<mach/map.h>
#include<mach/regs-gpio.h>
#include<mach/gpio-bank-k.h>
#include<plat/gpio-cfg.h>
#include<asm/io.h>
#include<asm/uaccess.h>
#define J1_GPIO S3C64XX_GPE(3)
#define J2_GPIO S3C64XX_GPE(4)
#define J1_ON 0x01
#define J1_OFF 0x00
#define J2_ON 0x11
#define J2_OFF 0x10
static char drv_buf[2];
static void update_relay(void)
{
switch(drv_buf[0])
{
case J1_ON:
gpio_set_value(J1_GPIO,1);
break;
case J1_OFF:
gpio_set_value(J1_GPIO,0);
break;
case J2_ON:
gpio_set_value(J2_GPIO,1);
break;
case J2_OFF:
gpio_set_value(J2_GPIO,0);
break;
default:
printk(KERN_ALERT"Bad input!\n");
break;
}
}
static ssize_t relay_write(struct file* filp, const char* buffer, size_t count, loff_t* ppos)
{
unsigned long err;
err = copy_from_user(drv_buf,buffer,1);
update_relay();
return 1;
}
static struct file_operations relay_fops = {
.write = relay_write,
};
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = "project_2_relay",
.fops = &relay_fops,
};
static int __init relay_init(void)
{
int result;
s3c_gpio_cfgpin(J1_GPIO,S3C_GPIO_SFN(1));
s3c_gpio_cfgpin(J2_GPIO,S3C_GPIO_SFN(1));
result = misc_register(&misc);
printk(KERN_ALERT"initialized!\n");
return result;
}
static void __exit relay_exit(void)
{
misc_deregister(&misc);
printk(KERN_ALERT"unloaded!\n");
}
module_init(relay_init);
module_exit(relay_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yumin");
声控模块驱动:
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#include<linux/module.h>
#include<linux/init.h>
#include<linux/fs.h>
#include<linux/kernel.h>
#include<linux/errno.h>
#include<linux/types.h>
#include<linux/ioctl.h>
#include<linux/poll.h>
#include<linux/slab.h>
#include<linux/sched.h>
#include<linux/moduleparam.h>
#include<linux/uio.h>
#include<linux/delay.h>
#include<linux/semaphore.h>
#include<linux/rwsem.h>
#include<linux/spinlock.h>
#include<linux/miscdevice.h>
#include<linux/interrupt.h>
#include<linux/irq.h>
#include<asm/irq.h>
#include<linux/gpio.h>
#include<mach/hardware.h>
#include<mach/map.h>
#include<mach/regs-gpio.h>
#include<mach/gpio-bank-k.h>
#include<mach/gpio-bank-n.h>
#include<mach/gpio-bank-l.h>
#include<plat/gpio-cfg.h>
#include<asm/uaccess.h>
#include<asm/io.h>
#define LGPIO S3C64XX_GPM(4)
static ssize_t sound_read(struct file* filp, char* buffer, size_t count, loff_t* ppos)
{
unsigned int tmp;
unsigned long err;
tmp = gpio_get_value(LGPIO);
err = copy_to_user(buffer,&tmp,1);
return 1;
}
static struct file_operations sound_fops = {
.read = sound_read,
};
static struct miscdevice sound_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = "project_2_sound",
.fops = &sound_fops,
};
static int __init sound_init(void)
{
int result;
s3c_gpio_cfgpin(LGPIO, S3C_GPIO_SFN(0));
s3c_gpio_setpull(LGPIO, S3C_GPIO_PULL_DOWN);
result = misc_register(&sound_misc);
if(result < 0)
{
printk(KERN_ALERT"misc_register() error\n");
return result;
}
printk(KERN_ALERT"initialized!\n");
return 0;
}
static void __exit sound_exit(void)
{
misc_deregister(&sound_misc);
printk(KERN_ALERT"unloaded!\n");
}
module_init(sound_init);
module_exit(sound_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yumin");
人体红外模块驱动:
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#include<linux/module.h>
#include<linux/init.h>
#include<linux/kernel.h>
#include<linux/fs.h>
#include<linux/errno.h>
#include<linux/types.h>
#include<linux/ioctl.h>
#include<linux/poll.h>
#include<linux/slab.h>
#include<linux/sched.h>
#include<linux/uio.h>
#include<linux/delay.h>
#include<linux/moduleparam.h>
#include<linux/miscdevice.h>
#include<linux/rwsem.h>
#include<linux/semaphore.h>
#include<linux/spinlock.h>
#include<linux/gpio.h>
#include<mach/hardware.h>
#include<mach/map.h>
#include<mach/regs-gpio.h>
#include<mach/gpio-bank-k.h>
#include<plat/gpio-cfg.h>
#include<asm/uaccess.h>
#include<asm/io.h>
#define LGPIO S3C64XX_GPM(5)
static ssize_t bodyinduction_read(struct file* filp, char* buffer, size_t count, loff_t* ppos)
{
unsigned int tmp;
unsigned long err;
tmp = gpio_get_value(LGPIO);
printk("===%d===\n",tmp);
err = copy_to_user(buffer,&tmp,1);
return 1;
}
static struct file_operations bodyinduction_fops = {
.read = bodyinduction_read,
};
static struct miscdevice misc = {
.name = "project_2_bodyinduction",
.fops = &bodyinduction_fops,
.minor = MISC_DYNAMIC_MINOR,
};
static int __init bodyinduction_init(void)
{
int result;
s3c_gpio_cfgpin(LGPIO,S3C_GPIO_SFN(0));
result = misc_register(&misc);
if(result < 0)
{
printk(KERN_ALERT"misc_register() error\n");
return result;
}
printk(KERN_ALERT"initialized!\n");
return 0;
}
static void __exit bodyinduction_exit(void)
{
misc_deregister(&misc);
printk(KERN_ALERT"unloaded!\n");
}
module_init(bodyinduction_init);
module_exit(bodyinduction_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yumin");
除了通过网页方式控制,通过按键中断也可以控制LED灯与各个感应器件的开关,按键驱动程序根据不同的按键产生的中断,向用户空间返回不同的值,控制程序根据返回的值进行相应操作,按键驱动程序如下:
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#include<linux/module.h>
#include<linux/init.h>
#include<linux/kernel.h>
#include<linux/fs.h>
#include<linux/errno.h>
#include<linux/types.h>
#include<linux/ioctl.h>
#include<linux/poll.h>
#include<linux/slab.h>
#include<linux/sched.h>
#include<linux/semaphore.h>
#include<linux/rwsem.h>
#include<linux/spinlock.h>
#include<linux/uio.h>
#include<linux/delay.h>
#include<linux/moduleparam.h>
#include<linux/miscdevice.h>
#include<linux/interrupt.h>
#include<linux/irq.h>
#include<asm/irq.h>
#include<linux/gpio.h>
#include<mach/hardware.h>
#include<mach/map.h>
#include<mach/regs-gpio.h>
#include<mach/gpio-bank-k.h>
#include<mach/gpio-bank-n.h>
#include<mach/gpio-bank-l.h>
#include<plat/gpio-cfg.h>
#include<asm/io.h>
#include<asm/uaccess.h>
struct button_irq_dec
{
int irq;
int number;
unsigned int pin;
char* name;
};
static struct button_irq_dec button_irqs[] = {
{IRQ_EINT(0),0,S3C64XX_GPN(0),"button0"},
{IRQ_EINT(1),1,S3C64XX_GPN(1),"button1"},
{IRQ_EINT(2),2,S3C64XX_GPN(2),"button2"},
{IRQ_EINT(3),3,S3C64XX_GPN(3),"button3"},
{IRQ_EINT(4),4,S3C64XX_GPN(4),"button4"},
};
static volatile int ev_press = 0;
static volatile char drv_buf[2] = {0,0};
static wait_queue_head_t button_waitq;
static irqreturn_t buttons_interrupt(int irq, void* dev_id)
{
struct button_irq_dec* pressed_button = (struct button_irq_dec*)dev_id;
int num = pressed_button->number;
drv_buf[0] = num;
ev_press = 1;
wake_up_interruptible(&button_waitq);
printk(KERN_ALERT"button %d clicked!\n",num + 1);
wake_up_interruptible(&button_waitq);
return IRQ_RETVAL(IRQ_HANDLED);
}
static ssize_t button_read(struct file* filp, char* buffer, size_t count, loff_t* ppos)
{
unsigned long err;
wait_event_interruptible(button_waitq,ev_press);
ev_press = 0;
err = copy_to_user(buffer,(void*)drv_buf,1);
printk(KERN_ALERT"user read from driver!\n");
return 1;
}
static int button_open(struct inode* inode, struct file* filp)
{
int i,err;
for(i = 0; i < 5; i++)
{
err = request_irq(button_irqs[i].irq,buttons_interrupt,IRQ_TYPE_EDGE_FALLING,button_irqs[i].name,(void*)&button_irqs[i]);
if(err != 0)
{
printk(KERN_ALERT"request irq %d error\n",button_irqs[i].irq);
}
}
printk(KERN_ALERT"6410 button init!\n");
return 0;
}
static int button_close(struct inode* inode, struct file* filp)
{
int i;
for(i = 0; i < 5; i++)
{
free_irq(button_irqs[i].irq,(void*)&button_irqs[i]);
}
printk(KERN_ALERT"6410 button exit!\n");
return 0;
}
static struct file_operations button_fops = {
.read = button_read,
.open = button_open,
.release = button_close,
.owner = THIS_MODULE,
};
static struct miscdevice button_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = "project_2_button",
.fops = &button_fops,
};
static int __init button_init(void)
{
int result;
if((result = misc_register(&button_misc)) < 0)
{
printk(KERN_ALERT"misc_register() error\n");
return result;
}
init_waitqueue_head(&button_waitq);
printk(KERN_ALERT"initialized!\n");
return 0;
}
static void __exit button_exit(void)
{
misc_deregister(&button_misc);
printk(KERN_ALERT"unload!\n");
}
module_init(button_init);
module_exit(button_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yumin");
按键控制程序如下:
#include<unistd.h>
#include<pthread.h>
#include<sys/types.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define J1_ON 0x01
#define J1_OFF 0x00
#define J2_ON 0x11
#define J2_OFF 0x10
#define BUTTON_FILE "/dev/project_2_button"
#define RELAY_FILE "/dev/project_2_relay"
#define RAY_FILE "/dev/project_2_light"
#define SOUND_FILE "/dev/project_2_sound"
#define BODYINDUCTION_FILE "/dev/project_2_bodyinduction"
static volatile int light_1_flag = 0;
static volatile int light_2_flag = 0;
static volatile int ray_flag = 0;
static volatile int sound_flag = 0;
static volatile int body_flag = 0;
static volatile int sound_response_flag = 0;
static volatile int body_response_flag = 0;
static int relay_fd;
void* button_pth(void* arg)
{
int button_fd = -1;
char button_buf;
char write_buf;
if((button_fd = open(BUTTON_FILE,O_RDONLY)) < 0)
{
printf("button file open error\n");
exit(EXIT_FAILURE);
}
while(1)
{
read(button_fd,&button_buf,1);
if(button_buf == 0)
{
if(light_1_flag == 0)
{
write_buf = J1_ON;
write(relay_fd,&write_buf,1);
light_1_flag = 1;
}
else
{
write_buf = J1_OFF;
write(relay_fd,&write_buf,1);
light_1_flag = 0;
}
}
if(button_buf == 1)
{
if(light_2_flag == 0)
{
write_buf = J2_ON;
write(relay_fd,&write_buf,1);
light_2_flag = 1;
}
else
{
write_buf = J2_OFF;
write(relay_fd,&write_buf,1);
light_2_flag = 0;
}
}
if(button_buf == 2)
{
if(ray_flag == 0)
{
ray_flag = 1;
printf("start ray!\n");
}
else
{
ray_flag = 0;
printf("stop ray!\n");
}
}
if(button_buf == 3)
{
if(sound_flag == 0)
{
sound_flag = 1;
printf("start sound!\n");
}
else
{
sound_flag = 0;
printf("stop sound!\n");
}
}
if(button_buf == 4)
{
if(body_flag == 0)
{
body_flag = 1;
printf("start body induction!\n");
}
else
{
body_flag = 0;
printf("stop body induction!\n");
}
}
}
}
void* body_pth(void* arg)
{
int body_fd = -1;
char body_buf;
char body_write_buf;
if((body_fd = open(BODYINDUCTION_FILE,O_RDONLY)) < 0)
{
printf("body file open error\n");
exit(EXIT_FAILURE);
}
while(1)
{
if(body_flag == 1)
{
read(body_fd, &body_buf, 1);
if(body_buf == 1)
{
body_response_flag = 1;
body_write_buf = J1_ON;
write(relay_fd, &body_write_buf, 1);
body_write_buf = J2_ON;
write(relay_fd, &body_write_buf,1);
sleep(5);
body_response_flag = 0;
if(light_1_flag == 0)
{
body_write_buf = J1_OFF;
write(relay_fd,&body_write_buf,1);
}
if(light_2_flag == 0)
{
body_write_buf = J2_OFF;
write(relay_fd,&body_write_buf,1);
}
}
}
sleep(1);
}
close(body_fd);
}
void* sound_pth(void* arg)
{
int sound_fd = -1;
char sound_buf;
char sound_write_buf;
if((sound_fd = open(SOUND_FILE,O_RDONLY)) < 0)
{
printf("open sound file error!\n");
exit(EXIT_FAILURE);
}
while(1)
{
if(sound_flag == 1)
{
read(sound_fd,&sound_buf,1);
if(sound_buf == 0)
{
sound_response_flag = 1;
sound_write_buf = J1_ON;
write(relay_fd, &sound_write_buf, 1);
sound_write_buf = J2_ON;
write(relay_fd, &sound_write_buf,1);
sleep(5);
sound_response_flag = 0;
if(light_1_flag == 0)
{
sound_write_buf = J1_OFF;
write(relay_fd,&sound_write_buf,1);
}
if(light_2_flag == 0)
{
sound_write_buf = J2_OFF;
write(relay_fd,&sound_write_buf,1);
}
}
}
usleep(30 * 1000);
}
close(sound_fd);
}
void* ray_pth(void* arg)
{
int ray_fd = -1;
char ray_buf;
char ray_write_buf;
if((ray_fd = open(RAY_FILE,O_RDONLY)) < 0)
{
printf("ray file open error\n");
exit(EXIT_FAILURE);
}
while(1)
{
if(ray_flag == 1)
{
read(ray_fd,&ray_buf,1);
if(ray_buf == 1)
{
if(light_1_flag == 0)
{
ray_write_buf = J1_ON;
write(relay_fd,&ray_write_buf,1);
}
if(light_2_flag == 0)
{
ray_write_buf = J2_ON;
write(relay_fd,&ray_write_buf,1);
}
}
else
{
if(light_1_flag == 0 && sound_response_flag != 1 && body_response_flag != 1)
{
ray_write_buf = J1_OFF;
write(relay_fd,&ray_write_buf,1);
}
if(light_2_flag == 0 && sound_response_flag != 1)
{
ray_write_buf = J2_OFF;
write(relay_fd,&ray_write_buf,1);
}
}
}
sleep(0.5);
}
close(ray_fd);
}
int main()
{
pthread_t but_p,ray_p,sound_p,body_p;
if((relay_fd = open(RELAY_FILE,O_WRONLY)) < 0)
{
printf("relay file open error\n");
exit(EXIT_FAILURE);
}
pthread_create(&but_p,NULL,button_pth,NULL);
pthread_create(&ray_p,NULL,ray_pth,NULL);
pthread_create(&sound_p,NULL,sound_pth,NULL);
pthread_create(&body_p,NULL,body_pth,NULL);
pthread_join(but_p,NULL);
pthread_join(ray_p,NULL);
pthread_join(sound_p,NULL);
pthread_join(body_p,NULL);
return 0;
}