这是本文档旧的修订版!
银杏科技有限公司旗下技术文档发布平台 | |||
技术支持电话 | 0379-69926675-801 | ||
技术支持邮件 | Gingko@vip.163.com | ||
技术论坛 | http://www.eeschool.org | ||
版本 | 日期 | 作者 | 修改内容 |
---|---|---|---|
V1.0 | 2020-07-11 | gingko | 初次建立 |
int main(void) { GPIO_InitTypeDef GPIO_InitStruct; __HAL_RCC_GPIOI_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); HAL_GPIO_WritePin(GPIOH, GPIO_PIN_6|GPIO_PIN_8, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOI, GPIO_PIN_3, GPIO_PIN_SET); /*配置GPIO引脚 : PI8 */ GPIO_InitStruct.Pin = GPIO_PIN_8; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOI, &GPIO_InitStruct); /*配置GPIO引脚 : PH6 PH8 */ GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_8; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; HAL_GPIO_Init(GPIOH, &GPIO_InitStruct); /*配置GPIO引脚 : PH7 */ GPIO_InitStruct.Pin = GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOH, &GPIO_InitStruct); /*配置GPIO引脚 : PI3 */ GPIO_InitStruct.Pin = GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; HAL_GPIO_Init(GPIOI, &GPIO_InitStruct); led.initialize(); //LED初始化 key.initialize(); system_clock.initialize(); //系统时钟初始化 delay.initialize(216); //延时初始化 adc.initialize(); //AD初始化 my_malloc.initialize(SRAMIN); //动态内存初始化 usart6.initialize(115200); //串口波特设置 OSInit(); //UCOS初始化 while(lwip.initialize()) //lwip初始化 { LED_RED_ON; usart6.printf("\r\nETH initialize error!\r\n\r\n");//ETH初始化失败 } web.initialize(); //WEB初始化 OSTaskCreate(start_task,(void*)0,(OS_STK*)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO); OSStart(); //开启UCOS }
void start_task(void *pdata) { OS_CPU_SR cpu_sr; pdata = pdata ; OSStatInit(); //初始化统计任务 OS_ENTER_CRITICAL(); //关中断 #if LWIP_DHCP lwip_comm_dhcp_creat(); //创建DHCP任务 #if LWIP_DNS my_dns.initialize(); //创建DNS任务 #endif #endif OSTaskCreate(display_task,(void*)0,(OS_STK*)&DISPLAY_TASK_STK[DISPLAY_STK_SIZE-1],DISPLAY_TASK_PRIO); //显示任务 OSTaskSuspend(OS_PRIO_SELF); //挂起start_task任务 OS_EXIT_CRITICAL(); //开中断 }
static INT8U http_server_netconn_init(void)//动态刷新页面显示任务 { INT8U res; OS_CPU_SR cpu_sr; OS_ENTER_CRITICAL(); //关中断 res = OSTaskCreate(http_server_netconn_thread,(void*)0,(OS_STK*)&WEB_TASK_STK[WEB_STK_SIZE-1],WEB_PRIO); //创建TCP服务器线程 OS_EXIT_CRITICAL(); //开中断 return res; }
//LWIP初始化(LWIP启动的时候使用) u8 lwip_comm_init(void) { OS_CPU_SR cpu_sr; struct netif *Netif_Init_Flag; //调用netif_add()函数时的返回值,用于判断网络初始化是否成功 struct ip_addr ipaddr; //ip地址 struct ip_addr netmask; //子网掩码 struct ip_addr gw; //默认网关 if(lan8720.memory_malloc())return 1; //内存申请失败 if(lwip_comm_mem_malloc())return 1; //内存申请失败 if(lan8720.initialize())return 2; //初始化LAN8720失败 tcpip_init(NULL,NULL); //初始化tcp ip内核,该函数里面会创建tcpip_thread内核任务 lwip_comm_default_ip_set(&lwipdev); //设置默认IP等信息 #if LWIP_DHCP //使用动态IP ipaddr.addr = 0; netmask.addr = 0; gw.addr = 0; #else //使用静态IP IP4_ADDR(&ipaddr,lwipdev.ip[0],lwipdev.ip[1],lwipdev.ip[2],lwipdev.ip[3]); IP4_ADDR(&netmask,lwipdev.netmask[0],lwipdev.netmask[1] ,lwipdev.netmask[2],lwipdev.netmask[3]); IP4_ADDR(&gw,lwipdev.gateway[0],lwipdev.gateway[1],lwipdev.gateway[2],lwipdev.gateway[3]); usart6.printf("网卡en的MAC地址为:................%d.%d.%d.%d.%d.%d\r\n",lwipdev.mac[0],lwipdev.mac[1],lwipdev.mac[2],lwipdev.mac[3],lwipdev.mac[4],lwipdev.mac[5]); usart6.printf("静态IP地址........................%d.%d.%d.%d\r\n",lwipdev.ip[0],lwipdev.ip[1],lwipdev.ip[2],lwipdev.ip[3]); usart6.printf("子网掩码..........................%d.%d.%d.%d\r\n",lwipdev.netmask[0],lwipdev.netmask[1],lwipdev.netmask[2],lwipdev.netmask[3]); usart6.printf("默认网关..........................%d.%d.%d.%d\r\n",lwipdev.gateway[0],lwipdev.gateway[1],lwipdev.gateway[2],lwipdev.gateway[3]); #endif Netif_Init_Flag=netif_add(&lwip_netif,&ipaddr,&netmask,&gw,NULL,ðernetif_init,&tcpip_input);//向网卡列表中添加一个网口 #if LWIP_DNS dns_init(); #endif if(Netif_Init_Flag==NULL)return 3;//网卡添加失败 else//网口添加成功后,设置netif为默认值,并且打开netif网口 { netif_set_default(&lwip_netif); //设置netif为默认网口 netif_set_up(&lwip_netif); //打开netif网口 } return 0;//操作OK. }
static void http_server_serve(int httpcon) { int i; unsigned char recv_buffer[MAX_URI_SIZE]; unsigned long int file_len = 0; unsigned short int send_len = 0; char* name; //获取方法请求文件名 char req_name[32]={0x00,}; //发布方法请求文件名 unsigned long int content_len=0; unsigned long int rx_len = 0,start_buf=0; long int cnt; char sub[10]; char *p; long int wr_len = 0; unsigned long int tmp_len=0; char data; int receive_length = 0; char boundary[64],endbound[64]; static __IO uint32_t FlashWriteAddress; unsigned char* http_response; st_http_request *http_request; receive_length = read(httpcon, recv_buffer, MAX_URI_SIZE); //提取http数据请求 http_response = (unsigned char*)recv_buffer; memset(tx_buf,0x00,MAX_URI_SIZE); http_request = (st_http_request*)tx_buf; parse_http_request(http_request, recv_buffer); // 分析请求后,转换为http_request //方法分析 switch (http_request->METHOD) { case METHOD_ERR : memcpy(http_response, ERROR_REQUEST_PAGE, sizeof(ERROR_REQUEST_PAGE)); write(httpcon, (unsigned char *)http_response, strlen((char const*)recv_buffer)); break; case METHOD_HEAD: case METHOD_GET: //从uri获取文件名 name = http_request->URI; if(strcmp(name,"/index.htm")==0 || strcmp(name,"/")==0 || (strncmp(name,"/index.html",11)==0)) { file_len = strlen(ALLOCATION_HTML); make_http_response_head((unsigned char*)http_response, PTYPE_HTML,file_len); write(httpcon, (unsigned char *)http_response, strlen((char const*)recv_buffer)); send_len=0; while(file_len) { if(file_len>1024) { write(httpcon, (const unsigned char*)ALLOCATION_HTML+send_len, 1024); send_len+=1024; file_len-=1024; } else { write(httpcon, (const unsigned char*)ALLOCATION_HTML+send_len, file_len); send_len+=file_len; file_len-=file_len; } } }else if(strcmp(name,"/demo_get.asp") == 0){ make_measure_response(tx_buf); sprintf((char *)recv_buffer,"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length:%d\r\n\r\n%s",strlen(tx_buf),tx_buf); write(httpcon, (unsigned char *)recv_buffer, strlen((char *)recv_buffer)); } break; /*POST方法*/ case METHOD_POST: mid(http_request->URI, "/", " ", req_name); if(strcmp(req_name,"upload.cgi") == 0){ LED_BLUE_ON; //进入升级文件指示灯 mid(http_request->URI,"boundary=", "\r\n", (char*)boundary); //获取内容长度 mid(http_request->URI,"Content-Length: ","\r\n",sub); content_len = ATOI32(sub,10); p = strstr((char*)http_request->URI,boundary); p += strlen(boundary); p = strstr(p,boundary); rx_len = p - http_request->URI; rx_len = receive_length - rx_len + 2; p = strstr((char*)http_request->URI,"octet-stream\r\n\r\n"); p += strlen("octet-stream\r\n\r\n"); wr_len = p - http_request->URI + 5; start_buf = wr_len ; wr_len = receive_length - start_buf; NCONFIG_OFF; DCLK_OFF; for(i = 0; i < 5000; i++); if(NSTATUS == 1) { LED_BLUE_ON; while(1); } for(i = 0;i < 40;i++); NCONFIG_ON; for(i = 0; i < 40; i++); for(cnt = 0;cnt < wr_len;cnt++){ data = *(recv_buffer + start_buf + cnt); for(i = 0; i < 8; i++) { if(data&0x01)DATA0_ON; else DATA0_OFF; DCLK_ON; data >>= 1; DCLK_OFF; } } while(rx_len <= content_len) { memset(recv_buffer,0x00,MAX_URI_SIZE); tmp_len = read(httpcon, recv_buffer, MAX_URI_SIZE); if(tmp_len > (strlen(boundary) + 8)) { for(i = 0; i < strlen(boundary);i ++){ endbound[i] = recv_buffer[tmp_len - strlen(boundary) + i - 4]; } //判断有没有获取到结束标志字符串boundary if(strncmp(endbound,boundary,strlen(boundary)) !=0){ if(tmp_len > MAX_URI_SIZE) tmp_len = MAX_URI_SIZE; start_buf = tmp_len; for(cnt = 0;cnt < tmp_len ;cnt++){ data = *(recv_buffer + cnt); for(i = 0; i < 8; i++) { if(data&0x01)DATA0_ON; else DATA0_OFF; DCLK_ON; data >>= 1; DCLK_OFF; } } rx_len += tmp_len; tmp_len = 0; }else{ if(tmp_len > MAX_URI_SIZE) tmp_len = MAX_URI_SIZE; //将除去获取的结束标识字符串boundary的数据,写入FLASH start_buf = tmp_len - strlen(boundary) - 8; for(cnt = 0;cnt < start_buf ;cnt++){ data = *(recv_buffer + cnt); for(i = 0; i < 8; i++) { if(data&0x01)DATA0_ON; DCLK_ON; data >>= 1; DCLK_OFF; } } rx_len += tmp_len; tmp_len = 0; /*写入flash数据结束,返回http OK */ make_upload_response(tx_buf); sprintf((char *)http_response,"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length:%d\r\n\r\n%s",strlen(tx_buf),tx_buf); write(httpcon, (unsigned char *)http_response, strlen((char const*)recv_buffer)); if(CONFIG_DONE == 1){ LED_BLUE_OFF; LED_GREEN_ON; }else{ LED_BLUE_ON; } for(i = 0; i < 40; i++) { DCLK_ON; for(i = 0; i < 800; i++);//延时100us DCLK_OFF; for(i = 0; i < 800; i++);//延时 100us } while(1); } } } LED_RED_ON;//升级失败,红灯亮 } break; //从uri获取文件名 default : break; } close(httpcon); }