一、系統(tǒng)架構(gòu)圖
系統(tǒng)硬件架構(gòu)圖:
從硬件架構(gòu)圖可以看出該系統(tǒng)采用B/S構(gòu)架,系統(tǒng)的主控平臺(tái)為MINI2440,通過(guò)在該平臺(tái)上構(gòu)建視頻服務(wù)器和WEB服務(wù)器實(shí)現(xiàn)系統(tǒng)主體設(shè)計(jì)。
系統(tǒng)軟件架構(gòu)圖:
軟件系統(tǒng)主要由Linux下的開(kāi)源服務(wù)器MJPG-Streamer、BOA服務(wù)器、小車(chē)控制應(yīng)用程序和小車(chē)驅(qū)動(dòng)組成。MJPG-Streamer和BOA服務(wù)器我們只需要移植便可,我們需要做的就是做一個(gè)HTML格式的web界面、一個(gè)控制小車(chē)應(yīng)用程序、小車(chē)驅(qū)動(dòng)和一個(gè)啟動(dòng)這些程序的Shell腳本。
二、MJPG-Streamer服務(wù)器的移植
MJPG-Streamer的移植方法我是參考MINI2440的文檔移植的。移植很簡(jiǎn)單只需編譯然后運(yùn)行便可。
三、BOA服務(wù)器的移植
到這部分大家可能會(huì)有點(diǎn)疑問(wèn),為什么有了視頻服務(wù)器還需要一個(gè)WEB服務(wù)器,上一步的MJPG-Streamer就可以在WEB瀏覽器上瀏覽到實(shí)時(shí)視頻了,是因?yàn)镸JPG-Streamer不支持CGI腳本,瀏覽器端無(wú)法和服務(wù)器就行通信。而B(niǎo)OA服務(wù)器支持CGI,CGI腳本可以實(shí)現(xiàn)服務(wù)器和應(yīng)用程序的通信,也就是說(shuō)瀏覽器端的信息可以通過(guò)CGI傳送給應(yīng)用程序。于是我們就可以通過(guò)瀏覽器端用戶的操作來(lái)決定小車(chē)的動(dòng)作。BOA服務(wù)器的移植,網(wǎng)上也有大把的文章,大家可以去查閱。
四、BOA顯示MJPG-Streamer視頻數(shù)據(jù)
上兩步我們已經(jīng)完成了MJPG-Streamer和BOA服務(wù)器的移植,但是如何把MJPG-Streamer的視頻數(shù)據(jù)在BOA服務(wù)器上顯示呢?我google了好久也沒(méi)發(fā)現(xiàn),后來(lái)自己嘗試成功了,只需加一條在BOA的顯示的HTML網(wǎng)頁(yè)文件中加一條語(yǔ)句即可:
<img src=
http://192.168.1.102:8080/?action=stream>
img是HTML語(yǔ)言的一個(gè)圖像控件,192.168.1.102是我的視頻服務(wù)器的IP地址。HTML界面設(shè)計(jì)我也不講了,我也沒(méi)學(xué)過(guò),只花了一天的時(shí)間學(xué)了用fontpage來(lái)構(gòu)建了一個(gè)很丑陋的界面,不過(guò)也能良好工作,后來(lái)嫌它實(shí)在太丑了,叫一個(gè)會(huì)這個(gè)的朋友幫忙做了一個(gè)。
五、CGI編程
CGI全稱叫做“通用網(wǎng)關(guān)接口”。利用通過(guò)網(wǎng)關(guān)接口(CGI),WEB服務(wù)器可以執(zhí)行一些外部的小程序。通用網(wǎng)關(guān)接口(CGI)只是規(guī)定了一個(gè)標(biāo)準(zhǔn)的接口規(guī)范,只要遵守這個(gè)標(biāo)準(zhǔn)規(guī)范,程序開(kāi)發(fā)人員就可以利用各種編程工具,例如Perl、C、Fortan、Visual Basic等進(jìn)行CGI編程。C語(yǔ)言是每一個(gè)程序員的必備語(yǔ)言,所以我們采用C語(yǔ)言進(jìn)行CGI編程。CGI主要通過(guò)GET和POST兩種方法對(duì)服務(wù)器端的表單進(jìn)行響應(yīng),具體操作見(jiàn)《CGI程序設(shè)計(jì)指南》。我的CGI的代碼很簡(jiǎn)單,如下:
[cpp]
view plaincopy<span style="font-size:18px;"></span><pre name="code" class="cpp">……………..
………………
#define FIFO_SERVER "/var/my_car_fifo"http://我的FIFO管道文件
void main()
{
char *buff= NULL;
charcar_bt_value[10]="";
intfifo_fd;
buff =getenv("QUERY_STRING");
sscanf(buff, "%*[^=]=%s", car_bt_value);
fifo_fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);
/* 向管道寫(xiě)入數(shù)據(jù) */
write(fifo_fd,car_bt_value,10);
close(fifo_fd);
return 0;
}</pre><br>
<br>
<pre></pre>
<span style="font-size:16px"></span>
<p></p>
<p align="left"><strong><span style="font-size:16px"> 六、小車(chē)驅(qū)動(dòng)</span></strong></p>
<p align="left"><span style="font-size:16px"> 小車(chē)采用L298N芯片驅(qū)動(dòng),這是一款功率放大芯片,專門(mén)用來(lái)驅(qū)動(dòng)小車(chē)用的。L298 可驅(qū)動(dòng)2 個(gè)電機(jī), OUT1、OUT2 和OUT3、OUT4 之間分別接2 個(gè)電動(dòng)機(jī)。5、7、10、12 腳接輸入控制電平, 控制電機(jī)的正反轉(zhuǎn), ENA, ENB 接控制使能端, 控制電機(jī)的停轉(zhuǎn)。下面是電路和邏輯功能圖:</span></p>
<p align="left" style="text-align:center"><span style="font-size:16px"><img src="http://hi.csdn.net/attachment/201112/25/0_1324825467ID8D.gif" alt=""></span></p>
<p align="left" style="text-align:center"><span style="font-size:16px"><img src="http://hi.csdn.net/attachment/201112/25/0_1324825492pWBE.gif" alt=""></span></p>
<p><span style="font-size:16px">所以小車(chē)的驅(qū)動(dòng)很容易編寫(xiě)只需要往GPIO寫(xiě)不同的高低電平即可,就和寫(xiě)LED驅(qū)動(dòng)一樣。</span></p>
<p><strong><span style="font-size:16px">七、小車(chē)控制應(yīng)用程序</span></strong></p>
<p><span style="font-size:16px"> 小車(chē)應(yīng)用程序只需要?jiǎng)?chuàng)建一個(gè)FIFO管道,然后從FIFO管道讀取到CGI寫(xiě)進(jìn)去的命令然后調(diào)用小車(chē)驅(qū)動(dòng)執(zhí)行相關(guān)的操作控制小車(chē)即可。代碼如下:</span></p>
<p></p>
<pre name="code" class="cpp"><span style="font-size:16px;">#include<sys/types.h>
#include<sys/stat.h>
#include<errno.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#define FIFO"/var/my_car_fifo"
#include<linux/ioctl.h>
#defineCAR_IOC_MAGIC 'k'
#define CAR_UP_IO(CAR_IOC_MAGIC, 0)
#define CAR_DOWN_IO(CAR_IOC_MAGIC, 1)
#define CAR_LEFT_IO(CAR_IOC_MAGIC, 2)
#define CAR_RIGHT_IO(CAR_IOC_MAGIC, 3)
#define CAR_STOP_IO(CAR_IOC_MAGIC, 4)
main(intargc,char** argv)
{
char buf_r[10];
int fifo_fd, car_fd;
int nread;
car_fd = open("/dev/my_car",0);
if(car_fd == -1){
perror("open car devicefailed");
exit(1);
}
/* 創(chuàng)建管道 */
if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST))
{
perror("cannot createfifo\n");
exit(1);
}
while(1)
{
fifo_fd=open(FIFO,O_RDONLY,0);
memset(buf_r,0,sizeof(buf_r));
if((nread=read(fifo_fd,buf_r,10))==-1)
{
if(errno==EAGAIN)
printf("no datayet\n");
}
if(!strcmp(buf_r, "UP"))
{
ioctl(car_fd, CAR_UP);
printf("goup!\n");
}
if(!strcmp(buf_r,"DOWN"))
{
ioctl(car_fd, CAR_DOWN);
printf("godown!\n");
}
if(!strcmp(buf_r,"LEFT"))
{
ioctl(car_fd, CAR_LEFT);
printf("goleft!\n");
}
if(!strcmp(buf_r,"RIGHT"))
{
ioctl(car_fd, CAR_RIGHT);
printf("goright!\n");
}
if(!strcmp(buf_r,"STOP"))
{
ioctl(car_fd, CAR_STOP);
printf("gostop!\n");
}
close(fifo_fd);
}
close(car_fd);
}</span></pre><span style="font-size:16px"><br>
<br>
</span>
<p></p>
<p><strong><span style="font-size:16px">八、Linux無(wú)線網(wǎng)卡的使用</span></strong></p>
<p><span style="font-size:16px"><strong> </strong>請(qǐng)查閱《基于MINI2440的USB無(wú)線網(wǎng)卡使用指南》。</span></p>
<p><span style="font-size:16px"><br>
</span></p>
<p><strong><span style="font-size:16px">九、結(jié)語(yǔ)</span></strong></p>
<p><span style="font-size:16px"> 本文檔只給大家一個(gè)實(shí)現(xiàn)的思路,具體實(shí)現(xiàn)還得靠自己。完成這個(gè)項(xiàng)目需要的知識(shí)有:Linux應(yīng)用程序編程、Linux內(nèi)核驅(qū)動(dòng)基本知識(shí)和CGI編程知識(shí)。之所以做這個(gè)項(xiàng)目是因?yàn)樯弦粋€(gè)項(xiàng)目H.264監(jiān)控做的不是很成功,于是考慮使用WEB方式來(lái)實(shí)現(xiàn),后來(lái)學(xué)了一些驅(qū)動(dòng)的知識(shí),然后查閱了一些資料,只用十幾天的就拿下了。這個(gè)項(xiàng)目和華清遠(yuǎn)見(jiàn)的一個(gè)項(xiàng)目差不多,發(fā)現(xiàn)這個(gè)項(xiàng)目也不過(guò)如此,沒(méi)多少含金量,所以本人不推薦有一定自學(xué)能力的人去進(jìn)行嵌入式培訓(xùn)。如有疑問(wèn)可以問(wèn)我:QQ:843308498</span></p>
<p><span style="font-size:16px"><span style="white-space:pre"></span>最后,上圖,秀一個(gè):</span></p>
<p><span style="font-size:16px"><img src="http://hi.csdn.net/attachment/201112/29/0_13251252205335.gif" alt=""><br>
</span></p>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre></pre>