这是本文档旧的修订版!
银杏科技有限公司旗下技术文档发布平台 | |||
技术支持电话 | 0379-69926675-801 | ||
技术支持邮件 | Gingko@vip.163.com | ||
技术论坛 | http://www.eeschool.org | ||
版本 | 日期 | 作者 | 修改内容 |
---|---|---|---|
V1.0 | 2020-07-11 | gingko | 初次建立 |
int main(void) { led.initialize(); //LED初始化 key.initialize(); if(ARM_KEY_STATE == KEY_UP){ //按键松开状态直接跳向应用程序 goto start; } 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 start: //测试用户代码是否从USER_FLASH_FIRST_PAGE_ADDRESS被编程 if (((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000) { /* 转跳到用户程序 */ JumpAddress = *(__IO uint32_t*) (USER_FLASH_FIRST_PAGE_ADDRESS + 4); Jump_To_Application = (pFunction) JumpAddress; /* 初始化用户应用程序的堆栈指针 */ __set_MSP(*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS); Jump_To_Application(); /* 什么都不做 */ while(1); }else{ //蓝绿LED灯循环点亮 while(1){ LED_GREEN_ON; LED_BLUE_OFF; delay.ms(500); LED_GREEN_OFF; LED_BLUE_ON; delay.ms(500); } } }
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(); //开中断 }
//内存管理初始化 void my_mem_init(u8 memx) { mymemset(mallco_dev.memmap[memx],0,memtblsize[memx]*4); //内存状态表数据清零 mallco_dev.memrdy[memx]=1; //内存管理初始化OK }
//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 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; }
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; unsigned char data[MAX_URI_SIZE]; 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; FLASH_If_Init();//解锁 //擦除FLASH if(FLASH_If_Erase(USER_FLASH_FIRST_PAGE_ADDRESS)){ LED_RED_ON; }; FlashWriteAddress = USER_FLASH_FIRST_PAGE_ADDRESS; rx_len = wr_len; //从USER_FLASH_FIRST_PAGE_ADDRESS地址写入数据 for(cnt = 0;cnt < wr_len ;cnt++){ *(data + cnt) = *(recv_buffer + start_buf + cnt); if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, FlashWriteAddress + cnt, *(uint32_t*)(data + cnt)) != HAL_OK) { LED_RED_ON;//写入失败,红灯亮 } } 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++){ if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, FlashWriteAddress + rx_len + cnt, *(uint32_t*)(recv_buffer + cnt)) != HAL_OK) { LED_RED_ON; } } 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++){ if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, FlashWriteAddress + rx_len + cnt, *(uint32_t*)(recv_buffer + cnt)) != HAL_OK) { LED_RED_ON;//写入失败,红灯亮 } } 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)); FLASH->ACR|=1<<10; HAL_FLASH_Lock();//锁FLASH LED_BLUE_OFF; LED_GREEN_ON; while(1); } } } LED_RED_ON;//升级失败,红灯亮 } break; //从uri获取文件名 default : break; } close(httpcon);