编译通过后,接下来就是调试测试,让goAhead在stm32板子上跑起来。在这里仅展示在浏览器上访问stm32板子上简单的web页面。一个产品的web页面设计及其表单(form)处理有机会再介绍。
之前有朋友曾经问过我怎么处理嵌入式web前端与服务器的数据。只是由于一些原因给耽搁了,在这里给那位朋友说声不好意思了!
下面是按照我的调试测试思路来介绍的。
webcomp编译问题
上一节,我们主要修改了goAhead源码并完成了其编译工作。但仔细分析后发现,在ECOS目录没有编译webcomp.c文件,也就不能把我们的web页面文件编译到程序中。这是怎么回事?
分析ECOS目录下makefile发现,原来是makefile的问题。在ECOS目录makefile中,有目标如下:
# # Build a set of ROMable pages # webrom.c: webcomp find ../web -name "*.*" >web_files ./webcomp ../web web_files >webrom.c
先来分析上面这个目标。当编译webrom.c文件时,会去先执行webcomp目标,也就是产生网页编译器程序。然后,找出ECOS目录的上一级目录web下的所有文件写入到web_files文件中,而后,执行webcomp把web_files文件内容输出到webrom.c中。换句话说,webrom.c存放的是经过转换后的web页面数据。
检查发现,ECOS目录的上一级没有web目录,好吧,建立web目录。这个web目录经分析应该是用于放置web页面文件的。
回归问题:怎么没有执行这个目标流程?原来,是OBJ_FILES中../webrom.o在做怪。根据makefile规则,应该把上述的目标规则改为:
../webrom.c: webcomp
webcomp目标如下:
# # This tool needs to be built using the native C compiler # # 把cc改为gcc. # 增加-D_STRUCT_TIMEVAL定义,以避免uemf.h中的struct timeval结构体定义和ecos库中的已有定义冲突. # 把../webcomp.c改为../utils/webcomp.c # Added by reille 2013.08.24 # webcomp: gcc -o webcomp -O2 -DWEBS -DOS="Linux" -DLINUX -D_STRUCT_TIMEVAL -I.. ../utils/webcomp.c
webcomp目标中webcomp.c的存储位置有问题,原先是:../webcomp.c,应该改为:../utils/webcomp.c
make出现问题:
reille@ubuntu:/mnt/hgfs/stm32_ecos/appl/web/webs-2-5/ECOS$ make
find ../web -name “*.*” >web_files
./webcomp ../web web_files >webrom.c
*** glibc detected *** ./webcomp: double free or corruption (!prev): 0x08998008 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0x4009cff1]
/lib/tls/i686/cmov/libc.so.6[0x4009e6f2]
/lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0x400a179d]
/lib/tls/i686/cmov/libc.so.6(fclose+0x14a)[0x4008d50a]
./webcomp[0x8048d55]
./webcomp[0x8048ded]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0x40048b56]
./webcomp[0x8048741]
======= Memory map: ========
08048000-0804a000 r-xp 00000000 00:16 41260 /mnt/hgfs/stm32_ecos/appl/web/webs-2-5/ECOS/webcomp
0804a000-0804b000 r–p 00001000 00:16 41260 /mnt/hgfs/stm32_ecos/appl/web/webs-2-5/ECOS/webcomp
0804b000-0804c000 rw-p 00002000 00:16 41260 /mnt/hgfs/stm32_ecos/appl/web/webs-2-5/ECOS/webcomp
08998000-089b9000 rw-p 00000000 00:00 0 [heap]
40000000-4001b000 r-xp 00000000 08:01 936 /lib/ld-2.10.1.so
4001b000-4001c000 r–p 0001a000 08:01 936 /lib/ld-2.10.1.so
4001c000-4001d000 rw-p 0001b000 08:01 936 /lib/ld-2.10.1.so
4001d000-4001e000 r-xp 00000000 00:00 0 [vdso]
4001e000-40021000 rw-p 00000000 00:00 0
40032000-40170000 r-xp 00000000 08:01 4940 /lib/tls/i686/cmov/libc-2.10.1.so
40170000-40172000 r–p 0013e000 08:01 4940 /lib/tls/i686/cmov/libc-2.10.1.so
40172000-40173000 rw-p 00140000 08:01 4940 /lib/tls/i686/cmov/libc-2.10.1.so
40173000-40177000 rw-p 00000000 00:00 0
40189000-401a5000 r-xp 00000000 08:01 90040 /lib/libgcc_s.so.1
401a5000-401a6000 r–p 0001b000 08:01 90040 /lib/libgcc_s.so.1
401a6000-401a7000 rw-p 0001c000 08:01 90040 /lib/libgcc_s.so.1
40200000-40221000 rw-p 00000000 00:00 0
40221000-40300000 —p 00000000 00:00 0
bfc31000-bfc46000 rw-p 00000000 00:00 0 [stack]
Aborted
make: *** [../webrom.c] Error 134
请看链接:https://github.com/embedthis/goahead/issues/2
这是因为webcomp.c的197行和203行,有两次“fclose(lp)”执行,根据上面链接的描述,由于两次执行了fclose(lp),导致在X86的Ubuntu上libc有问题(That causes verbose libc complaint when running on ubuntu x86),屏蔽webcomp.c的203行,make clean下再make。
这样,我们就可以把web目录下所有的网页文件编译到程序中去了。
修改main.c
由于之前有把goAhead移植到linux经验,所以修改ECOS目录下的main.c也很容易。
修改web服务器根目录和IP地址
在initWebs()函数中,116行开始,修改后代码如下:
/* * Configure the web server options before opening the web server */ // websSetDefaultDir("/www");// Disabled by reille 2013.08.25 websSetDefaultDir("/");// Added by reille 2013.08.25 // cp = inet_ntoa(eth0_bootp_data.bp_yiaddr);// Disabled by reille 2013.08.23 // Added by reille 2013.08.25 struct in_addr intaddr; intaddr.s_addr = inet_addr(T("192.168.0.24")); cp = inet_ntoa(intaddr); ascToUni(wbuf, cp, min(strlen(cp) + 1, sizeof(wbuf))); websSetIpaddr(wbuf); ascToUni(wbuf, host, min(strlen(host) + 1, sizeof(wbuf))); websSetHost(wbuf);
这段代码主要用于设置WEB服务器的根目录和服务器IP地址。简单起见,这里把web服务器的IP地址固定死了。实际应用中,应该设为设备的IP地址。
设定web服务器默认页面
代码如下:
/* * Configure the web server options before opening the web server */ //websSetDefaultPage(T("home.htm"));// Disabled by reille 2013.08.25 websSetDefaultPage(WEBS_DEFAULT_HOME);// Added by reille 2013.08.25 websSetPassword(password);
修改websHomePageHandler()函数
代码如下:
/* * Home page handler */ static int websHomePageHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, char_t* url, char_t* path, char_t* query) { /* * If the empty or "/" URL is invoked, redirect default URLs to the home page */ if (*url == '\0' || gstrcmp(url, T("/")) == 0) { //websRedirect(wp, T("home.asp"));// Disabled by reille 2013.08.25 websRedirect(wp, WEBS_DEFAULT_HOME);// Added by reille 2013.08.25 return 1; } return 0; }
修改makefile产生bin文件
上节编译完成后,默认生成的是静态库文件libwebs.a和elf格式映像文件webs。在makefile下面段落的下面:
# # Primary link # $(NAME): Makefile main.o $(ARCH) $(CC) -o $(NAME) $(CFLAGS) $(IFLAGS) \ main.o $(ARCH) $(LDFLAGS)
添加内容:
$(OBJCOPY) -O srec $@ $@.srec
$(OBJCOPY) -O binary -R .sram $@ $@.bin
用于产生srec和bin格式可执行映像文件。-R .sram用于删除.sram段。这样,我们就可以得到webs.srec和webs.bin文件。选其中一个下载到板子上运行。
不能访问到页面问题
把webs.bin下到板子上,但在浏览器上输入IP地址后,却不能访问到页面。提示信息如下:
看到这个问题时,一筹莫展。开始以为是设置根目录websSetDefaultDir(“/”);或设置默认页面有问题,但调来调去却不能解决问题。
不得已,追代码。根据之前移植goAhead的经验(链接地址:http://velep.com/archives/335.html),“Cannot open URL”信息应是web服务器输出给浏览器的。经搜索,该信息在goAhead源码default.c文件的websDefaultHandler()函数中。
由于我们移植的goAhead是来自于移植到linux的源码包,所以WEBS_WHITELIST_SUPPORT这个是不支持的。分析下来就是websPageOpen()函数返回出错了。
在websPageOpen()中,应该是使用了WEBS_PAGE_ROM,所以这个函数应该是调用websRomPageOpen()函数。分析websRomPageOpen()函数,应该是获取web页面文件的索引。而在source insight中发现,websRomPageIndex在多个webrom.c中都有定义。何解?到底用的是哪个?
回到上面,再来分析ECOS目录下的makefile,看是编译了哪个webrom.c,又是实际使用了哪个webrom.c来存放web页面数据?
在makefile中,OBJ_FILES使用../webrom.o,说明编译的是goAhead源码包根目录下的webrom.c文件,而ECOS目录下也有一个webrom.c文件。make后,打开这两个文件,发现ECOS目录下webrom.c文件有页面数据。也就是说,web页面编译器把所有web目录下的web页面文件转换到了ECOS目录下webrom.c文件中,而实际编译却不是这个文件。这就难怪在浏览器打开不了页面。
再次修改makefile。把OBJ_FILES中的../webrom.o改为webrom.o,把../webrom.c: webcomp改回去,即webrom.c: webcomp,重新编译再运行。OK,可以在浏览器访问到页面了。如下图所示:
goAhead移植到eCos的源码下载
最后的源码包整理上传到了eCos技术网论坛中。下载地址:http://52ecos.net/thread-626-1-1.html