智能家居网络系统设计(四)

上一篇文章我们刚好可以登录用户了,如果登录成功就是调用main.cgi这个java脚本在这一小节中我们就来学习main.c这个文件。

在这里我得强调一下,在网页中控制开发板上的开设,这个项目在所有开发板上基本通用,只是你的外设驱动程序不一样吧了,这里我写出我开发板上led驱动程序,如果你在网页上想显示温度,气体浓度,这需要加相应传感器和驱动就可以了,不同内核有可能用函数或者宏不一样,自己做相应的修改就好了。

led_drv.c驱动程序:(既然你都开始做项目了,我相信这个驱动程序应该难不倒你吧)

#include <linux/module.h>  
#include <linux/kernel.h>  
#include <linux/fs.h>  
#include <linux/init.h>  
#include <linux/device.h>  
#include <linux/miscdevice.h>  
#include <linux/delay.h>  
#include <asm/irq.h>  
#include <asm/io.h>  
#include <asm/uaccess.h>  
#include <mach/regs-gpio.h>  
#include <mach/hardware.h>  
#include <linux/device.h>  
#include <linux/gpio.h>  
  
#define DEVICE_NAME "led1"  

static struct class led_1;   / 定义一个;类,用来自动创建设备节点 */

static unsigned long led_table [] = {  
S3C2410_GPB5,  
S3C2410_GPB6,  
S3C2410_GPB8,  
S3C2410_GPB10,  
};  
static unsigned int led_cfg_table [] = {  
S3C2410_GPB5_OUTP, //0x01<<10 defined in refg-gpio.h  
S3C2410_GPB6_OUTP,  
S3C2410_GPB8_OUTP,  
S3C2410_GPB10_OUTP,  
};  
static int s3c2440_leds_ioctl( struct inode *inode, struct file *file,unsigned int cmd,unsigned long arg)  
{  
switch(cmd) {  
case 0:  
case 1:  
   if (arg > 4)   
   {  
   return -EINVAL;  
   }  
s3c2410_gpio_setpin(led_table[arg], !cmd);  
return 0;  
default:  
return -EINVAL;  
}  
}  
  
static struct file_operations s3c2440_leds_fops = {  
.owner = THIS_MODULE,  
.ioctl = s3c2440_leds_ioctl,  
};  
  
static int major;  
static int __init s3c2440_leds_init(void)  
{  
  int i;  
 major= register_chrdev(0, DEVICE_NAME, &s3c2440_leds_fops);  /* 自动分配主设备号 */  
  led_1 = class_create(THIS_MODULE, DEVICE_NAME);               /* 创建一个类 */  
device_create(led_1, NULL, MKDEV(major, 0), NULL, "led");/* 在类下面创建一个设备节点,名字为led,应用程序就可以调用open("/dev/led", O_RDWR来访问驱动程序。 */  
  
  
for (i = 0; i < 4 ; i++)   
{  
s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);//设置输出输入  
s3c2410_gpio_setpin(led_table[i], 1);  
}  
  
printk(DEVICE_NAME " initialized
");  
return 0;  
}  
static void __exit s3c2440_leds_exit(void)  
{  
unregister_chrdev(major, DEVICE_NAME);        /* 取消注册 */  
device_destroy(led_1,MKDEV(major, 0));            /* 删除类下面的设备节点 */  
class_destroy(led_1);/* 删除类 */  
}  
module_init(s3c2440_leds_init);  
module_exit(s3c2440_leds_exit);  
MODULE_LICENSE("Dual BSD/GPL");  

上面是我led驱动程序,在main.cgi中会用到。下面我们来看看main.c怎么编写的。

main.c文件:

#include<string.h>  
#include <stdio.h>  
#include <stdlib.h>  
#include<fcntl.h>  
  
void config(int *led_config,int led_num);          /* led配置文件 */  
void led_fun(int *led_config);/*调用led驱动函数*/  
  
int main()  
{  
int led_num=0;  
int led_config[4]={0,0,0,0};  
FILE *fp_html;  
char buf[512]="";  
char *len;  
printf("%s

","Content-Type:text/html");  
len = getenv("CONTENT_LENGTH");  
if(len != NULL)  
{   
unsigned int content_len = 0;  
char *data;  
content_len = atoi(len);  
data = malloc(content_len + 1);  
read(0, data, content_len);  
sscanf(data,"led%d",&led_num);   /* 把那个led状态改变读出来 */  
free(data);  
}  
else   
{  
led_num=0;  
}  
config(led_config,led_num);  
  
led_fun(led_config);  
if( (fp_html=fopen("main_html","r")) == NULL)   /*这里注意,我们不能再写一个html网页,只能通过printf来打印一个网页,为了方便,我们把这个网页读取出来放在一个数组中,在用printf来打印,这个网页是我们用来人机控制界面,开始我们设置了一个用户登录界面*/  
{  
exit(1);  
}  
while(fgets(buf,512,fp_html))  
{  
  
if(strncmp(buf,"$FLAG4$",7)==0)  /* 这里用到一个变量 */  
{  
int i=0;  
for(i=0; i < 4; i++)  
{  
if(led_config[i]==0)  
{  
printf("<img src="../www/image/off.jpg" width=30 height=30 hspace=45 >");/* 图片的切换 */  
}  
else   
{  
printf("<img src="../www/image/on.jpg" width=30 height=30 hspace=45 >");  
}  
}  
}  
  
  
else   
printf("%s",buf);  
}  
return 0;  
}  
  
  
void config(int *led_config,int led_num)  
{  
FILE *fp;  
if((fp=fopen("config.ini","r+"))==NULL)  /*这里很重要,开始我实现这个功能的时候,总是不成功,后来找到原因了,当我们点击网页上的按钮时候,这个脚本就会重新刷新一次,从开始重新执行,我们的led状态就会恢复初值,后来才想到一个办法,把led的状态保存在一个配置文件config.ini中,*/  
{  
printf("<p>fopen Error!<a href="/cgi-bin/main.cgi">Return/a>");  
exit(1);  
}  
fscanf(fp,"led1=%d,led2=%d,led3=%d,led4=%d",led_config,led_config+1,led_config+2,led_config+3);

/* fscanf是把配置文件的状态读取出来,来控制led */  
  
if(led_num > 0)  
{  
if(led_config[led_num-1]==1)  
{  
led_config[led_num-1] = 0;  
}  
else   
{  
led_config[led_num-1] = 1;  
}  
fseek(fp,7*(led_num-1)+5,SEEK_SET);  
fprintf(fp,"%d",led_config[led_num-1]);  /* 把改变的状态重新存放在配置文件,注意看文件句柄fp */  
}  
fclose(fp);  
}  
  
void led_fun(int *led_config)  
{  
unsigned int led_num = 0;  
int led_fd = open("/dev/led", O_RDWR);   /* 打开驱动程序 */  
  
for (led_num = 0; led_num < 4; led_num++)    /*传入我们的led配置文件*/  
{  
ioctl(led_fd, led_config[led_num], led_num);  
}  
close(led_fd);  
}  

下一篇文章中将写出led配置文件,main_html网页文件源代码。

文章导航