20155110王一帆 《远程安防监控系统》课程设计个人报告

一、个人所做的工作

  1. 编译linux内核,制作文件系统镜像
  2. 交叉编译项目代码
  3. 配合组长完成SD卡的烧写
  4. 调试运行开发板的各项功能

二、遇到的问题的及解决方法

问题1:fastboot的驱动安装

首先,我们在设备管理器中找到Android设备

但是安装fastboot驱动时,却失败了。

问题1的解决方法

在windows设置中找到“更新与安全”

找到恢复,在高级启动中找到“立即重启”

重启之后,选择“疑难解答”

接着选择“高级选项”

然后选择“启动设置”

重启以后,按下数字键“7”禁用驱动的强制签名

之后,我们就可以成功安装驱动了。

我们这时再观察设备管理器,我们就可以发现Android设备从未知变成已知了。

问题2:open /dev/ttyUSB0 error: No such file or directory

在进行串口通讯的时候,打开开发板后,一直会提示这样的消息。

原因是/dev目录下没有ttyUSB0这个设备文件。

问题2的解决方法

事实上,我们依旧可以输入linux命令的,要想不看到这个信息,需要在/dev下建立一个软链接。

输入ln -s /dev/null /dev/ttyUSB0,用“空设备”做个软链接。

这样就不会一直出现open /dev/ttyUSB0 error: No such file or directory这样的提示了

而且这样做不会影响正常的操作。

三、剖析CGI源码时的疑问与解答

我自己有过Web编程的经验,也了解早期的Web编程是靠CGI来完成的,用的语言也是五花八门——C/C++、perl、bash……

我选择研究该项目的CGI源码,也是因为自己对Web编程有一些了解,而对系统编程就完全不懂,也搞不清什么线程、锁、同步的概念。

(一)登录表单处理——login.cgi

我们进入文件系统rootfs的www目录下,这里就是存放web服务器html,css,js和cgi程序的地方。我们先看看index.html.

我们直接看登录的表单部分

<form name="form1" method="post"  action="cgi-bin/login.cgi"><table width="100%" border="0" cellspacing="9" cellpadding="0"><tbody><tr><td width="92">用户帐号:</td><td width="130"><label><input name="username" type="text" id="username" value="user"></label></td></tr><tr><td>登录密码:</td><td><label><input name="password" type="password" id="password" value="123456"></label></td></tr><tr><td height="25"></td><td><input type="image" name="submit" style="width:97px;height:25px;" src="data:images/login/go.gif"></td></tr></tbody> </table>
</form>

这个表单的数据会提交给login.cgi这个程序去处理。学过java servlet的同学会发现,CGI程序和servlet比较接近。

我们来分析一下login.cgi的源码。

//login.ccgiFormStringNoNewlines("username", name, N);
cgiFormStringNoNewlines("password", pw, N);

这两条语句将username和password分别放到char数组name和pw中,接下来肯定是要到数据库里面去查询了。这里的数据库用的是sqlite,非常轻量级的一个数据库。

//login.cif(sqlite3_open("/user.db", &db) != SQLITE_OK)
{fprintf(cgiOut, "<BODY>");fprintf(cgiOut, "<H1>%s</H1>", "Server is busy...");        fprintf(cgiOut, "<meta http-equiv=\"refresh\" content=\"1;url=../index.html\">");return -1;
}sprintf(sql, "select * from usr where name='%s' and password='%s'", name, pw);if(sqlite3_get_table(db, sql, &result, &row, &column, NULL) != SQLITE_OK)
{fprintf(cgiOut, "<BODY>");fprintf(cgiOut, "<H1>%s</H1>", "Server is busy...");        fprintf(cgiOut, "<meta http-equiv=\"refresh\" content=\"1;url=../index.html\">");sqlite3_close(db);return -1;
}

非常容易理解,sqlite3_open()函数用来打开数据user.db,如果打开失败就会看到网页上有Server is busy...字样。

char数组sql中存放了一条select语句,sqlite3_get_table()函数就是用来查询的,如果数据库出现问题,依然在网页上显示有Server is busy...

如果在数据库里找不到对应的用户,变量row的值就是0,网页上显示Name or password error

//login.cif(row == 0)
{fprintf(cgiOut, "<BODY>");fprintf(cgiOut, "<H1>%s</H1>", "Name or password error");       fprintf(cgiOut, "<meta http-equiv=\"refresh\" content=\"1;url=../index.html\">");sqlite3_close(db);return 0;
}

查看user.db数据库,只有一条记录

代码里的cgiOut是什么呢?,我们在cgic.h头文件的实现文件cgic.h中找到了答案。

//cgic.ccgiIn = stdin;cgiOut = stdout;

cgiOut就是标准输出。登录成功后,会跳转到主页面main.html。

(二)环境信息获取——env_1_a9_info.cgi

main.html页面是一个frameset框架,由left.html,top.html,right.html三个页面构成。

其中只要left.html导航栏具有实际的功能选项。

我们先看看环境信息env1.html页面中的cgi程序

<iframe  frameborder="0"  border=0 scrolling="no" src="cgi-bin/env_1_a9_info.cgi" width="100%" height="100%"></iframe>

这个iframe告诉我们env_1_a9_info.cgi程序会处理当前的实时数据,并返回结果。

分析一下env_1_a9_info.cgi的源码,来看看这些数据是怎么得到的。

get_env()函数是用来获取环境信息的。

//env_1_a9_info.cvoid get_env()
{sqlite3 *db;char sql1[N] = {0}, sql2[N] = {0};char **result1, **result2;int row1, colunm1, row2, colunm2;if  (sqlite3_open("/smartfarm.db", &db) != SQLITE_OK) {fprintf(cgiOut, "<H2>sqlit smartfarm.db open err</H2>");    errflag = 1;return ;}sprintf(sql1, "select * from env where farm_no=1");if (sqlite3_get_table(db, sql1, &result1, &row1, &colunm1, NULL) != SQLITE_OK) {fprintf(cgiOut, "<H2>sqlite3_get_table  err</H2>"); errflag = 1;return ;}strncpy(temp_max, result1[colunm1 + 1], 9);strncpy(temp_min, result1[colunm1 + 2], 9);strncpy(hum_max, result1[colunm1 + 3], 9);strncpy(hum_min, result1[colunm1 + 4], 9);strncpy(light_max, result1[colunm1 +5], 9);strncpy(light_min, result1[colunm1 + 6], 9);.......sqlite3_close(db);
}

不难发现,这些数据都是从数据库smartfarm.db中获取的。

最高/最低气温,湿度,光照,都在env表中。

还有一张collect_env表,显示的是实时信息,但是好像没有用到。

//env_1_a9_info.cvoid get_env()
{........sprintf(sql2, "select * from collect_env where farm_no=-1");if (sqlite3_get_table(db, sql2, &result2, &row2, &colunm2, NULL) != SQLITE_OK) {errflag = 1;return ;}
#if 0strncpy(temp, result2[colunm2 + 1], 9);strncpy(hum, result2[colunm2 + 2], 9);strncpy(light, result2[colunm2 + 3], 9);
#endif}

很明显,temp,hum,light分别存放当前的温度、湿度和光照,但是被注释掉了

(三)实时监控的图像拍照处理——take_photo.cgi

实现监控的CGI程序是take_photo.cgi,我们还是直接分析它的源代码。

抛开cgi程序的fprintf不看,我们直接看核心处理的部分

//take_photo.ckey_t key; int msgid; char buf[2] = {0};if((key = ftok("/lib", 'a')) < 0){perror("ftok");exit(1);}if ((msgid = msgget(key, IPC_CREAT | IPC_EXCL | 0666)) < 0){if (errno == EEXIST) {msgid = msgget(key, 0666);}else{perror("msgget msgid");return 0;}}struct message msgbuf;msgbuf.type = 1L;msgbuf.msg_type = 2L;cgiFormString("mode", buf, 2);if(buf[0] <= '0' || buf[0] > '9')goto err;msgbuf.text.camera = buf[0] - '0';msgsnd (msgid, &msgbuf, sizeof (msgbuf) - sizeof (long), 0);

这是一段linux的进程间通信,我们需要关注以下三个系统调用:

  • key_t ftok(const char *pathname, int proj_id)
  • int msgget(key_t key, int msgflg)
  • int msgsnd(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg)

这些调用的细节不去管它,只要知道该进程需要收发其他进程的消息就可以了。

我们关注这段代码,看看进程发送的消息msgbuf是什么。

//take_photo.cstruct message msgbuf;msgbuf.type = 1L;msgbuf.msg_type = 2L;cgiFormString("mode", buf, 2);if(buf[0] <= '0' || buf[0] > '9')goto err;msgbuf.text.camera = buf[0] - '0';

注意到这里的cgiFormStirng函数,我们的buf存的是表单中收集到的数字,下面是表单的内容。

<form id="take_photo" name="take_photo" method="post" action="cgi-bin/take_photo.cgi"><td width="15%"><input type="radio" name="mode" id="mode_1" value="1" />1</td><td width="15%"><input type="radio" name="mode" id="mode_2" value="3" />3</td><td width="15%"><input type="radio" name="mode" id="mode_3" value="5" />5</td><td width="15%"><input type="radio" name="mode" id="mode_4" value="7" />7</td><td width="15%"><input type="radio" name="mode" id="mode_5" value="9" />9</td><td width="25%"><input type="submit" name="take_photo" id="take_photo" value="图像抓拍" /></td>
</form>

结构体message在struct.h头文件中有定义

//struct.hunion text {unsigned char led;unsigned char buzzer;unsigned char camera;unsigned char fan;unsigned char relay;unsigned char uart;char phone[24];struct control_parameter parameter;
};struct message {long type;long msg_type;union text text;
};

那么谁会接收msgbuf这个消息呢?我们可以在项目源码中找到答案。

看一下,项目源码里面pthread_client_request.c中的一个代码片段

//pthread_client_request.cswitch (msgbuf.msg_type) {........case CAMERA:printf("received camera request\n");pthread_mutex_lock (&mutex_camera);dev_camera_mask = msgbuf.text.camera;pthread_cond_signal (&cond_camera);pthread_mutex_unlock (&mutex_camera);break;........default:
#if DEBUGprintf("pthread client request default break\n");
#endifbreak;}

也就是说会 有专门的线程用来处理摄像头有关的消息

我们还记得之前take_photo.c有这样一段代码

    struct message msgbuf;msgbuf.type = 1L;msgbuf.msg_type = 2L;

1L、2L这样的魔数是什么意思呢

答案在项目源码的global_variable.h头文件中

//global_variable.h/*message queue type */
#define REQUEST 1L        //msgbuf.type=1L/*message queue msg_type*/
#define BUZZER 1L
#define CAMERA 2L       //msgbuf.msg_type = 2L
#define FAN 3L
#define LED 4L
#define RELAY 5L
#define SET_PARAMETER 6L
#define SMS 7L
//#define SQLITE 7L
#define UART 8L
#define MODIFY_PHONE_NUM 9L
#define BEEP 10L

linux下一切都是文件,打开摄像头也不例外

//pthread_camera.cif ((dev_camera_fd = open (DEV_CAMERA, O_RDWR | O_NOCTTY | O_NDELAY)) < 0){printf ("Cann't open file /tmp/webcam\n");exit (-1);}

其中DEV_CAMERA这个常量的定义在头文件global_variable.h中也能找到

//global_variable.h#define DEV_GPRS            "/dev/ttyUSB1"
#define DEV_GPRS_2          "/dev/ttyUSB2"
#define DEV_ZIGBEE          "/dev/ttyUSB0"
#define DEV_LED             "/dev/led"
#define DEV_BUZZER          "/dev/buzzer"
#define DEV_CAMERA          "/tmp/webcam"
#define SQLITE_OPEN         "./smartfarm.db"

这个常量就是/tmp/webcam,这应该指的就是摄像头设备

(四)照片展示——show_photo.cgi

在“历史照片”这一功能中,调用的CGI程序是show_photo.cgi

我们同样还是忽略掉CGI源码中的fprintf部分。

#define DIRNAME     "../pice"
#define PHOTO_NUM_MAX   100 // 最多100张,0-99int cgiMain()
{.........if((dir = opendir(DIRNAME)) == NULL)    //打开图片存放的目录{perror("fail to opendir");exit(1);}while((dirp = readdir(dir)) != NULL)  //读文件夹里文件的名字{if(dirp->d_name[0] > '9' || dirp->d_name[0] < '0')   //名字的第一个字母continue;sprintf(photoname[syncmsg1.photo_num++], "%s", dirp->d_name);if(syncmsg1.photo_num >= PHOTO_NUM_MAX)         //判断是否超过最大值{syncmsg1.photo_num = PHOTO_NUM_MAX - 1;break;}}.........}

我们从中可以知道,历史照片都是保存在/www/pice目录下的,而且最多只保存100张。

四、调试过程中无法解决的问题

难题1:WIFI模块无法使用

原本这个系统是通过WIFI来访问并进行控制的,但是我们的WIFI模块出现了问题,现在只能用网线直连的方式控制系统。

我们将手机热点配置为my_accent,密码设为012345678,在rootfs/etc中添加配置文件wpa-spk-tkip.conf

# WPA-PSK/TKIPctrl_interface=/var/run/wpa_supplicantnetwork={ssid="my_accent"key_mgmt=WPA-PSKproto=WPApairwise=CCMPgroup=CCMPpsk="012345678"
}

更新文件系统以后重新烧写镜像,配置IP和网关后,执行命令wpa_supplicant -B -i wlan0 -c /etc/wpa-psk-tkip.conf

我们可以看到,wlan网卡依然没有连接到手机热点上。我们暂时没有解决这个问题。

难题2:视频模块无法使用

我们无论直接使用含有项目内容的文件系统,还是自己重新编译mjpeg-streamer都出现了同样的问题。

我们启动开发板后,对mjpeg-streamer进行测试。

运行mjpg_streamer -i "/mjpg/input_uvc.so -y -d /dev/video0" -o "/mjpg/output_http.so -w 192.168.9.111:8080"

系统显示由于设备被占用了,初始化失败。我们没有找到解决的方法。

这些问题目前依然没有找到解决方案

五、心得体会

我们小组成员之前都没有嵌入式开发的经验,这次课程设计——“远程安防监控系统”对我们来说是一次挑战吧。虽然已经有现成的源码和成熟的文档,我们真正操作的时候还是遇到了许多问题,才真正体会到什么是“纸上得来终觉浅”。

我们在这次课程设计中收获很多,我们惊讶地发现,之前的linux操作经验对我们进行嵌入式开发有很大的帮助,串口通讯之后,文件的操作与查看,网络状态的查看,进程的查看与kill,都如出一辙,不得不感叹linux的伟大,在linux知识上的投资收益真棒。

C语言的可移植性还是不错的,很多源码进行较差编译的时候,只需要把原来的编译器"CC=gcc"改为"CC=arm-none-linux-gnueabi-gcc"就可以,有时甚至不用改变C语言代码就能正常make。

嵌入式开发还是很有意思的,我们通过这次课程设计慢慢摸到了点门道。

六、参考资料

  1. Win10怎么禁用驱动程序强制签名
  2. /dev/tty /dev/ttyS0 /dev/tty0区别
  3. 《远程安防监控系统项目文档》华清远见教育集团研发中心

转载于:https://www.cnblogs.com/wyf12138/p/9125423.html

20155110王一帆 《远程安防监控系统》课程设计个人报告相关推荐

  1. 服务器发送消息到客户端互斥,小车远程监控系统 课程设计

    <小车远程监控系统 课程设计>由会员分享,可在线阅读,更多相关<小车远程监控系统 课程设计(17页珍藏版)>请在人人文库网上搜索. 1.课程设计n报告(2016/2017学年 ...

  2. 计算机网络技术现代安防是啥意思,现代化校园视频安防监控系统 具有哪些特点呢...

    原标题:现代化校园视频安防监控系统 具有哪些特点呢 校园视频安防监控系统主要是利用监控设备对学校场所进行全方位.全高清视频立体化管理和监控,从而维护校园秩序和安全,同时能为同学们的生活和学习营造更好的 ...

  3. 安防工业交换机将成为安防监控系统主要的传输设备

    工业交换机即工业以太网交换机,它作用是放到路由器后端,来扩展路由器接口,以解决接口不够用的问题.以太网在设计时,由于其采用载波侦听多路复用冲突检测(CSMA/CD机制),在复杂的工业环境中应用,其可靠 ...

  4. 安防监控系统流媒体服务器,搭建一套安防监控系统RTSP/Onvif网络摄像头视频流媒体服务有哪些核心要素?...

    原标题:搭建一套安防监控系统RTSP/Onvif网络摄像头视频流媒体服务有哪些核心要素? 在现代信息社会,人民的生活水准不断提高,因而对安全的需求也越来越迫切.特别自"9·11"与 ...

  5. 如何自己动手为家庭做一套安防监控系统

    作为一个拥有小孩的父母,作为一个拥有高龄父母的儿女,你会尽可能采用各种方式保护家人安全.当你刷视频看到各种盗窃案或者入室抢劫案的时候,细思极恐.很多威胁人身安全的事情都发生在晚上,或者人们放假的时候, ...

  6. 智能楼宇中的安防监控系统

    在城市现代化建设的发展与建筑的智能化进程中,随着监控技术的成熟和计算机应用领域的拓宽,我国的智能楼宇安防监控系统逐渐发展起来.在建筑内安装相应的监控系统已经成为一种普遍的现象,越来越受到人们的青睐. ...

  7. 大华城市安防监控系统平台管理存在任意文件下载漏洞

    大华城市安防监控系统平台管理存在任意文件下载漏洞 1.大华城市安防监控系统平台管理存在任意文件下载漏洞 1.1.漏洞描述 1.2.漏洞影响 1.3.FOFA 2.漏洞复现 2.1.登录页面 2.2.抓 ...

  8. 【解决方案】教育培训中心安防监控系统:RTSP协议网络摄像头互联网无插件直播平台EasyNVR助力培训点智能安防搭建

    随着安防行业的不断发展,平安校园建设在各地的推广应用逐渐成为行业趋势.越来越多与学校同步的培训点选择了科学.有效,且节约人力物力的安防系统建设作为保护学生安全的重要手段. 教育培训中心安防监控系统的搭 ...

  9. 服务器监控系统哪家性价比高,伊利智能安防监控系统哪家专业

    伊利智能安防监控系统哪家专业 由于IT基础设施,运维监控特性,这种方式被广泛应用.一般对时序数据进行建模分为三个部分,分别是:主体,时间点和测量值.通过这个例子来看一下,时序数据库的数学模型,例如:需 ...

  10. 安防监控系统组成部分介绍

    安防监控系统是一门被人们日益重视的新兴专业,就目前发展看,应用普及越来越广,科技含量越来越高.几乎所有高新科技都可促进其发展,尤其是信息时代的来临,更为该专业发展提供契机.但就监控业界而言,系统组成一 ...

最新文章

  1. CSS定位布局display/float/position属性之间的关系/区别和如何使用取值行为机制
  2. Cannot perform runtime binding on a null reference
  3. mysql分组取出每组地一条数据_MySQL 分组后取每组前N条数据
  4. swift. 扩展类添加属性_Swift iOS-如何动态地向现有类添加属性然后访问它们
  5. 浅析epoll – epoll函数深入讲解
  6. Win11系统资源管理器自动重启怎么办
  7. 曾经一手好牌,但如今却被网友怼或已堕落
  8. 【总结】C++逻辑与或
  9. [linux命令]基本命令
  10. 肯德尔系数怎么分析_论文实战2——德尔菲法与信度分析
  11. 网络在线播放ASF格式流媒体文件的制作(转)
  12. 世界水周:美国女高中生水污染解决方案获2021斯德哥尔摩青少年水奖
  13. 关于DDoS攻击的8个误区
  14. 导弹拦截(动态规划)
  15. 百宝云Post与Get事件教程
  16. Delphi编程中流的使用
  17. canvas 画线条
  18. 用Python自动批量提取Tableau报表数据源中用的数据库表
  19. 含有一般疑问句的歌_一般疑问句,特殊疑问句和否定句
  20. 深圳南山区的篮球场大全

热门文章

  1. 锐龙调用python库的问题_一个小白对当前锐龙4000笔记本的愚见
  2. Nginx负载均衡配置
  3. 深入理解Amazon Alexa Skill(三)
  4. 计算机文化基础试题每日一练15,【每日一练】2018教师[资格考编]笔试备考练习(9.6)...
  5. es6 混合commjs_ES6 模块化的时代真的来临了么?Using MJS
  6. mysql创建索引降序_Mysql中的降序索引底层实现
  7. An Introduction to Pairing-Based Cryptography学习笔记
  8. 生命以负熵为生:零知识证明的前世今生
  9. TMS320C6748的StarterSware软件包
  10. gitee码云安装和使用教程