52.6.2 STM32F429开发板实验 配套例子: V6-1069_RL-TCPnet实验_WebServer之Ajax实现动态网页局部刷新(RTX)。 实验目的: 1. 学习Ajax技术实现动态网页局部刷新的制作方法和RL-TCPnet的Web服务器实现 实验内容: 1. 强烈推荐将网线接到路由器或者交换机上面测试,因为已经使能了DHCP,可以自动获取IP地址。 2. 用户可在浏览器中直接输入IP地址访问Web服务器,跟大家访问路由器后台一样,也可以通过NetBIOS局域网域名直接访问,即http://armfly/,这样就无需查看具体IP了。 3. Web服务器的用户名admin,密码123456。 4. 本例子主要学习Ajax技术(异步JavaScript+XML),做了两个交互功能。 一个是温度监控页面: (1)温度传感器采用的DS18B20,开发板上面没有带此器件,但是有接口,测试例子前务必插上。 (2)为了保证RTC实时时钟能够正常起振,下载程序后将板子断电然后重新上电再测试。 另一个是蜂鸣器控制页面: (1)如果用的比较老的V5开发板,请查看板子上面是否有无源蜂鸣器,后来出的V5和V6板子都带无源蜂鸣器。 5. 关于网页的制作和Web服务器的测试方法,务必看本例子配套的教程,有详细讲解!!! 网页制作: 详见本章节52.4小节。 配置向导文件设置(Net_Config.c): 详见本章节52.2小节。 调试文件设置(Net_Debug.c): 详见本章节52.3小节。 Web服务器访问效果: 详见本章节52.5小节。 RTX配置: RTX配置向导详情如下: Task Configuration (1)Number of concurrent running tasks AppTaskUserIF任务 :按键消息处理。 AppTaskLED任务 :LED闪烁和DS18B20温度读取。 AppTaskMsgPro任务 :按键和蜂鸣器检测。 AppTaskTCPMain任务:RL-TCPnet网络主任务 AppTaskStart任务 :启动任务,也是最高优先级任务,这里实现RL-TCPnet的时间基准更新。 (2)Number of tasks with user-provided stack 创建的5个任务都是采用自定义堆栈方式。 (3)Run in privileged mode 设置任务运行在非特权级模式。 RTX任务调试信息: 程序设计: 任务栈大小分配: staticuint64_t AppTaskUserIFStk[1024/8]; /* 任务栈 */ staticuint64_t AppTaskLEDStk[1024/8]; /* 任务栈 */ staticuint64_t AppTaskMsgProStk[1024/8]; /* 任务栈 */ staticuint64_t AppTaskTCPMainStk[4096/8]; /* 任务栈 */ staticuint64_t AppTaskStartStk[1024/8]; /* 任务栈 */ 将任务栈定义成uint64_t类型可以保证任务栈是8字节对齐的,8字节对齐的含义就是数组的首地址对8求余等于0。如果不做8字节对齐的话,部分C语言库函数、浮点运算和uint64_t类型数据运算会出问题。 系统栈大小分配: RTX初始化: - /*
- *********************************************************************************************************
- * 函 数 名: main
- * 功能说明: 标准c程序入口。
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- int main (void)
- {
- /* 初始化外设 */
- bsp_Init();
-
- /* 创建启动任务 */
- os_sys_init_user (AppTaskStart, /* 任务函数 */
- 5, /* 任务优先级 */
- &AppTaskStartStk, /* 任务栈 */
- sizeof(AppTaskStartStk)); /* 任务栈大小,单位字节数 */
- while(1);
- }
复制代码
硬件外设初始化 硬件外设的初始化是在 bsp.c 文件实现: - /*
- *********************************************************************************************************
- * 函 数 名: bsp_Init
- * 功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void bsp_Init(void)
- {
- /*
- 由于ST固件库的启动文件已经执行了CPU系统时钟的初始化,所以不必再次重复配置系统时钟。
- 启动文件配置了CPU主时钟频率、内部Flash访问速度和可选的外部SRAM FSMC初始化。
-
- 系统时钟缺省配置为168MHz,如果需要更改,可以修改 system_stm32f4xx.c 文件
- */
- /* 优先级分组设置为4,可配置0-15级抢占式优先级,0级子优先级,即不存在子优先级。*/
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
-
- SystemCoreClockUpdate(); /* 根据PLL配置更新系统时钟频率变量 SystemCoreClock */
-
- bsp_InitDWT(); /* 初始化DWT */
- bsp_InitUart(); /* 初始化串口 */
- bsp_InitKey(); /* 初始化按键变量(必须在 bsp_InitTimer() 之前调用) */
-
- bsp_InitExtIO(); /* FMC总线上扩展了32位输出IO, 操作LED等外设必须初始化 */
- bsp_InitLed(); /* 初始LED指示灯端口 */
-
- BEEP_InitHard(); /* 初始化蜂鸣器 */
- bsp_InitDS18B20(); /* 初始化18B20 */
-
- bsp_InitRTC(); /* 初始化RTC时钟 */
- }
复制代码
RTX任务创建: - /*
- *********************************************************************************************************
- * 函 数 名: AppTaskCreate
- * 功能说明: 创建应用任务
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void AppTaskCreate (void)
- {
- HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF, /* 任务函数 */
- 1, /* 任务优先级 */
- &AppTaskUserIFStk, /* 任务栈 */
- sizeof(AppTaskUserIFStk)); /* 任务栈大小,单位字节数 */
-
- HandleTaskLED = os_tsk_create_user(AppTaskLED, /* 任务函数 */
- 2, /* 任务优先级 */
- &AppTaskLEDStk, /* 任务栈 */
- sizeof(AppTaskLEDStk)); /* 任务栈大小,单位字节数 */
-
- HandleTaskMsgPro = os_tsk_create_user(AppTaskMsgPro, /* 任务函数 */
- 3, /* 任务优先级 */
- &AppTaskMsgProStk, /* 任务栈 */
- sizeof(AppTaskMsgProStk)); /* 任务栈大小,单位字节数 */
-
- HandleTaskTCPMain = os_tsk_create_user(AppTaskTCPMain, /* 任务函数 */
- 4, /* 任务优先级 */
- &AppTaskTCPMainStk, /* 任务栈 */
- sizeof(AppTaskTCPMainStk)); /* 任务栈大小,单位字节数 */
- }
复制代码
五个RTX任务的实现:
RL-TCPnet功能测试 这里专门创建了一个app_tcpnet_lib.c文件用于RL-TCPnet功能的测试,此文件主要实现网络主函数main_TcpNet的调用。 - #include "includes.h"
-
-
-
- /*
- *********************************************************************************************************
- * 函 数 名: TCPnetTest
- * 功能说明: TCPent测试函数。
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void TCPnetTest(void)
- {
-
- while (1)
- {
- os_evt_wait_or(0x0001, 0xFFFF);
-
- /* RL-TCPnet主处理函数 */
- while (main_TcpNet() == __TRUE);
- }
- }
复制代码
HTTP_CGI.c文件中接口函数的实现 KEIL官网有提供HTTPCGI的接口文件,名为HTTP_CGI.c。我们就是在这个文件上修改实现,主要是函数cgi_func,其它函数未使用。具体实现内容如下: - #include <Net_Config.h>
- #include <stdio.h>
- #include <string.h>
- #include "bsp.h"
-
-
- /* ---------------------------------------------------------------------------
- * The HTTP server provides a small scripting language.
- *
- * The script language is simple and works as follows. Each script line starts
- * with a command character, either "i", "t", "c", "#" or ".".
- * "i" - command tells the script interpreter to "include" a file from the
- * virtual file system and output it to the web browser.
- * "t" - command should be followed by a line of text that is to be output
- * to the browser.
- * "c" - command is used to call one of the C functions from the this file.
- * It may be followed by the line of text. This text is passed to
- * 'cgi_func()' as a pointer to environment variable.
- * "#' - command is a comment line and is ignored (the "#" denotes a comment)
- * "." - denotes the last script line.
- *
- * --------------------------------------------------------------------------*/
-
- /* at_System.c */
- extern LOCALM localm[];
- #define LocM localm[NETIF_ETH]
-
- /* Net_Config.c */
- extern struct tcp_cfg tcp_config;
- extern struct http_cfg http_config;
- #define tcp_NumSocks tcp_config.NumSocks
- #define tcp_socket tcp_config.Scb
- #define http_EnAuth http_config.EnAuth
- #define http_auth_passw http_config.Passw
-
-
- extern volatile int16_t iTemp;
- extern RTC_TimeTypeDef RTC_TimeStructure;
-
- /* Local variables. */
- U8 LEDControl;
-
-
- /* My structure of CGI status U32 variable. This variable is private for */
- /* each HTTP Session and is not altered by HTTP Server. It is only set to */
- /* zero when the cgi_func() is called for the first time. */
- typedef struct {
- U16 xcnt;
- U16 unused;
- } MY_BUF;
- #define MYBUF(p) ((MY_BUF *)p)
-
- /*----------------------------------------------------------------------------
- * HTTP Server Common Gateway Interface Functions
- *---------------------------------------------------------------------------*/
-
- /*--------------------------- cgi_process_var -------------------------------*/
-
- void cgi_process_var (U8 *qs) {
- /* This function is called by HTTP server to process the Querry_String */
- /* for the CGI Form GET method. It is called on SUBMIT from the browser. */
- /*.The Querry_String.is SPACE terminated. */
- U8 *var;
- int s[4];
-
- var = (U8 *)alloc_mem (40);
- do {
- /* Loop through all the parameters. */
- qs = http_get_var (qs, var, 40);
- /* Check the returned string, 'qs' now points to the next. */
- if (var[0] != 0) {
- /* Returned string is non 0-length. */
- if (str_scomp (var, "ip=") == __TRUE) {
- /* My IP address parameter. */
- sscanf ((const char *)&var[3], "%d.%d.%d.%d",&s[0],&s[1],&s[2],&s[3]);
- LocM.IpAdr[0] = s[0];
- LocM.IpAdr[1] = s[1];
- LocM.IpAdr[2] = s[2];
- LocM.IpAdr[3] = s[3];
- }
- else if (str_scomp (var, "msk=") == __TRUE) {
- /* Net mask parameter. */
- sscanf ((const char *)&var[4], "%d.%d.%d.%d",&s[0],&s[1],&s[2],&s[3]);
- LocM.NetMask[0] = s[0];
- LocM.NetMask[1] = s[1];
- LocM.NetMask[2] = s[2];
- LocM.NetMask[3] = s[3];
- }
- else if (str_scomp (var, "gw=") == __TRUE) {
- /* Default gateway parameter. */
- sscanf ((const char *)&var[3], "%d.%d.%d.%d",&s[0],&s[1],&s[2],&s[3]);
- LocM.DefGW[0] = s[0];
- LocM.DefGW[1] = s[1];
- LocM.DefGW[2] = s[2];
- LocM.DefGW[3] = s[3];
- }
- else if (str_scomp (var, "pdns=") == __TRUE) {
- /* Default gateway parameter. */
- sscanf ((const char *)&var[5], "%d.%d.%d.%d",&s[0],&s[1],&s[2],&s[3]);
- LocM.PriDNS[0] = s[0];
- LocM.PriDNS[1] = s[1];
- LocM.PriDNS[2] = s[2];
- LocM.PriDNS[3] = s[3];
- }
- else if (str_scomp (var, "sdns=") == __TRUE) {
- /* Default gateway parameter. */
- sscanf ((const char *)&var[5], "%d.%d.%d.%d",&s[0],&s[1],&s[2],&s[3]);
- LocM.SecDNS[0] = s[0];
- LocM.SecDNS[1] = s[1];
- LocM.SecDNS[2] = s[2];
- LocM.SecDNS[3] = s[3];
- }
- }
- }while (qs);
- free_mem ((OS_FRAME *)var);
- }
-
-
- /*--------------------------- cgi_process_data ------------------------------*/
-
- void cgi_process_data (U8 code, U8 *dat, U16 len) {
- /* This function is called by HTTP server to process the returned Data */
- /* for the CGI Form POST method. It is called on SUBMIT from the browser. */
- /* Parameters: */
- /* code - callback context code */
- /* 0 = www-url-encoded form data */
- /* 1 = filename for file upload (0-terminated string) */
- /* 2 = file upload raw data */
- /* 3 = end of file upload (file close requested) */
- /* 4 = any xml encoded POST data (single or last stream) */
- /* 5 = the same as 4, but with more xml data to follow */
- /* Use http_get_content_type() to check the content type */
- /* dat - pointer to POST received data */
- /* len - received data length */
- U8 *var;
-
- switch (code) {
- case 0:
- /* Url encoded form data received. */
- break;
-
- case 1:
- /* Filename for file upload received as encoded by the browser. */
- /* It might contain an absolute path to a file from the sending */
- /* host. Open a file for writing. */
- return;
-
- case 2:
- /* File content data received. Write data to a file. */
- /* This function will be called several times with */
- /* code 2 when a big file is being uploaded. */
- return;
-
- case 3:
- /* File upload finished. Close a file. */
- return;
-
- case 4:
- /* XML encoded content type, last packet. */
- // pType = http_get_content_type ();
- /* check the content type for CGX file request. */
- /* pType is a pointer to a 0-terminated string */
- /* For example: text/xml; charset=utf-8 */
- return;
-
- case 5:
- /* XML encoded as under 4, but with more to follow. */
- return;
-
- default:
- /* Ignore all other codes. */
- return;
- }
-
- if (len == 0) {
- /* No data or all items (radio, checkbox) are off. */
- return;
- }
-
- var = (U8 *)alloc_mem (40);
-
- do {
- /* Parse all returned parameters. */
- dat = http_get_var (dat, var, 40);
- if (var[0] != 0) {
-
- }
- }while (dat);
- free_mem ((OS_FRAME *)var);
- }
-
- /*--------------------------- cgi_func --------------------------------------*/
-
- U16 cgi_func (U8 *env, U8 *buf, U16 buflen, U32 *pcgi) {
- /* This function is called by HTTP server script interpreter to make a */
- /* formated output for 'stdout'. It returns the number of bytes written */
- /* to the output buffer. Hi-bit of return value (len is or-ed with 0x8000)*/
- /* is a repeat flag for the system script interpreter. If this bit is set */
- /* to 1, the system will call the 'cgi_func()' again for the same script */
- /* line with parameter 'pcgi' pointing to a 4-byte buffer. This buffer */
- /* can be used for storing different status variables for this function. */
- /* It is set to 0 by HTTP Server on first call and is not altered by */
- /* HTTP server for repeated calls. This function should NEVER write more */
- /* than 'buflen' bytes to the buffer. */
- /* Parameters: */
- /* env - environment variable string */
- /* buf - HTTP transmit buffer */
- /* buflen - length of this buffer (500-1400 bytes - depends on MSS) */
- /* pcgi - pointer to session local buffer used for repeated loops */
- /* This is a U32 variable - size is 4 bytes. Value is: */
- /* - on 1st call = 0 */
- /* - 2nd call = as set by this function on first call */
- U32 len = 0;
-
- switch (env[0]) {
- /* Analyze the environment string. It is the script 'c' line starting */
- /* at position 2. What you write to the script file is returned here. */
- /* BEEP Input - xml file 'beep.cgx' */
- case 'q':
- switch (env[1]) {
- case '1':
- BEEP_Start(5, 1, 2);
- break;
- }
-
- len = 0;
- break;
-
- case 'g':
- /* DS18B20 Input - xml file 'ds180b20.cgi' */
- switch (env[2]) {
- case '1':
- RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure);
- len = sprintf((char *)buf,(const char *)&env[4], RTC_TimeStructure.RTC_Hours,
- RTC_TimeStructure.RTC_Minutes,
- RTC_TimeStructure.RTC_Seconds);
- break;
-
- case '2':
- len = sprintf((char *)buf,(const char *)&env[4],(float)iTemp/16);
- break;
- }
- break;
-
- case 'p':
- /* DS18B20 Input - xml file 'ds180b20.cgx' */
- RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure);
- len = sprintf((char *)buf,(const char *)&env[1], RTC_TimeStructure.RTC_Hours,
- RTC_TimeStructure.RTC_Minutes,
- RTC_TimeStructure.RTC_Seconds);
- break;
-
- case 'x':
- /* DS18B20 Input - xml file 'ds180b20.cgx' */
- len = sprintf((char *)buf,(const char *)&env[1], (float)iTemp/16);
- break;
-
- }
- return ((U16)len);
- }
-
- /*--------------------------- cgx_content_type ------------------------------*/
- #if 0
- U8 *cgx_content_type (void) {
- /* User configurable Content-type for CGX script files. If this function */
- /* is missing, or returns a NULL pointer, the default 'text/xml' content */
- /* type from the library is used for xml-script file types. */
- return ("text/xml; charset=utf-8");
- }
- #endif
-
- /*--------------------------- http_encoding ---------------------------------*/
-
- #if 0
- U8 *http_encoding (void) {
- /* User configurable character encoding for text types. If this function */
- /* is missing, or returns a NULL pointer, web browser uses a default */
- /* character encoding, which is set in the browser configuration. */
- return ("utf-8");
- }
- #endif
-
- /*--------------------------- http_accept_host ------------------------------*/
- #if 0
- BOOL http_accept_host (U8 *rem_ip, U16 rem_port) {
- /* This function checks if a connection from remote host is accepted or */
- /* not. If this function is missing, all remote hosts are accepted. */
-
- if (rem_ip[0] == 192 &&
- rem_ip[1] == 168 &&
- rem_ip[2] == 1 &&
- rem_ip[3] == 1) {
- /* Accept a connection. */
- return (__TRUE);
- }
- /* Deny a connection. */
- return (__FALSE);
- }
- #endif
-
- /*----------------------------------------------------------------------------
- * end of file
- *---------------------------------------------------------------------------*/
复制代码
|