搜索
bottom↓
回复: 13

44b0实例二:基于uClinux的boa web服务器

[复制链接]

出0入0汤圆

发表于 2010-2-6 11:05:47 | 显示全部楼层 |阅读模式
44b0现在确实有点退潮了,这个实验也是好几年前做的了,不过对刚接触这方面的应该会有一定的参考吧。

实现功能:通过浏览器,访问44b0服务器上的网页,通过网页选项,控制44b0板上的蜂鸣器。
涉及内容:uClinux的配置编译,boa服务器的配置,简单的CGI程序,简单的网页程序,基于uClinux的蜂鸣器驱动程序。
点击此处下载 ourdev_532650.rar(文件大小:22K) (原文件名:home.rar)

一、uClinux的配置和编译(以下操作在linux环境下进行)
1) 在ARM开发板配套的光盘中,找到这两个文件(没有的网上down吧):压缩文件uClinux-dist-20050311.tar.gz和交叉编译器配置文件arm-elf-tools-20040427.sh(也可以从网上下载),把它们放到Linux环境下,并把它们放在一起。我在实践过程中,将这两个文件放在/usr/local/src下。
2) 安装ARM交叉编译器
(1) 将arm-elf-tools-20040427.sh的权限设置为可执行,命令为:chmod u+x arm-elf-tools-20040427.sh
(2) ./arm-elf-tools-20040427.sh
相应的工具安装在/usr/local/bin目录下。实践中,我将uClinux-dist-20050311.tar.gz复制到/usr/local/bin目录下。
3) 解压 uClinux-dist-20050311.tar.gz 文件
命令为: tar zxvf uClinux-dist-20050311.tar.gz
此时当前工作目录下增加了一个名为 uClinux-dist 的目录。 
4) 进入解压目录 uClinux-dist ;并清理过去留下的编译垃圾
命令:cd ./uClinux-dist         //进入目录
make clean;make mrproper       //清理垃圾
5) 配置内核
uClinux提供三个不同的命令进行uClinux的配置,效果完全一样
make config          控制台命令行方式配置命令
make xconfig         x窗口图形界面方式配置命令
make menuconfig      文本菜单方式配置命令
在实际过程中,我使用的是make menuconfig 命令来配置内核,编译后,在config目录下生成 .config的隐藏文件。
具体配置过程如下:
(1) 进入配置目录,输入配置内核命令,如下图:

(原文件名:进入目标文件,输入内核配置命令.png)

(2) 进入配置主界面,配置目标平台,如下图

(原文件名:配置主界面.png)

Vendor/Product Selection         //供应商板子产品选择
Kernel /Library/Defaults Selection  //目标平台选择

在Vendor/Product Selection下选择供应商和产品版本号,如图

(原文件名:供应商与产品选择界面.png)
此处选择Samsung的44B0。

在Kernel /Library/Defaults Selection下,选择定制内核,如图

(原文件名:定制内核.png)
选择Customize Kernel Settings  //定制内核
Customize Vendor/User Settings  //定制供应商和用户程序

(3)回到主界面,保存后离开。继续编译,出现内核定制界面,如图

(原文件名:内核定制界面.png)
在这个界面里,选中下面的选项:
General Type               //常规配置
Networking options          //网络配置
Network device support       //网络装置的支持

General Type的配置,如图

(原文件名:常规配置.png)
选中以下选项:
Networking support
Support uClinux FLAT format binaries
Timer and CPU usage LEDS
Timer LED
CPU usage LED

Networking options的配置,如图

(原文件名:网络配置.png)
选中以下选项:
Packet socket
Netlink device emulation
TCP/IP networking

Network device support的配置,如图

(原文件名:网络支持.png)
在主目录下选择Ethernet(10 or 100M bit ),进入下一级菜单,如下图

(原文件名:网卡芯片支持.png)
选中以下选项:
Cirrus Logic CS8900A support
Cther ISA cards
NE2000/NE1000 support

(4) 保存退出后回到主菜单,继续编译,出现用户程序配置界面,如下图

(原文件名:配置菜单.png)
配置Network Applications 这项。
选中以下选项:
boa        //适合于嵌入式应用的web server
ftp        //文件传输协议客户端程序
ftpd       //文件传输协议应用端程序
ifconfig    //网络工具软件
ping       //网络测试程序
tftp       //tftp协议客户端程序
tftpd      //tftp协议server端程序

(5) 保存后退出,继续编译。

6) 依次执行以下命令,完成uClinux的编译过程:
make dep          //建立依赖关系,并以此生成依赖文件
make lib_only      //编译库文件
make user_only     //编译用户应用程序文件
make romfs        //生成romfs文件系统
make             //编译内核
make image        //生成内核镜像文件
在编译的过程中,如果前三步有错,则需要从头再来,如果只是在make以后有错,后重复make,make image,直到生成没有错误的镜像文件image.ram

二、boa服务器的配置及CGI程序的编写

1、对boa.conf进行如下修改:(路径: ./uclinux-samsung/user/boa/src/boa.conf)
1).将user nobody改为User 0;
2).将Group nobody改为Group 0;
3).将DocumentRoot/etc改为DocumentRoot/home;
4).将MimeTypes/etc/mime.types改为MimeTypes/home/mime.types;
5).将#AddType application/x-httpd-cgi cgi前面的#去掉使系统可以支持cgi方式;
6).定义CGI程序所在目录:ScriptAlias/cgi-bin/ /home/;
7).将ErrorLog /var/log/boa/error_log等等几个log选项用#注释掉(具体配置参考所附文件,用写字板打开)
这样配置后的boa服务器将/home目录作为服务器的根目录,cgi程序位于home目录下,默认页面文件为home/index.html。

2、使用了蜂鸣器驱动程序的CGI
/*********************************************************************
* File:   submit.c
* Author: Embest  2004.12.20
* Desc:    cgi script file
* History:  
*********************************************************************/
#include <stdio.h>  
#include <stdlib.h>
#include <unistd.h>  
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

int main(void) {
int fd;
char *data;  
long m,n;
fd=open("/dev/beep",O_RDWR);
if(fd<0)
        {
        printf("can not open file\n");
        exit(0);       
        }         
printf("Content-type: text/html\n\n");
//下面的这些printf语句,动态的生成了CGI返回的信息页面
//注意:不要在输出的信息里使用汉字,不然有错
printf("<html><head><title>The Embedded Web Servers Of Beep Control Test</title></head>\n");
printf("<body><h2 align=\"center\"><i>The Response Of CGI</i></h2><pre>
\n");
data = getenv("QUERY_STRING");
if(strstr(data, "V1"))
    {
        printf("<p align=\"center\">[color=\"#000000\"]Can you hear the voice.</p>");
        ioctl(fd,1,0);//在CGI中调用蜂鸣器驱动程序,第二个参数为1,打开蜂鸣器
    }
else   
    {
        printf("<p align=\"center\">[color=\"#000000\"]You closeed the beep.</p>");
        ioctl(fd,0,0);//第二个参数为0,关闭蜂鸣器
    }
close(fd);
printf("<p align=\"center\">Return</p>\n");
printf("
");
printf("</pre></body></html>\n");
exit(0);
}
注:上面程序中的192.168.0.100是开发板所配置的IP地址,Return按钮超连接到这个地址

将上面的文件保存为submit.c,在linux环境下用交叉编译工具编译上面的文件
arm-elf-gcc -elf2flt -o submit.cgi submit.c
编译后回生成在当前文件夹下生成submit.cgi


Boa.conf文件的注释中指出,boa.conf文件和mime.types文件必须放到Web服务器根目录下,本例的Web服务器根目录为home,所以将修改后的boa.conf,mime.types,submit.cgi和下面的index.html文件都copy到uClinux-dist/romfs/home文件夹下
3、对应的index.html文件
<html>
<head><title>uClinux</title></head>
<body>
<p> </p>
<p align="center"><b>嵌入式Web服务器控制蜂鸣器的测试</b></p>
<p> </p>


<p align="center">通过下面的选项,你可以控制开发板上的蜂鸣器</p>
<form action="/submit.cgi">
  <p align="center">&nbsp;&nbsp;&nbsp; <input type="radio" name="R1" value="V1" checked>开蜂鸣器</p>         
  <p align="center">&nbsp;&nbsp;&nbsp; <input type="radio" name="R1" value="V2">关蜂鸣器</p>   
  <p align="center">
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="submit" value="确认"   
name="B1"></p>
  <p align="center">
   </p>
</form>
<p></p>


<p> </p>
<p>http://www.uclinux.org</p>
<p>http://www.boa.com</p>
</body>
</html>

注:上面form action后面的东东是对提交的表单进行处理的CGI文件的的路径和文件名,通过这个就关联到服务器端的处理程序了

三、蜂鸣器驱动程序的添加
1、beep.c是蜂鸣器的驱动程序,将其COPY到uClinux-dist/linux-2.4.x/drivers/char里面,uClinux的字符型设备驱动程序都放在这个文件夹下。
/***********************************************************************
*beep.c
************************************************************************/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
#include <asm/arch/s3c44b0x.h>
int beep_major=254;
//#define Non_Cache_Start  (0x2000000)
//#define Non_Cache_End   (0xc000000)
#define BEEP_CMD_SIGNAL 0
/************************* PORTS ****************************/
static int  beepman_ioctl(struct inode * inode, struct file * file,unsigned int cmd, unsigned long arg);
void Port_Init(void)
{
    (*(volatile unsigned *)S3C44B0X_PCONA)=0x1ff;   
    (*(volatile unsigned *)S3C44B0X_PDATB)=0x3ff;
    (*(volatile unsigned *)S3C44B0X_PCONB)=0x3ff;
    (*(volatile unsigned *)S3C44B0X_PDATC)=0xffff;  //All I/O Is High
    (*(volatile unsigned *)S3C44B0X_PCONC)=0x0f05ff55;   
    (*(volatile unsigned *)S3C44B0X_PUPC)=0x30f0;  //PULL  UP  RESISTOR  should  be enabled to I/O
    (*(volatile unsigned *)S3C44B0X_PDATD)=0xff;
    (*(volatile unsigned *)S3C44B0X_PCOND)= 0x0;
          (*(volatile unsigned *)S3C44B0X_PUPD) = 0x0;
    (*(volatile unsigned *)S3C44B0X_PDATE)=0x1ff;   
    (*(volatile unsigned *)S3C44B0X_PCONE)=0x25568;   
    (*(volatile unsigned *)S3C44B0X_PUPE)=0x0df;  //pull-up resistor.   
    (*(volatile unsigned *)S3C44B0X_PDATF)=0x1ff;  //All I/O Is High
    (*(volatile unsigned *)S3C44B0X_PCONF)=0x20900a;//All NC is INPUT
    (*(volatile unsigned *)S3C44B0X_PUPF)=0x163;
    (*(volatile unsigned *)S3C44B0X_PDATG)=0xff;
    (*(volatile unsigned *)S3C44B0X_PCONG)=0x00ff;         
    (*(volatile unsigned *)S3C44B0X_PUPG)=0x0;   //should be enabled   
    (*(volatile unsigned *)S3C44B0X_SPUCR)=0x7;   //D15-D0 pull-up disable
    (*(volatile unsigned *)S3C44B0X_EXTINT)=0x0;  //All EXTINT0-7 Low level interrupt
    (*(volatile unsigned *)S3C44B0X_NCACHBE0)=0;//((Non_Cache_End>>12)<<16)|(Non_Cache_Start>>12);  
}

void Beep(int BeepStatus)
{
  //PE5 Low available
if (BeepStatus==0)
(*(volatile unsigned *)S3C44B0X_PDATE)=(*(volatile unsigned *)S3C44B0X_PDATE)&0x1df;
else
(*(volatile unsigned *)S3C44B0X_PDATE)=(*(volatile unsigned *)S3C44B0X_PDATE)|0x020;
}

static int beepman_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
{  
  int  i;
  if (cmd == BEEP_CMD_SIGNAL)
  {
                                  printk("beep0\n");
                                  Beep(0);
                                  return(0);
}
else
{
                 printk("beep1\n");
                 Beep(1);
}
return  0;
}  

struct file_operations beep_fops={
ioctl: beepman_ioctl, /* ledman_ioctl */
};
int beep_init(void)
{
int result;
result=register_chrdev(254,"beep",&beep_fops);
if(result<0){printk("beep:cannot get major number!\n");
return result;}
return 0;
}


void cleanup_module(void)
{unregister_chrdev(beep_major,"beep");}


2、修改编译选项。在uClinux-dist/linux-2.4.x/drivers/char文件夹下找到Makefile这个文件,在适当位置添加一行(你看这个文件里面有和下面这个长相的差不多的,找到后就把这个添到后面即可):
obj-$(CONFIG_BEEP) +=beep.o
3、修改配置选项。在uClinux-dist/linux-2.4.x/drivers/char文件夹下找到Config.in文件,添加一行(为了配置方便,可以直接加到第一个if选项前面,这样在配置字符设备的时候就可以第一个看到他):
bool 'beep device' CONFIG_BEEP
4、在uClinux-dist/linux-2.4.x/drivers/char文件夹下找到mem.c,在适当位置添加(也是看有和下面代码差不多的地方):
#ifdef CONFIG_BEEP
extern void beep_init(void);
#endif
同时在chr_dev_init()函数中添加:
#ifdef CONFIG_BEEP
beep_init();
#endif
5、建立设备接点。在uClinux-dist/vendors/Samsung/44B0文件夹下找到Makefile文件,在DEVIVE部分添加:
beep,c,254,0
注:254是设备号,只要是没用的设备号都可以用,但要和其驱动程序里的设备号(如beep.c里的设备号一致)
6、以上是字符类驱动的修改配置过程,经过以上步骤,重新make menuconfig的时候,在选字符型驱动的时候选中这个选项就可以在应用程序中用自己的驱动程序了。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2010-2-6 11:08:10 | 显示全部楼层
顶你一下。哈哈

出0入0汤圆

发表于 2010-2-6 11:12:38 | 显示全部楼层
不错,最近弄到一个44BO的开发板,正好学习一下,感谢分享

出0入0汤圆

发表于 2010-2-6 13:35:26 | 显示全部楼层
不错

出0入0汤圆

发表于 2010-12-11 16:32:18 | 显示全部楼层
按你的一样配置,但make romfs时提示:
romfs-inst.sh /etc/boa.conf
cp: stat 'boa.conf'失败:没有那个文件或目录。

出0入0汤圆

 楼主| 发表于 2010-12-24 05:00:40 | 显示全部楼层
boa.conf文件和mime.types文件必须放到Web服务器根目录下,本例的Web服务器根目录为home,所以将修改后的boa.conf,mime.types,submit.cgi和下面的index.html文件都copy到uClinux-dist/romfs/home文件夹下

你看看有这个文件没,这个文件是否放在了正确的路径下。

出0入0汤圆

发表于 2010-12-26 00:04:40 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-12-31 13:52:44 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-12-31 23:20:10 | 显示全部楼层
现在ARM7是不是大多都是lpc的,那这款44b0是不是很少人用了?

出0入0汤圆

发表于 2011-3-2 20:14:14 | 显示全部楼层
我移植后为什么 var\www 中的HTML文件可以访问
而 var\www\cgi-bin 中的cgi却不能访问?

出0入0汤圆

发表于 2011-3-6 18:12:45 | 显示全部楼层
学习一下

出0入0汤圆

发表于 2011-3-7 09:05:00 | 显示全部楼层
mark

出0入4汤圆

发表于 2012-5-31 09:46:21 | 显示全部楼层
很好的分享,测试了一下,能用

出0入4汤圆

发表于 2012-5-31 09:46:56 | 显示全部楼层
ljt8015 发表于 2011-3-2 20:14
我移植后为什么 var\www 中的HTML文件可以访问
而 var\www\cgi-bin 中的cgi却不能访问? ...

注意html中对cgi的调用路径。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-20 17:47

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表