IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 基于lwip的TCP远程更新emmc测试 -> 正文阅读

[网络协议]基于lwip的TCP远程更新emmc测试


前言

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


一、前期准备

板子使用原子哥的领航者V1,在vivado中勾选SD1,保存设计后执行“Generate Output Products”导出export hardware并导入SDK,SDK中创建应用工程,NEW一个新的Appliation Project,选择lwip echo的示例,并在BSP下的Board Support Package Sttings下勾选xilffs(emmc需要使用到),并且修改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文件,点击发送,即可实现远程更新emmc程序


总结

用emmc启动还是很实用的
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-11-27 10:15:37  更:2021-11-27 10:18:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年7日历 -2024/7/6 7:57:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码