代码改变世界

Web配置子系统中的一个缺陷纠正

2013-05-25 01:55  zmkeil  阅读(629)  评论(0编辑  收藏  举报

1.系统简介

    就是上一篇中提到的那回事,所用系统是uC/OS,协议栈用的是LwIP(轻量级TCP/IP协议栈)。在uC/OS系统中,协议栈被放在一个task中,并且封装了一套API,供其它task调用来发送数据到网络上,或从网络上接受数据。为提高效率,协议栈的socket实现在该netTask中,而数据buffer实现在各自的task中,即不复制数据,而是task间共享。关于LwIP可以参考网上的很多资料。

    要注意的是,该协议栈仅是为这个SoC(片上系统)服务。而在板子中,还集成一个switch和一个以太网口Lan,以及一个DSL口Wan。可以把SoC子系统看成一个独立的计算机,它接在switch上,另外一台PC通过Lan口也接在switch上,那么它就可以和SoC通信了。而LwIP正是服务于SoC的协议栈,与板子上其它部分无关。

    在SoC上添加http、telnet服务器,那么外界PC就可以通过Lan、Wan口,经由switch,来读取信息、发送指令。

    还有一个问题是,SoC必须有MAC、IP啊,这里要注意的是,在LwIP中为该SoC准备了一个netif{}结构,并设置其类型为ethernet(类似于Linux中的net_device{})。而实际上它并没有以太网接口,它和switch集成在一块芯片内,彼此是通过片上总线直接相连的。MAC并不是要用于网卡收发,而只是对外模拟出好像正有一个以太网设备在板子上,另外告诉switch,该目的MAC的包发给SoC。

    IP是协议栈必须的,外部PC通过ARP协议将该IP映射为它的MAC。为了方便,我们称该IP为lan_ip。注意了,这里的lan和之前提到的Lan口没任何关系,那只是switch上的一个端口,没IP一说,只是其用于内部网络,习惯上陈为lan口。

    缺陷就是,通过http访问SoC,对板子进行配置,有一项就是修改SoC的lan_ip(默认是192.168.1.1),但改了IP之后,之前的socket连接会失效,怎么保证不重启的情况下,保持原来的连接(包括http,telent等)。

2.Allegro RomPager Advanced Web Server

    公司系统中用的是Allegro的http服务器,写得很复杂,暂且不去管它了。它为每个页面准备一个Description结构,该结构中主要有URL_str,html_item,ExtensionObject几个成员,第一个对应client的http-request的url(request类型可以是GET、POST…),第二个指向html页面,第三个是一个额外的数据结构,里面包含有一个处理函数指针(*func)(),该函数在http-response之前被执行。

    那问题就来了,有些处理必须在response完成后执行,如修改ip、reboot等。Allegro的服务器不提供response之后的hook函数接口,如果要添加,会比较麻烦。结合实际的应用,web配置都是局域网内用户通过Lan口来完成的,延时很小。所以可以在处理函数中,发送一个消息给另一个ConnManagerTask,该task收到消息后,睡眠1s钟(默认这段时间内response完成了),然后根据消息执行相应的操作(reset ip, reboot等)。

    上述的处理框架如下图所示:

另外在uC/OS中,消息队列是作为独立于task的全局变量,任何task可以用POST、PEND函数向队列中发消息、或取消息,且这些函数都是调度点。这种结构实现比较清晰、简洁,开发过程中,使用也很方便。

3.保持连接

    现在来看这个do_reset怎么做。这里主要纠结的是tcp,因为tcp是面向连接的,所创建的tcp-socket接口的本地local_ip可能就是这个lan_ip,如果lan_ip改了,那么所有这些socket都会失效。

    说到这,其实解决方法已经有了,就是在修改lan_interface的IP前,先遍历所有已存在的tcp-socket。这里socket分为两种:

  1. 一种是listen状态的,如服务器的监听口,如果它是绑定在原lan_interface上的,则修改其local_ip为新的IP,以便之后客户端可以通过新的IP访问服务器(避免了重启);
  2. 另一种是established状态的,如已连接的telnet,那么只能在服务器端销毁这个socket,当然销毁前,先发一个RST给客户端,一般客户程序收到RST后会退出(如telnet客户端),然后客户可用新的IP来创建新的tcp连接了。