zoukankan      html  css  js  c++  java
  • 安防监控 —— 数据上行刷新与命令下发过程

    一、数据刷新

    在主框架中可以看到数据刷新线程:pthread_refrash.c

    略去出错处理,如下:

     1 #include "data_global.h"
     2 #include "sem.h"
     3 
     4 #define N 1024  //for share memory
     5 
     6 //外部声明键值与id
     7 extern int shmid;
     8 extern int msgid;
     9 extern int semid;
    10 
    11 extern key_t shm_key;
    12 extern key_t sem_key;
    13 extern key_t key; //msg_key
    14 
    15 //外部互斥体声明
    16 extern pthread_mutex_t mutex_client_request,
    17                 mutex_refresh,
    18                 ...
    19 //外部声明条件变量
    20 extern pthread_cond_t  cond_client_request,
    21                 cond_refresh,
    22                 ...
    23 
    24 //包含所有环境信息的结构体,在data_global.h中声明,
    25 //最终为makeru_zigbee_info与makeru_a9_info这两个结构体的组合
    26 extern struct env_info_client_addr  sm_all_env_info;
    27 
    28 //将所有环境信息结构体与home_id再次封装成一个结构体
    29  struct shm_addr
    30  {
    31     char shm_status;   //shm_status可以等于home_id,用来区分共享内存数据
    32     struct env_info_client_addr  sm_all_env_info;
    33 };
    34 struct shm_addr *shm_buf;
    35 
    36 //模拟数据刷新的函数
    37 int file_env_info_struct(struct env_info_client_addr  *rt_status,int home_id);
    38 
    39 /* shm复习:
    40  * 共享内存使用步骤:
    41  *    1 创建/打开共享内存 —— shmget
    42  *    2 映射共享内存,即把指定的共享内存映射到进程地址空间用于访问 —— shmat
    43  *    3 读写共享内存 —— 地址 = shmat
    44  *    4 撤销共享内存映射 —— shmdt
    45  *    5 删除共享内存对象 —— shmctl
    46 */
    47 
    48 void *pthread_refresh(void *arg)
    49 {
    50     //semaphore for access to resource limits
    51     //信号量+共享内存实现对资源的互斥操作
    52     
    53     //"/tmp"--路径,'i'--生成key的数字,范围1-255 ,返回值:key_t
    54     sem_key = ftok("/tmp",'i');
    55 
    56     //创建信号量,返回id
    57     semid = semget(sem_key,1,IPC_CREAT|IPC_EXCL|0666);
    58     
    59     init_sem (semid, 0, 1);
    60     
    61 
    62     //创建共享内存
    63     shm_key = ftok("/tmp",'i');
    64     shmid = shmget(shm_key,N,IPC_CREAT|IPC_EXCL|0666);
    65 
    66     //映射共享内存,为shm_buf指定共享内存
    67     shm_buf = (struct shm_addr *)shmat(shmid,NULL,0));
    68 
    69     //清空一下shm_buf
    70     bzero (shm_buf, sizeof (struct shm_addr));
    71     //
    72     while(1){
    73         sem_p(semid,0);  //P操作
    74         shm_buf->shm_status = 1;  //指定home1
    75         file_env_info_struct(&shm_buf->sm_all_env_info,shm_buf->shm_status);  //刷新数据到web
    76         sleep(1);
    77         sem_v(semid,0);  //V操作
    78     }
    79     
    80     
    81 int file_env_info_struct(struct env_info_client_addr *rt_status,int home_id)
    82 {
    83     int  env_info_size = sizeof(struct env_info_client_addr);
    84     printf("env_info_size = %d.
    ",env_info_size);
    85 
    86     rt_status->monitor_no[home_id].zigbee_info.temperature = 10.0;
    87         ...
    88     rt_status->monitor_no[home_id].zigbee_info.reserved[1]  = -0.01;
    89 
    90     rt_status->monitor_no[home_id].a9_info.adc  = 9.0;
    91     ...
    92     rt_status->monitor_no[home_id].a9_info.reserved[1]  = -0.01;
    93     
    94     return 0;
    95 }

    2、在CGI部分

    env1.c -- > env1.cgi

     1 #include <stdio.h>
     2 ...
     3 #include "cgic.h"
     4 #include "data_global.h"
     5 
     6 
     7 //包含环境信息的结构体
     8 struct shm_addr
     9 {
    10     char shm_status;
    11     struct env_info_client_addr  sm_all_env_info;
    12 };
    13 
    14 int cgiMain()
    15 {
    16     key_t key;
    17     int shmid,semid;
    18     struct shm_addr *shm_buf;
    19 
    20     //key就相当于文件名,/tmp为其路径
    21     key = ftok("/tmp",'i');
    22     
    23     //创建信号量
    24     semid  = semget(key, 1, 0666);
    25     
    26     //映射shm,并让shm_buf指向shm
    27     shm_buf = (struct shm_addr*)shmat(shmid, NULL, 0);
    28 
    29     //信号量:P操作
    30     sem_p(semid,0);
    31 
    32     //CGI接口规范
    33     //CGI即通用网关接口,就是处理HTML网页端数据与服务器端的接口
    34     //使服务器和网页端能互相识别处理彼此的数据
    35     if (shm_buf->shm_status == 1)
    36     {
    37         //最终会在网页端打印以下信息
    38         fprintf(cgiOut, "<h4>Temperature:	%0.2f</H4>
     ", shm_buf->sm_all_env_info.monitor_no[shm_buf->shm_status].zigbee_info.temperature );
    39         ...
    40         fprintf(cgiOut, "<h4>A9数据显示部分</H4>
     ");
    41         fprintf(cgiOut, "<h4>Adc:	%0.2f</H4>
     ", shm_buf->sm_all_env_info.monitor_no[shm_buf->shm_status].a9_info.adc);
    42         ...
    43         fprintf(cgiOut, "<h4>A9-RESERVED[1]:	%d</H4>
     ", shm_buf->sm_all_env_info.monitor_no[shm_buf->shm_status].a9_info.reserved[1]);
    44 
    45         fprintf(cgiOut, "<h4>......</H4>
     ");
    46     }
    47     else
    48     {
    49     }
    50     //信号量:V操作
    51     sem_v (semid, 0);
    52     return 0;
    53 }

    3、网页端

    env1.html

     1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     2 <html xmlns="http://www.w3.org/1999/xhtml">
     3 
     4     <head>
     5         <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
     6         <title>仓库一环境信息</title>
     7     </head>
     8 
     9     <body>
    10 
    11         <body background="./images/huaqing002.jpg">
    12             </div>
    13             <table width="1080" border="0" height="200" background="./images/huaqing2.jpg" align="center">
    14                 <tr>
    15                     <td>&nbsp;</td>
    16                     <td>&nbsp;</td>
    17                 </tr>
    18             </table>
    19             <table width="1080" border="1" align="center">
    20                 <tr>
    21                     <td width="556">
    22                         <div align="center">
    23                             <h3>环境信息</h3></div>
    24                     </td>
    25                     <td width="500">
    26                         <div align="center">
    27                             <a href="home1.html">
    28                                 <h3>回主页</h3></a>
    29                         </div>
    30                     </td>
    31                 </tr>
    32             </table>
    33             <table width="1080" height="511" border="1" align="center">
    34                 <tr>
    35                     <td width="283" height="500" background="./images/zigee.jpg" align="left"></td>
    36                     <td width="432"><iframe src="cgi-bin/env1.cgi" height="500" width="518" align="middle"></iframe></td>
    37                     <td width="283" background="./images/gprs.jpg" align="right"></td>
    38                 </tr>
    39             </table>
    40         </body>
    41 
    42 </html>

    在第36行,网页端会调用到服务器端的cgi-bin目录下的env1.cgi文件进行数据的刷新与显示,

    效果如下:

     服务器端下的目录结构:

    二、web端命令下发

    从上往下分析

       在html端通过action,将对应的控制指令交给xxxx.cgi,在CGI进程中,对数据进行解析,将数据填充进消息,在将消息发送给消息队列,

     给主线程中的接收用户请求线程,获取消息队列里的消息,进而将指令分发给不同的主线程。

    以led为例:

    在网页查看控制部分的源码:

     1 <table width="400" height="270" align="center" border="3" bordercolor="red">
     2             <td height="60">
     3                 <div align="center">
     4                     <form id="form1" name="form1" method="post" action="cgi-bin/a9_led.cgi">
     5                         <div class="strip1">
     6                             <input type="hidden" name="store" id="hiddenField" value="1" /> Led:
     7                             <label>
     8                 <input type="radio" name="led" value="1" id="led_0" />
     9                 on</label>
    10 
    11                             <label>
    12                 <input type="radio" name="led" value="0" id="led_1" />
    13                 off</label>
    14                             <input type="submit" name="button" id="button" value="确定" />
    15                         </div>
    16                     </form>
    17                 </div>
    18             </td>
    19             </tr>
    20             <tr>

    由4四行,去查看a9_led.c

     1 #include <stdio.h> 
     2 #include "cgic.h" 
     3     ...    
     4 #include <sys/msg.h>
     5 
     6 #define N 8
     7 
     8 struct msg
     9 {
    10     long type;
    11     long msgtype;
    12     unsigned char text[N];
    13 };
    14 
    15 
    16 int cgiMain() 
    17 { 
    18     key_t key;
    19     char buf[N];
    20     char sto_no[2];
    21     int msgid;
    22     struct msg msg_buf;
    23     memset(&msg_buf,0,sizeof(msg_buf));
    24     
    25     cgiFormString("led",buf,N);
    26     cgiFormString("store",sto_no,2);
    27 
    28     key = ftok("/tmp", 'g');
    29 
    30     msgid = msgget(key, 0666);
    31 
    32     bzero (msg_buf.text, sizeof (msg_buf.text));
    33 
    34     if (buf[0] == '1')
    35     {    //构造命令,并填充结构体
    36         msg_buf.text[0] = ((sto_no[0] - 48)) << 6 | (0x0 << 4) | (1 << 0);
    37     }
    38     else
    39     {
    40         msg_buf.text[0] = ((sto_no[0] - 48)) << 6 | (0x0 << 4) | (0 << 0);
    41     }
    42     
    43     //填充结构体
    44     msg_buf.type = 1L;
    45     msg_buf.msgtype = 1L;  //具体的消息类型 === 指代控制的设备,如1L->LED
    46     msgsnd(msgid, &msg_buf,sizeof(msg_buf)-sizeof(long),0);
    47 
    48     sto_no[0] -= 48;
    49 
    50     cgiHeaderContentType("text/html
    
    "); 
    51     fprintf(cgiOut, "<HTML><HEAD>
    "); 
    52     fprintf(cgiOut, "<TITLE>My CGI</TITLE></HEAD>
    "); 
    53     fprintf(cgiOut, "<BODY>"); 
    54 
    55     fprintf(cgiOut, "<H2>send sucess</H2>");
    56 
    57     //fprintf(cgiOut, "<a href='.html'>返回</a>"); 
    58     fprintf(cgiOut, "<meta http-equiv="refresh" content="1;url=../a9_zigbee%d.html">", sto_no[0]);
    59     fprintf(cgiOut, "</BODY>
    "); 
    60     fprintf(cgiOut, "</HTML>
    "); 
    61 
    62     return 0; 
    63 } 

    在A9主线程中的接收用户请求线程获取消息队列中的消息,进而判断并分发给不同子线程

     1 #include "data_global.h"
     2 
     3 extern int msgid;
     4 extern key_t key;
     5 
     6 extern pthread_mutex_t mutex_client_request,
     7                 mutex_refresh,
     8                 ...
     9                  mutex_led,
    10 
    11 extern pthread_cond_t  cond_client_request,
    12                 cond_refresh,
    13                 ...
    14                  cond_led;
    15 
    16 
    17 struct msg msgbuf;
    18 
    19 
    20 void *pthread_client_request(void *arg)
    21 {
    22     key = ftok("/tmp",'g')) < 0);
    23 
    24     msgid = msgget(key,IPC_CREAT|IPC_EXCL|0666);
    25 
    26     while(1){
    27         bzero(&msgbuf,sizeof(msgbuf));
    28             printf("wait form client request...
    ");
    29         //从消息队列接收消息
    30         msgrcv (msgid, &msgbuf, sizeof (msgbuf) - sizeof (long), 1L, 0);
    31         printf ("Get %ldL msg
    ", msgbuf.msgtype);
    32         printf ("text[0] = %#x
    ", msgbuf.text[0]);
    33         
    34         //对消息进行判断进而去调用不同的线程处理
    35         switch(msgbuf.msgtype){
    36             case 1L:
    37                     printf("hello led
    ");
    38                 break;
    39             case 2L:
    40                     printf("hello beep
    ");
    41                 break;
    42             case 3L:
    43                     printf("hello seg
    ");
    44                 break;
    45             case 4L:
    46                     printf("hello fan
    ");
    47                 break;
    48             case 5L:
    49                     printf("set env data
    ");
    50                     printf("temMAX: %d
    ",*((int *)&msgbuf.text[1]));
    51                     ...
    52                     printf("illMAX: %d
    ",*((int *)&msgbuf.text[21]));
    53 
    54                 break;
    55             case ...
    56             case 10L:
    57             default:
    58                 break;
    59                 
    60         }
    61     }
    62 
    63 }
    64 
    65 #if 0
    66 
    67         long msgtype;//具体的消息类型
    68         消息类型的分配:
    69             1L:         LED控制
    70             2L:            蜂鸣器控制
    71             3L:            四路LED灯模拟的数码管
    72             4L:            风扇
    73             5L:            温湿度最值设置
    74             6L-7L-8L-9L,用于个人的扩展
    75             10L:         3G通信模块-GPRS 
    76         switch(msgbuf.msgtype){
    77             case 1L: ...  break;
    78             ....
    79             default ....  break;
    80         }
    81 #endif 

    测试结果:

            

  • 相关阅读:
    solr 的全量更新与增量更新
    solr 服务器的搭建
    Mysql 问题
    App 微信支付
    App 支付宝支付
    Linux 常见命令
    [备注] 钉钉使用教程
    PARAMETER和ARGUMENT的区别
    无界面浏览器
    URLs ...
  • 原文地址:https://www.cnblogs.com/y4247464/p/12527232.html
Copyright © 2011-2022 走看看