金牌会员
 
- 积分
- 1400
- 金钱
- 1400
- 注册时间
- 2016-6-2
- 在线时间
- 166 小时
|
10金钱
本帖最后由 hyarcher25 于 2016-9-21 14:56 编辑
参考原子哥的udp通讯以及串口iap程序,已经写了一个上位机每次发1K的bin文件,发送和接收没有做校验,只为了实现最基础的,每隔200ms发送1K。app大概41K
IAP从0x8000000大小0xA000,40K
APP从0x800A000大小0xF000,60K.APP程序已设置好SCB->VTOR = FLASH_BASE | 0xA000,IROM1也已经设置好;
用的107的芯片,下载iap程序用jlink监控:
1.我用jlink监控iap程序里面的cishu接收计数为82次,意思是发了82*1024=82K的数据,但我实际bin文件也就41K,上位机也确实只发了41K。
2.每次在if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)处无法满足条件,0x0800A000是APP起始地址应该没错吧???
以下是iap程序里面的udp升级函数。
[mw_shl_code=cpp,true]#define FLASH_APP1_ADDR 0x0800A000 //APP地址
u8 udp_recvbuf[1024];
u16 recvlen;
u16 cishu;//接收计数
void udp_task(void)
{
err_t err;
struct udp_pcb *udppcb;
struct ip_addr rmtipaddr;
u8 res=0;
udp_demo_set_remoteip();//选择IP 192.168.1.106
udppcb=udp_new();
if(udppcb)//创建成功
{
IP4_ADDR(&rmtipaddr,remoteip[0],remoteip[1],remoteip[2],remoteip[3]);
err=udp_connect(udppcb,&rmtipaddr,UDP_PORT);
if(err==ERR_OK)
{
err=udp_bind(udppcb,IP_ADDR_ANY,UDP_PORT);/绑定本地IP和端口号
if(err==ERR_OK) /绑定完成
{
udp_recv(udppcb,udp_demo_recv,NULL);//注册接收回调函数
}else res=1;
}else res=1;
}else res=1;
while(res==0)
{
if(recvlen==1024)//接收到1k数据
{
iap_write_appbin((FLASH_APP1_ADDR+(cishu*1024)),udp_recvbuf,recvlen);//写flash
cishu++;
}
if((recvlen<1024)&&(cishu>0))//接收数据小于1k,认为是最后一帧数据
{
iap_write_appbin((FLASH_APP1_ADDR+(cishu*1024)),udp_recvbuf,recvlen);//写flash
recvlen=0;
if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)
{
iap_load_app(FLASH_APP1_ADDR);//Ö′DDFLASH APP′úÂë
}
}
if(udp_flag&1<<6)//是否接收到数据
{
udp_flag&=~(1<<6);//标记数据已经被处理
}
LwIP_Periodic_Handle(LocalTime);
IWDG_Feed();
}
}[/mw_shl_code]
udp接收回调函数
[mw_shl_code=cpp,true]
void udp_demo_recv(void *arg,struct udp_pcb *upcb,struct pbuf *p,struct ip_addr *addr,u16_t port)
{
u32 data_len = 0;
struct pbuf *q;
if(p!=NULL) //接收到不为空的数据时
{
memset(udp_recvbuf,0,UDP_RX_BUFSIZE); //数据接收缓存清零
for(q=p;q!=NULL;q=q->next) //遍历完整个pbuf链表
{
if(q->len > (UDP_RX_BUFSIZE-data_len))
memcpy(udp_recvbuf+data_len,q->payload,(UDP_RX_BUFSIZE-data_len));//拷贝数据
else
memcpy(udp_recvbuf+data_len,q->payload,q->len);
data_len += q->len;
recvlen=q->len;
if(data_len > UDP_RX_BUFSIZE) break; //超出tcp客户端接收数组,跳出
}
upcb->remote_ip=*addr; //记录远程主机IP地址
upcb->remote_port=port; //记录远程主机端口
remoteip[0]=upcb->remote_ip.addr&0xff; //IADDR4
remoteip[1]=(upcb->remote_ip.addr>>8)&0xff; //IADDR3
remoteip[2]=(upcb->remote_ip.addr>>16)&0xff;//IADDR2
remoteip[3]=(upcb->remote_ip.addr>>24)&0xff;//IADDR1
udp_flag|=1<<6; //标记接收到数据了
pbuf_free(p);//释放内存
}else
{
udp_disconnect(upcb);
}
} [/mw_shl_code]
iap.c的内容,我都没改直接用的例程的
[mw_shl_code=cpp,true]void iap_write_appbin(u32 appxaddr,u8 *appbuf,u32 appsize)
{
u16 t;
u16 i=0;
u16 temp;
u32 fwaddr=appxaddr;/当前写入的地址
u8 *dfu=appbuf;
for(t=0;t<appsize;t+=2)
{
temp=(u16)dfu[1]<<8;
temp+=(u16)dfu[0];
dfu+=2;//偏移2个直接
iapbuf[i++]=temp;
if(i==1024)
{
i=0;
STMFLASH_Write(fwaddr,iapbuf,1024);
fwaddr+=2048;//偏移2048
}
}
if(i)STMFLASH_Write(fwaddr,iapbuf,i);//将最后的内容写进去
}
void iap_load_app(u32 appxaddr)
{
if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000) //检查栈顶地址是否合法
{
jump2app=(iapfun)*(vu32*)(appxaddr+4);
MSR_MSP(*(vu32*)appxaddr);//初始化APP堆栈指针
jump2app(); //跳转到APP
}
} [/mw_shl_code]
求大神指点,gank!
|
|