新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > DS80C400的Keil C语言编程

DS80C400的Keil C语言编程

作者:时间:2012-02-01来源:网络收藏
注意在每次启动应用时都须调用finit函数,以确保文件系统已正确安装并能正常工作。如果文件系统已正确初始化(返回0),并且我们所要的文件已全部到位,则函数直接退出,不去尝试下载文件。否则,它会尝试从TFTP服务器下载文件,并将它们写入文件系统,正如函数get_tftp_file中所显示的。

SolarWinds为Windows (平台提供了一个免费的TFTP服务器,它被应用于该演示程序的开发中。在SolarWinds网站(www.solarwinds.net),跟随Downloads - Free Software菜单可找到TFTP服务器下载。安装以后,使用File菜单下的Configure选项来配置现有文件。确保程序使用你的TFTP服务器IP地址(TFTP_IP_MSP, TFTP_IP_2,TFTP_IP_3和TFTP_IP_LSB)。

简单的HTTP服务器
该应用中的HTTP服务器是RFC 2068所描述的HTTP服务器的一个简化版实现。在该版本下,只支持'GET'方法。输入头被忽略,只给出很少的输出头。

服务器套接字通过调用Berkley型套接字函数来创建,这样使得服务器套接字容易建立。以下代码说明了这个简单的HTTP服务器是如何创建、邦定并接受新连接的。

      struct sockaddr local;unsigned int socket_handle, new_socket_handle, temp;socket_handle = socket(0, SOCKET_TYPE_STREAM, 0);local.sin_port = 80;bind(socket_handle, local, sizeof(local));listen(socket_handle, 5);printf("Ready to accept HTTP connections...r");// here is the main loop of the HTTP serverwhile (1){new_socket_handle = accept(socket_handle, address, sizeof(address));handleRequest(new_socket_handle);closesocket(new_socket_handle);}
请注意,接受了新的套接字后,这个简单的应用并不启动新的线程或进程来处理请求。而是在同一进程中处理该请求。任何非演示版的HTTP服务器都会在新的线程中处理收到的请求,这样就允许多个连接出现并被同时处理。请求处理完后,关闭套接字,等待另一个收到的连接。

handleRequest方法从收到的请求中解析出一个文件名,并确定该方法是'GET'。其它方法(甚至是'POST','HEAD'或'OPTIONS')均不被接受。两个文件名被作为特例处理。当请求文件为time.html时,服务器动态产生一个响应,其中包含来自timeserver的最新结果,以及自上一次查询时间服务器以来的秒数。当请求文件为stats.html时,将显示服务器的正常运行时间和请求次数统计结果。

如果找不到文件或发出的是无效的请求方法,HTTP服务器报告错误码。

SNTP客户端
第二个主要部分是Simple Network Time Protocol客户端,参见RFC 1361的描述。它是Network Time Protocol (RFC 1305)的一个版本。SNTP要求UDP从一个侦听端口123的服务器请求时戳。我们的timeserver使用以下代码周期性地与服务器time.nist.gov同步。请注意,在写这篇文章时,DNS检索还不被支持,因此服务器的IP地址须手动设置。DNS现已被添加到了C库网站,以下代码更新后可通过检索获得IP地址。

      socket_handle = socket(0, SOCKET_TYPE_DATAGRAM, 0);// set a timeout of about 2 secondsbuffer[0] = 0x0;buffer[1] = 0x0;buffer[2] = 0x8;buffer[3] = 0x0;setsockopt(socket_handle, 0, SO_TIMEOUT, buffer, 200);buffer[2] = 0;                            // reset since we used this in call to setsockoptbuffer[0] = 0x23;                         // No warning/NTP Ver 4/Clientaddress.sin_addr[12] = TIME_NIST_GOV_IP_MSB;address.sin_addr[13] = TIME_NIST_GOV_IP_2;address.sin_addr[14] = TIME_NIST_GOV_IP_3;address.sin_addr[15] = TIME_NIST_GOV_IP_LSB;address.sin_port = NTP_PORT;sendto(socket_handle, buffer, 48, 0, address, sizeof(struct sockaddr));recvfrom(socket_handle, buffer, 256, 0, address, sizeof(struct sockaddr));timeStamp = *(unsigned long*)(buffer[40]);timeStamp = timeStamp - NTP_UNIX_TIME_OFFSET;// now we have time since Jan 1 1970formatTimeString(timeStamp, "London", last_time_reading_1);last_reading_seconds = getTimeSeconds();closesocket(socket_handle);
首先生成一个数据报套接字,并给定一个约2秒的超时(0x800==2048ms)。这样可以确保在与我们选择的服务器通信失败时,不必无限期地等待下去。

下一行设定请求选项。关于这些位的描述参见RFC 1361第三节。值0x23要求闰秒时无需告警,要求采用NTP版本4,并声明模式为'Client'。当我们使用公共数据报函数sendto和recvfrom发出请求并收到回答后,时戳的秒部被赋给变量timeStamp,然后调整到参考时间1970年1月1日。formatTimeString函数将时戳转换为易读的字符串,如“In London it is 15:37:37 on March 31, 2003”。

getTimeSeconds函数以内部时钟为基础确定上一次更新。由于该程序大约每60秒才更新一次,HTML页time.html使用这个数值来报告自上次更新以来的时间间隔。最后,关闭套接字,SNTP客户端在下面的60秒内进入休眠。

有关同步的说明
在LARGE存储模式下,编译器将通过在进程交换中非安全的存储器传递有限数量的参数。这就意味着有些函数不能由多个程序同时调用。尽管已专为 400开发了C库,其中的所有变量都通过在进程交换中安全的直接存储器传递,有些函数仍然是危险的。例如,Berkeley式的套接字header要求一些较长的方法签名,它会涉及到一些通过非安全存储器传递的数据。因此,针对套接字有两个库:

一个库(rom_sock.lib)遵循Berkeley式的header。但是,两个进程同时用这个库调用某个函数是不安全的。不过,如果一个进程正在使用UDP函数而另一个正在使用TCP函数就不会有问题。为了对并发访问非安全存储器提供真正的保护,开发了另外一个套接字库(rom_sock.lib)。该库中的函数类似于Berkeley型函数,但具有更少或重新安排的变量,以使编译器通过安全存储区传递参数。无论何种情况,请参考相关文档,以确认函数是否为多进程安全的。

c语言相关文章:c语言教程




评论


相关推荐

技术专区

关闭