基于lwip的TCP远程更新sd测试


前言

最近需要做个从sd启动的程序测试,实际应用中,sd的数据内容肯定是从tcp传输过来,不多说,往下看了。


一、前期准备

板子使用原子哥的领航者V1,在vivado中勾选SD0,保存设计后执行“Generate Output Products”导出export hardware并导入SDK,SDK中创建应用工程,NEW一个新的Appliation Project,选择lwip echo的示例,并在BSP下的Board Support Package Sttings下勾选xilffs(sd需要使用到),并且修改lwip的设置:大致如下:

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

保存,选择OK,等待更新完毕。

二、软件

1.大致思路

对于emmc,先初始化以及挂载成功,此部分这里省略。
对于lwip,它的官方例程可以直接拿来使用,把轮询模式修改为中断接收数据模式,然后在回调函数中做相应的数据处理即可。
由于实际应用中,tcp客户端需要不断的和服务端通讯,主程序收到客户端的命令不可能在中断回调中完成(影响效率),所以只在中断回调函数中做简单的数据处理,命令的实际处理放在主程序中执行。
在这里插入图片描述

2.部分代码

/** 命令头*/
typedef struct _Head{	
	unsigned short uHeader;			    //头---0x1234
	unsigned short uHeader1;			//头1---0xffff
	unsigned short uCmd;				//命令值  下载命令设置为0x01
	unsigned short uCmdReverse;			//命令值取反
	unsigned int nLenth;				//数据长度	
}Head_T;
/** LWIP的回调函数处理部分代码*/
err_t recv_callback(void *arg, struct tcp_pcb *tpcb,struct pbuf *p, err_t err)
{
	int nLen = 0,i = 0;
	char *pRev = NULL;
	static int nSumLen = 0;
	struct pbuf *q;
	char cCopyflag = FALSE;
	
	pRev = (char *)RECEIVE_BUF;//为DDR缓存地址
	/**< 获取数据头*/
	if(!cCopyflag)
	{
		nLen = 4;
		uint16_t *pHead =(unsigned short *)&tCmdHead;
		while(nLen--)
		{
			*(pHead + i) =  *((unsigned short *)(p->payload)+i);
			i++;
		}
		tCmdHead.wLenthInt =  *((int *)(p->payload)+2);
	}
	
	/**< 分包接收bin文件到buf缓存中*/
	if(cCopyflag)
	{
		memcpy((uint8_t *)(pLinuxRev+nSumLen), p->payload, p->len);
		nSumLen += p->len;
	}
	/**< 下载命令*/
	if((tCmdHead.uCmd == 0x01) && (cCopyflag == FALSE) && (wLwipCmdState == NULL_CMD)){
		cCopyflag = TRUE;
		/**< 首包丢掉命令头*/
		memcpy((uint8_t *)(pLinuxRev+nSumLen), ((unsigned short *)(p->payload+6)), (p->len - 12));
		nSumLen += (p->len-12);
	}
	/**< 接收完毕,可获取下一个数据头*/
	if(nSumLen == tCmdHead.wLenthInt)
	{
		cCopyflag = FALSE;
		nSumLen = 0;
		wLwipCmdState = NEW_CMD;//通知有新命令未处理
	}
	tcp_recved(tpcb, p->len);


}
/**< 主函数处理部分代码*/
void main(void)
{
	char *pRev = NULL;
	if(wLwipCmdState == NEW_CMD)
	{
		switch(tCmdHead.uCmd)
		{
			case 0x01:
				pRev = (char *)RECEIVE_BUF;//为DDR缓存地址
				eMMCWrite("program",(u32)pRev,tCmdHead.wLenthInt);//写入emmc
				wLwipCmdState = NULL_CMD;
				tCmdHead.uCmd = 0;
			break;
			default: Aprintf("ERROR CMD!!!\r\n");break;
		}
	}
}

验证的时候,SDK用FSBL生成bin文件,然后用UltraEdit工具的十六进制编辑模式,把数据头添加进bin文件中,如图
在这里插入图片描述
程序烧写至开发板,这里不做过多说明
然后用网络调试助手,连接好TCP客户端
在这里插入图片描述
选择打开文件数据源,选择bin文件,点击发送,即可实现远程更新sd程序


总结

用sd启动还是很实用的
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值