历时5个工作日,总算把以太网远程远程固件升级功能完成,期间踩了不少的坑。最初设计的时候参照stm32官方1.26.1标准固件HAL库,新建一个工程,把官方对应的驱动移植到新的工程底下。
因为使用以太网方式BootLoader,由于以太网占用内存及ROM空间比较大,故从0x08000000—0x08020000处128KROM空间分配给BootLoader程序,从0x08020000—0x080FFFFF处896KROM空间分配给用户程序。
分配空间,下载BootLoader程序到主板上,使用http登陆到下载程序界面,点击下载,然后复位,结果用户程序未执行,未能成功。
使用烧录器烧录用户程序到0x08020000处,使用BootLoader引导对比测试,发现跳转以后用户程序正常运行。说明跳转过程没有问题,BootLoader程序跳转正常。通过汇编单步调试,定位到跳转到HardFault_Handler错误中断前代码地址0x080209C0处。同时在同一地址处,比较BootLoader烧录代码与烧录器烧录代码差异,发现在0x080209DA地址处发生了代码差异。故此现象由于FLASH存储的代码差异引起,可能原因如下:
- BootLoader程序接收http传输bin文件发生了错误
- BootLoader程序写FLASH发生了错误
- 编译器生成bin文件发生了错误
最容易排查的是http传输问题。测试使用http接收数据转发网络日志存储,通过存储发现,发送6000多字节,实际接收2000多个字节,判定接收异常。
?????? 同时对比使用http调试助手模拟http服务器,测试发现,模拟服务器能够接收完整的数据,判定web客户端发送正常。
同步通过日志打印,最终发现,官方的例程驱动移植过来,连续接收网络数据存在网络丢包现象,故官方的网络驱动接收存在bug,然后重新设计网络驱动程序。最终完美完成远程web方式固件升级。关键代码如下:
#include "lwip/debug.h" #include "lwip/stats.h" #include "lwip/tcp.h" #include "fsdata.h" #include "fsdata.c" #include "main.h" #include "flash_if.h" #include <string.h> #include <stdio.h>
struct fs_file { ? char *data; ? int len; };
struct http_state { ? char *file; ? u32_t left; };
typedef enum? { ? LoginPage = 0, ? FileUploadPage, ? UploadDonePage, ? ResetDonePage }htmlpageState; ?? htmlpageState htmlpage; ? static const char http_crnl_2[4] =? /* "\r\n--" */ {0xd, 0xa,0x2d,0x2d}; static const char octet_stream[14] =? /* "octet-stream" */ {0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d,0x0d, }; static const char Content_Length[17] =? /* Content Length */ {0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67,0x74, 0x68, 0x3a, 0x20, };
static __IO uint32_t DataFlag=0; static __IO uint32_t size =0; __IO uint32_t FlashWriteAddress; static uint32_t TotalReceived=0; static char LeftBytesTab[4]; static uint8_t LeftBytes=0; static __IO uint8_t resetpage=0; static uint32_t ContentLengthOffset =0,BrowserFlag=0; static __IO uint32_t TotalData=0, checklogin=0;? void IAP_HTTP_writedata(char * ptr, uint32_t len);
#if LWIP_TCP static struct tcp_pcb *tcp_echoserver_pcb;
/* ECHO protocol states */ enum tcp_echoserver_states { ? ES_NONE = 0, ? ES_ACCEPTED, ? ES_RECEIVED, ? ES_CLOSING };
/* structure for maintaing connection infos to be passed as argument? ? ?to LwIP callbacks*/ struct tcp_echoserver_struct { ? u8_t state; ? ? ? ? ? ? /* current connection state */ ? u8_t retries; ? struct tcp_pcb *pcb; ? ?/* pointer on the current tcp_pcb */ ? struct pbuf *p; ? ? ? ? /* pointer on the received/to be transmitted pbuf */ };
static err_t tcp_echoserver_accept(void *arg, struct tcp_pcb *newpcb, err_t err); static err_t tcp_echoserver_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err); static void tcp_echoserver_error(void *arg, err_t err); static err_t tcp_echoserver_poll(void *arg, struct tcp_pcb *tpcb); static err_t tcp_echoserver_sent(void *arg, struct tcp_pcb *tpcb, u16_t len); static void tcp_echoserver_send(struct tcp_pcb *tpcb, struct tcp_echoserver_struct *es); static void tcp_echoserver_connection_close(struct tcp_pcb *tpcb, struct tcp_echoserver_struct *es);
static int fs_open(char *name, struct fs_file *file) { ?? ?struct fsdata_file_noconst *f; ?? ?for (f = (struct fsdata_file_noconst *)FS_ROOT; f != NULL; f = (struct fsdata_file_noconst *)f->next) ?? ?{ ?? ??? ?if (!strcmp(name, f->name)) ?? ??? ?{ ?? ??? ??? ?file->data = f->data; ?? ??? ??? ?file->len = f->len; ?? ??? ??? ?return 1; ?? ??? ?} ?? ?} ?? ?return 0; } static uint32_t Parse_Content_Length(char *data, uint32_t len) { ?? ?uint32_t i=0,size=0, S=1; ?? ?int32_t j=0; ?? ?char sizestring[6], *ptr;
?? ?ContentLengthOffset =0;
?? ?/* find Content-Length data in packet buffer */ ?? ?for (i=0;i<len;i++) ?? ?{ ?? ??? ?if (strncmp ((char*)(data+i), Content_Length, 16)==0) ?? ??? ?{ ?? ??? ??? ?ContentLengthOffset = i+16; ?? ??? ??? ?break; ?? ??? ?} ?? ?} ?? ?/* read Content-Length value */ ?? ?if (ContentLengthOffset) ?? ?{ ?? ??? ?i=0; ?? ??? ?ptr = (char*)(data + ContentLengthOffset); ?? ??? ?while(*(ptr+i)!=0x0d) ?? ??? ?{ ?? ??? ??? ?sizestring[i] = *(ptr+i); ?? ??? ??? ?i++; ?? ??? ??? ?ContentLengthOffset++;? ?? ??? ?} ?? ??? ?if (i>0) ?? ??? ?{ ?? ??? ??? ?/* transform string data into numeric format */ ?? ??? ??? ?for(j=i-1;j>=0;j--) ?? ??? ??? ?{ ?? ??? ??? ??? ?size += (sizestring[j]-'0')*S; ?? ??? ??? ??? ?S=S*10; ?? ??? ??? ?} ?? ??? ?} ?? ?} ?? ?return size; }
void tcp_echoserver_init(void) { ?? ?err_t err; ?? ?tcp_echoserver_pcb = tcp_new();?? ??? ??? ??? ??? ??? ??? ??? ?/* create new tcp pcb */ ?? ?if (tcp_echoserver_pcb != NULL) ?? ?{?? ? ?? ??? ?err = tcp_bind(tcp_echoserver_pcb, IP_ADDR_ANY, 80);?? ??? ?/* bind echo_pcb to port 7 (ECHO protocol) */ ?? ??? ?if (err == ERR_OK) ?? ??? ?{?? ??? ? ?? ??? ??? ?tcp_echoserver_pcb = tcp_listen(tcp_echoserver_pcb);?? ?/* start tcp listening for echo_pcb */?? ??? ??? ? ?? ??? ??? ?tcp_accept(tcp_echoserver_pcb, tcp_echoserver_accept);?? ?/* initialize LwIP tcp_accept callback function */ ?? ??? ?}?? ? ?? ??? ?else? ?? ??? ?{?? ??? ? ?? ??? ??? ?memp_free(MEMP_TCP_PCB, tcp_echoserver_pcb);?? ??? ??? ?/* deallocate the pcb */ ?? ??? ?} ?? ?} }
static err_t tcp_echoserver_accept(void *arg, struct tcp_pcb *newpcb, err_t err) { ?? ?err_t ret_err; ?? ?struct tcp_echoserver_struct *es;
?? ?LWIP_UNUSED_ARG(arg); ?? ?LWIP_UNUSED_ARG(err); ?? ?tcp_setprio(newpcb, TCP_PRIO_MIN);?? ??? ??? ?/* set priority for the newly accepted tcp connection newpcb */ ?? ?/* allocate structure es to maintain tcp connection informations */ ?? ?es = (struct tcp_echoserver_struct *)mem_malloc(sizeof(struct tcp_echoserver_struct)); ?? ?if (es != NULL) ?? ?{ ?? ??? ?es->state = ES_ACCEPTED; ?? ??? ?es->pcb = newpcb; ?? ??? ?es->retries = 0; ?? ??? ?es->p = NULL;?? ??? ? ?? ??? ?tcp_arg(newpcb, es);?? ??? ??? ??? ??? ??? ?/* pass newly allocated es structure as argument to newpcb */?? ? ?? ??? ?tcp_recv(newpcb, tcp_echoserver_recv);?? ??? ?/* initialize lwip tcp_recv callback function for newpcb ?*/ ?? ??? ? ?? ??? ?tcp_err(newpcb, tcp_echoserver_error);?? ??? ?/* initialize lwip tcp_err callback function for newpcb ?*/?? ??? ? ?? ??? ?tcp_poll(newpcb, tcp_echoserver_poll, 0);?? ?/* initialize lwip tcp_poll callback function for newpcb */ ?? ??? ?ret_err = ERR_OK; ?? ?} ?? ?else ?? ?{?? ??? ? ?? ??? ?tcp_echoserver_connection_close(newpcb, es);?? ?/* ?close tcp connection */?? ??? ? ?? ??? ?ret_err = ERR_MEM;?? ??? ??? ??? ??? ??? ??? ??? ?/* return memory error */ ?? ?} ?? ?return ret_err; ? }
static err_t tcp_echoserver_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { ?? ?struct tcp_echoserver_struct *es; ?? ?err_t ret_err; ?? ?struct pbuf *ptr; ?? ?LWIP_ASSERT("arg != NULL",arg != NULL); ?? ?es = (struct tcp_echoserver_struct *)arg; ?? ?/* if we receive an empty tcp frame from client => close connection */ ?? ?if (p == NULL) ?? ?{?? ??? ? ?? ??? ?es->state = ES_CLOSING;?? ??? ??? ??? ??? ??? ??? ?/* remote host closed connection */ ?? ??? ?if(es->p == NULL) ?? ??? ?{?? ??? ? ?? ??? ??? ?tcp_echoserver_connection_close(tpcb, es);?? ?/* we're done sending, close connection */ ?? ??? ?} ?? ??? ?else ?? ??? ?{?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?/* we're not done yet */?? ??? ? ?? ??? ??? ?tcp_sent(tpcb, tcp_echoserver_sent);?? ??? ?/* acknowledge received packet */?? ??? ??? ? ?? ??? ??? ?tcp_echoserver_send(tpcb, es);?? ??? ??? ??? ?/* send remaining data*/ ?? ??? ?} ?? ??? ?ret_err = ERR_OK; ?? ?} ?? ?? ?/* else : a non empty frame was received from client but for some reason err != ERR_OK */ ?? ?else if(err != ERR_OK) ?? ?{?? ??? ? ?? ??? ?if (p != NULL)?? ??? ??? ??? ??? ??? ??? ??? ??? ?/* free received pbuf*/ ?? ??? ?{ ?? ??? ??? ?es->p = NULL; ?? ??? ??? ?pbuf_free(p); ?? ??? ?} ?? ??? ?ret_err = err; ?? ?} ?? ?else if(es->state == ES_ACCEPTED) ?? ?{?? ??? ? ?? ??? ?es->state = ES_RECEIVED;?? ??? ??? ??? ??? ??? ?/* first data chunk in p->payload */?? ??? ? ?? ??? ?es->p = p;?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?/* store reference to incoming pbuf (chain) */?? ??? ? ?? ??? ?tcp_sent(tpcb, tcp_echoserver_sent);?? ??? ??? ?/* initialize LwIP tcp_sent callback function */?? ??? ? ?? ??? ?tcp_echoserver_send(tpcb, es);?? ??? ??? ??? ??? ?/* send back the received data (echo) */ ?? ??? ?ret_err = ERR_OK; ?? ?} ?? ?else if (es->state == ES_RECEIVED) ?? ?{ ?? ??? ?/* more data received from client and previous data has been already sent*/ ?? ??? ?if(es->p == NULL) ?? ??? ?{ ?? ??? ??? ?es->p = p;?? ??? ??? ? ?? ??? ??? ?tcp_echoserver_send(tpcb, es);?? ??? ??? ??? ?/* send back received data */ ?? ??? ?} ?? ??? ?else ?? ??? ?{?? ??? ??? ? ?? ??? ??? ?ptr = es->p;?? ??? ??? ??? ??? ??? ??? ??? ?/* chain pbufs to the end of what we recv'ed previously ?*/ ?? ??? ??? ?pbuf_chain(ptr,p); ?? ??? ?} ?? ??? ?ret_err = ERR_OK; ?? ?} ?? ?else if(es->state == ES_CLOSING) ?? ?{?? ? ?? ??? ?tcp_recved(tpcb, p->tot_len);?? ??? ??? ??? ??? ?/* odd case, remote side closing twice, trash data */ ?? ??? ?es->p = NULL; ?? ??? ?pbuf_free(p); ?? ??? ?ret_err = ERR_OK; ?? ?} ?? ?else ?? ?{?? ??? ? ?? ??? ?tcp_recved(tpcb, p->tot_len);?? ??? ??? ??? ??? ?/* unkown es->state, trash data ?*/ ?? ??? ?es->p = NULL; ?? ??? ?pbuf_free(p); ?? ??? ?ret_err = ERR_OK; ?? ?} ?? ?return ret_err; }
static void tcp_echoserver_error(void *arg, err_t err) { ?? ?struct tcp_echoserver_struct *es; ?? ?LWIP_UNUSED_ARG(err); ?? ?es = (struct tcp_echoserver_struct *)arg; ?? ?if (es != NULL) ?? ?{?? ??? ? ?? ??? ?mem_free(es);?? ??? ??? ??? ??? ??? ??? ??? ?/* ?free es structure */ ?? ?} }
static err_t tcp_echoserver_poll(void *arg, struct tcp_pcb *tpcb) { ?? ?err_t ret_err; ?? ?struct tcp_echoserver_struct *es; ?? ?es = (struct tcp_echoserver_struct *)arg; ?? ?if (es != NULL) ?? ?{ ?? ??? ?if (es->p != NULL) ?? ??? ?{ ?? ??? ??? ?tcp_sent(tpcb, tcp_echoserver_sent);?? ??? ? ?? ??? ??? ?tcp_echoserver_send(tpcb, es);?? ??? ??? ?/* there is a remaining pbuf (chain) , try to send data */ ?? ??? ?} ?? ??? ?else ?? ??? ?{?? ??? ? ?? ??? ??? ?if(es->state == ES_CLOSING)?? ??? ??? ??? ?/* no remaining pbuf (chain) ?*/ ?? ??? ??? ?{?? ??? ??? ? ?? ??? ??? ??? ?tcp_echoserver_connection_close(tpcb, es);?? ?/* ?close tcp connection */ ?? ??? ??? ?} ?? ??? ?} ?? ??? ?ret_err = ERR_OK; ?? ?} ?? ?else ?? ?{?? ? ?? ??? ?tcp_abort(tpcb);?? ??? ??? ??? ??? ??? ??? ??? ?/* nothing to be done */ ?? ??? ?ret_err = ERR_ABRT; ?? ?} ?? ?return ret_err; }
static err_t tcp_echoserver_sent(void *arg, struct tcp_pcb *tpcb, u16_t len) { ?? ?struct tcp_echoserver_struct *es; ?? ?LWIP_UNUSED_ARG(len); ?? ?es = (struct tcp_echoserver_struct *)arg; ?? ?es->retries = 0; ?? ?if(es->p != NULL) ?? ?{ ?? ??? ?/* still got pbufs to send */ ?? ??? ?tcp_sent(tpcb, tcp_echoserver_sent); ?? ??? ?tcp_echoserver_send(tpcb, es); ?? ?} ?? ?else ?? ?{ ?? ??? ?/* if no more data to send and client closed connection*/ ?? ??? ?if(es->state == ES_CLOSING) ?? ??? ??? ?tcp_echoserver_connection_close(tpcb, es); ?? ?} ?? ?return ERR_OK; }
err_t TcpSend(unsigned char *pData,int len); void TcpPrintf(const char *format, ...); u8_t ?g_recvBuff[1500]; unsigned int g_len = 0; unsigned int g_bootBytes=0; unsigned char g_recvData[10240]; void WebAnalysis(char *data,int len,struct tcp_pcb *tpcb) { ?? ?uint32_t DataOffset, FilenameOffset; ?? ?char ?*ptr,filename[40], login[LOGIN_SIZE+1]; ?? ?struct fs_file file = {0, 0}; ?? ?struct http_state *hs; ?? ?struct pbuf *ptrData; ?? ?int i; ?? ??? ? ?? ?if (strncmp(data, "GET / HTTP", 10) == 0)?? ??? ??? ??? ?//首页登陆界面 ?? ?{ ?? ??? ?htmlpage = LoginPage; ?? ??? ?fs_open("/index.html", &file); ?? ??? ?tcp_write(tpcb, file.data, file.len, 1); ?? ?} ?? ?else if ((strncmp(data, "GET /resetmcu.cgi", 17) ==0)&&(htmlpage == UploadDonePage))?? ?//复位界面 ?? ?{ ?? ??? ?htmlpage = ResetDonePage; ?? ??? ?fs_open("/reset.html", &file); ?? ??? ?tcp_write(tpcb, file.data, file.len, 1); ?? ??? ?resetpage = 1; ?? ?} ?? ?else if ((strncmp(data, "POST /checklogin.cgi",20)==0)&&(htmlpage== LoginPage)) ?? ?{ ?? ??? ?ptr = strstr(data,"username="); ?? ??? ?if(ptr != NULL) ?? ??? ?{ ?? ??? ??? ?sprintf((char *)login,"username=%s&password=%s",USERID,PASSWORD); ?? ??? ??? ?if (strncmp(ptr, (char *)login ,LOGIN_SIZE)==0) ?? ??? ??? ?{ ?? ??? ??? ??? ?htmlpage = FileUploadPage; ?? ??? ??? ??? ?fs_open("/upload.html", &file); ?? ??? ??? ?} ?? ??? ??? ?else ?? ??? ??? ?{ ?? ??? ??? ??? ?htmlpage = LoginPage; ?? ??? ??? ??? ?fs_open("/index.html", &file); ?? ??? ??? ?} ?? ??? ??? ?tcp_write(tpcb, file.data, file.len, 1); ?? ??? ?} ?? ?? ?} ?? ?else if (strncmp(data, "POST /upload.cgi",16)==0||DataFlag >=1) ?? ?{? ?? ??? ?DataOffset =0; ?? ??? ?if (DataFlag ==0) ?? ??? ?{? ?? ??? ??? ?BrowserFlag=0; ?? ??? ??? ?TotalReceived =0; ?? ??? ??? ?size = Parse_Content_Length(data, len);?? ??? ? ?? ??? ??? ?ptr = strstr(data,octet_stream); ?? ??? ??? ?if(ptr != NULL) ?? ??? ??? ?{ ?? ??? ??? ??? ?DataOffset = ptr - data + 16; ?? ??? ??? ?} ?? ??? ??? ?if (DataOffset==0) ?? ??? ??? ?{ ?? ??? ??? ??? ?DataFlag++; ?? ??? ??? ??? ?BrowserFlag = 1; ?? ??? ??? ??? ?return; ?? ??? ??? ?} ?? ??? ??? ?else ?? ??? ??? ?{ ?? ??? ??? ??? ?TotalReceived = len - (ContentLengthOffset + 4); ?? ??? ??? ?} ?? ??? ?} ?? ??? ?if (((DataFlag ==1)&&(BrowserFlag==1)) || ((DataFlag ==0)&&(BrowserFlag==0))) ?? ??? ?{? ?? ??? ??? ?if ((DataFlag ==0)&&(BrowserFlag==0))? ?? ??? ??? ?{ ?? ??? ??? ??? ?DataFlag++; ?? ??? ??? ?} ?? ??? ??? ?else if ((DataFlag ==1)&&(BrowserFlag==1)) ?? ??? ??? ?{?? ??? ??? ? ?? ??? ??? ??? ?ptr = strstr(data,octet_stream); ?? ??? ??? ??? ?if(ptr != NULL) ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?DataOffset = ptr - data + 16; ?? ??? ??? ??? ?} ?? ??? ??? ??? ?TotalReceived+=len; ?? ??? ??? ??? ?DataFlag++; ?? ??? ??? ?} ? ?? ??? ??? ?FilenameOffset = 0; ?? ??? ??? ?ptr = strstr(data,"filename="); ?? ??? ??? ?if(ptr != NULL) ?? ??? ??? ?{ ?? ??? ??? ??? ?FilenameOffset = ptr - data + 16; ?? ??? ??? ?} ? ? ? ?? ?? ??? ??? ?i =0; ?? ??? ??? ?if (FilenameOffset) ?? ??? ??? ?{ ?? ??? ??? ??? ?while((*(data+FilenameOffset + i)!=0x22 )&&(i < 40)) ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?filename[i] = *(data+FilenameOffset + i); ?? ??? ??? ??? ??? ?i++; ?? ??? ??? ??? ?} ?? ??? ??? ??? ?filename[i] = 0x0; ?? ??? ??? ?} ?? ??? ??? ?if (i==0) ?? ??? ??? ?{ ?? ??? ??? ??? ?htmlpage = FileUploadPage; ?? ??? ??? ??? ?fs_open("/upload.html", &file); ?? ??? ??? ??? ?tcp_write(tpcb, file.data, file.len, 1); ?? ??? ??? ??? ?DataFlag=0; ?? ??? ??? ??? ?return; ?? ??? ??? ?} ?? ??? ??? ?TotalData =0; ?? ??? ??? ?FLASH_If_Init(); ?? ??? ??? ?FLASH_If_Erase(USER_FLASH_FIRST_PAGE_ADDRESS); ?? ??? ??? ?FlashWriteAddress = USER_FLASH_FIRST_PAGE_ADDRESS; //?? ??? ??? ?TcpPrintf(" ?State: Programming...\n"); ?? ??? ??? ?g_bootBytes = 0; ?? ??? ?} ?? ??? ?else? ?? ??? ?{ ?? ??? ??? ?TotalReceived +=len; ?? ??? ?} ?? ??? ?ptr = (char*)(data + DataOffset); ?? ??? ?len-= DataOffset; ?? ??? ?TotalData +=len; ?? ??? ?if (TotalReceived == size) ?? ??? ?{ ?? ??? ??? ?i=4;? ?? ??? ??? ?while (strncmp ((char*)(data+ len -i),http_crnl_2 , 4) && (len -i > 0)) ?? ??? ??? ?{ ?? ??? ??? ??? ?i++; ?? ??? ??? ?} ?? ??? ??? ?len-=i; ?? ??? ??? ?TotalData-=i; ?? ??? ??? ?if (len) ?? ??? ??? ?{ ?? ??? ??? ??? ?memcpy(g_recvData+g_bootBytes,ptr, len); ?? ??? ??? ??? ?g_bootBytes += len; ?? ??? ??? ??? ?IAP_HTTP_writedata(ptr,len); ?? ??? ??? ?} ?? ??? ??? ?DataFlag=0; //?? ??? ??? ?TcpPrintf(" State: Prog Finished %d\r\n",g_bootBytes); ?? ??? ??? ?htmlpage = UploadDonePage; ?? ??? ??? ?fs_open("/uploaddone.html", &file); ?? ??? ??? ?tcp_write(tpcb, file.data, file.len, 1); ?? ??? ?} ?? ??? ?else ?? ??? ?{ ?? ??? ??? ?if(len) ?? ??? ??? ?{ ?? ??? ??? ??? ?memcpy(g_recvData+g_bootBytes,ptr, len); ?? ??? ??? ??? ?g_bootBytes += len; ?? ??? ??? ??? ?IAP_HTTP_writedata(ptr,len); ?? ??? ??? ?} ?? ??? ?} ?? ?} ?? ?else ?? ?{ //?? ??? ?close_conn(pcb, hs); ?? ?}
}
static void tcp_echoserver_send(struct tcp_pcb *tpcb, struct tcp_echoserver_struct *es) { ?? ?struct pbuf *ptr; ?? ?err_t wr_err = ERR_OK; ?? ?u16_t plen; ?? ?u8_t freed;?? ? ?? ?char *data; ?? ?int len; ?? ?plen = ptr->len; ?? ?len = 0; ?? ?memset(g_recvBuff,0,sizeof(g_recvBuff)); ?? ?while ((wr_err == ERR_OK) && (es->p != NULL) && (es->p->len <= tcp_sndbuf(tpcb))) ?? ?{?? ? ?? ??? ?g_len += ptr->len;?? ??? ? ?? ??? ?ptr = es->p;?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?/* get pointer on pbuf from es structure */ ?? ??? ?if(ptr->len > (1500-len)) ?? ??? ?{ ?? ??? ??? ?data = (char *)&g_recvBuff[0]; ?? ??? ??? ?WebAnalysis(data,len,tpcb); ?? ??? ??? ?memset(g_recvBuff,0,sizeof(g_recvBuff)); ?? ??? ??? ?len = 0; ?? ??? ?} ?? ??? ?memcpy(g_recvBuff+len,ptr->payload, ptr->len); ?? ??? ?len += ptr->len; ?? ??? ?es->p = ptr->next;?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?/* continue with next pbuf in chain (if any) */ ?? ??? ?if(es->p != NULL) ?? ??? ?{?? ??? ??? ? ?? ??? ??? ?pbuf_ref(es->p);?? ??? ??? ??? ??? ??? ??? ??? ??? ?/* increment reference count for es->p */ ?? ??? ?}?? ??? ??? ? ?? ??? ?do?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?/* chop first pbuf from chain */ ?? ??? ?{?? ??? ??? ? ?? ??? ??? ?freed = pbuf_free(ptr);?? ??? ??? ??? ??? ??? ??? ??? ?/* try hard to free pbuf */ ?? ??? ?} ?? ??? ?while(freed == 0); ?? ??? ?tcp_recved(tpcb, plen);?? ??? ??? ??? ??? ??? ??? ??? ??? ?/* we can read more data now */?? ? ?? ?} ?? ?data = (char *)&g_recvBuff[0]; ?? ?WebAnalysis(data,len,tpcb); }
static void tcp_echoserver_connection_close(struct tcp_pcb *tpcb, struct tcp_echoserver_struct *es) { ?? ?/* remove all callbacks */ ?? ?tcp_arg(tpcb, NULL); ?? ?tcp_sent(tpcb, NULL); ?? ?tcp_recv(tpcb, NULL); ?? ?tcp_err(tpcb, NULL); ?? ?tcp_poll(tpcb, NULL, 10); ?? ?/* delete es structure */ ?? ?if (es != NULL) ?? ?{ ?? ??? ?mem_free(es); ?? ?} ? ?? ?/* close tcp connection */ ?? ?tcp_close(tpcb); }
void IAP_HTTP_writedata(char * ptr, uint32_t len) ? ? ? ? ? ? { ?? ?uint32_t count, i=0, j=0; ?? ?/* check if any left bytes from previous packet transfer*/ ?? ?/* if it is the case do a concat with new data to create a 32-bit word */ ?? ?if (LeftBytes) ?? ?{ ?? ??? ?while(LeftBytes<=3) ?? ??? ?{ ?? ??? ??? ?if(len>(j+1)) ?? ??? ??? ?{ ?? ??? ??? ??? ?LeftBytesTab[LeftBytes++] = *(ptr+j); ?? ??? ??? ?} ?? ??? ??? ?else ?? ??? ??? ?{ ?? ??? ??? ??? ?LeftBytesTab[LeftBytes++] = 0xFF; ?? ??? ??? ?} ?? ??? ??? ?j++; ?? ??? ?} ?? ??? ?FLASH_If_Write(&FlashWriteAddress, (uint32_t*)(LeftBytesTab),1); ?? ??? ?LeftBytes =0;
?? ??? ?/* update data pointer */ ?? ??? ?ptr = (char*)(ptr+j); ?? ??? ?len = len -j; ?? ?}
?? ?/* write received bytes into flash */ ?? ?count = len/4;
?? ?/* check if remaining bytes < 4 */ ?? ?i= len%4; ?? ?if (i>0) ?? ?{ ?? ??? ?if (TotalReceived != size) ?? ??? ?{ ?? ??? ??? ?/* store bytes in LeftBytesTab */ ?? ??? ??? ?LeftBytes=0; ?? ??? ??? ?for(;i>0;i--) ?? ??? ??? ??? ?LeftBytesTab[LeftBytes++] = *(char*)(ptr+ len-i); ? ?? ??? ?} ?? ??? ?else count++; ?? ?} ?? ?FLASH_If_Write(&FlashWriteAddress, (uint32_t*)ptr ,count); }
#endif
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
?
|