IAP上位机开发

IAP上位机开发

串口类型和串口名

由于使用到的串口类型和串口名都是系统自带的,我们所能做的只是将电脑中可用的串口搜索出来,并且在上位机上面显示出来供我们使用。因此,我们是没办法自己编辑串口名和串口类型来使用的。因此在设置这两个功能的combo Box的时候,需要修改一下他们的DropDownStyle属性,将其修改为DropDownList,就可以让这两个下拉列表只能够使用提供的选项,而不能由用户自定义编辑。

而串口的波特率有些时候由于预设的波特率不满足需求,需要用户自定义波特率,因此这个时候,下拉列表的DropDownStyle属性就不需要修改,保持为DropDown就行了。

传输文件的打开

我们需要一个button来打开所需要传输的文件,并且将打开了的文件路径显示在一个text box中。但是由于IAP串口升级固件不是所有的文件都能够传输的,因此需要进行判断,不能够传输的文件就无法打开。通过messagebox报告错误信息.

控制编辑的数据内容

由于波特率和下载的初始地址是用户自定义编辑的,因此我们需要控制用户编辑的内容是符合要求的. 比方说波特率的输入只能是数字,不能有其他的内容. 否则波特率就是不合法的,会导致程序错误. 同样的,文件传输的开始地址也是如此. 而要要控制编辑的内容,需要添加keypress事件,在添加的keypress事件函数中添加我们所需要规定的内容就可以了. 具体的实现函数如下所示:

// 传输开始地址编辑内容控制 
private void textBox2_KeyPress(object sender, KeyPressEventArgs e){e.Handled = "0123456789ABCDEFabcdef\b".IndexOf(char.ToUpper(e.KeyChar)) < 0;}
// 波特率编辑内容控制private void comboBox3_KeyPress(object sender, KeyPressEventArgs e){e.Handled = "0123456789\b".IndexOf(char.ToUpper(e.KeyChar)) < 0;}

要想添加keypress事件可以通过属性边上的闪电标志进行添加.

串口RS232下载

这是整个IAP通过USART串口升级最重要的部分

这个部分可以分为几个部分,我分别进行介绍

获取所需传输的文件信息

要通过串口升级固件,首先就是要知道我们需要发送的文件是什么,内容如何.

这里我们通过一个class类将文件所需的一些基本信息包括进来

public class FilePartInfo
{public uint PartStartAddress; //开始地址public int PartEndAddress; //结束地址public int PartSize; //大小public int PartChecksum; //校验位public byte[] PartData; //数据
}

由于一个文件太大,不可能一次性发送完成,因此我们的基本信息是一部分一部分的进行收集的.

这个class是将每个部分的信息保存起来,然后将所有部分的信心,统一保存在一个list<FilePartInfo>中.

而要获取所需传输文件的信息,在串口下载的时候还需要进行判断获取信息的过程是否成功,如果失败了,则串口升级就失败了,就需要停止串口下载升级固件.因此,我们需要这个函数返回一个bool类型的值 . 但也需要将所需文件的信息也返回出来,在c#中有一个关键词可以让一个函数返回多个值,就是out. 我们让整个函数返回bool类型的值,然后通过out修饰函数的参数,在函数中对out所修饰的值进行修改,就可以达到返回多个值的目的. 只是out修饰的参数并不是函数的返回值,但是已经在函数中被修改了.

获取所需文件的函数具体实现如下:

private bool GetFileInfo(out uint StartAddr, out List<FilePartInfo> FIleInfo, string filePath)
{StartAddr = 0;FIleInfo = null;if (filePath == string.Empty){return false;}string tempType = filePath.Substring(filePath.LastIndexOf(@"\")).ToUpper();if (tempType.Substring(tempType.Length - 3, 3) == "BIN"){FIleInfo = AddValue(filePath);string strAddr = textBox2.Text;StartAddr = StringToUInt32(strAddr, 16);}else{MessageBox.Show("下载文件格式错误", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error,MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification);return false;}if (FIleInfo == null){MessageBox.Show("下载文件错误,file information为null", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error,MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification);CloseProgress();return false;}if (FIleInfo.Count == 0){MessageBox.Show("下载文件错误,file information.count为0", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error,MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification);CloseProgress();return false;}return true;
}

首先是判断是否有文件打开,如果filePath为空,则返回false,文件的信息则还是为null. 如果filePath不为空,则继续判断格式是否复合要求, 不符合的报错,符合的再将文件的基本信息通过AddValue函数保存到事先声明好的列表中. AddValue后,再对列表进行判断,来最后决定是否成功的将所需的文件信息保存到了列表中.

其中AddValue函数的具体实现为:

public List<FilePartInfo> AddValue(string FilePath)
{if (!File.Exists(FilePath)){return null;}List<FilePartInfo> partInfo = new List<FilePartInfo>();FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read);BinaryReader br = new BinaryReader(fs);int fullLength = (int)fs.Length;if (fullLength == 0){return null ;}int partLength = 0;FilePartInfo tempInfo = new FilePartInfo();tempInfo.PartStartAddress = 0;tempInfo.PartEndAddress = 0;tempInfo.PartSize = 2048;tempInfo.PartData = new byte[2048];for (int k = 0; k < 2048; k++)tempInfo.PartData[k] = 0xFF;partInfo.Add(tempInfo);partLength = 0;for(int i = 0; i < fullLength; i++){partInfo[partInfo.Count - 1].PartData[partLength] = br.ReadByte();partLength++;if ((partLength == 0x0800) && (i + 1 < fullLength)){tempInfo = new FilePartInfo();tempInfo.PartStartAddress = partInfo[partInfo.Count - 1].PartStartAddress + 0x0800;tempInfo.PartEndAddress = 0;tempInfo.PartSize = 2048;tempInfo.PartData = new byte[2048];for (int k = 0; k < 2048; k++)tempInfo.PartData[k] = 0xFF;partInfo.Add(tempInfo);partLength = 0;}}return partInfo;
}

同样的,首先是对filePath进行判断,只有文件路径存在,才说明有文件的信息需要保存.

当文件路径存在的时候,再通过文件流filestream对文件进行打开,并且使用binaryreader进行对文件进行读取.(因此文件我们规定只有二进制文件能够传输) 然后通过tempInfo将文件的信息一部分一部分的保存在声明的列表中. 由于串口通信协议规定不满足2k的数据用0xFF填充,因此我们先将所有的数据都填充为0xFF,然后再对实际的数据进行更改. 最后将所有的 数据都保存到列表后,返回列表.

串口通信

串口通信其实就是根据串口通信协议,对上位机面对不同情况的时候所需要做出的反应进行设置就可以了.

由于串口通信协议中对于超时的情况认定为通信失败,因此我们需要获取时间来判断是否超时. 而计算机中一个经典的获取时间的方法为:

private long GetCurrentTimeSeconds()
{long currentTicks = System.DateTime.Now.Ticks;System.DateTime dtFrom = new System.DateTime(1970, 1, 1, 0, 0, 0, 0);long currentMillis = (currentTicks - dtFrom.Ticks) / 1000 / 1000 / 10;return currentMillis;
}

1970年一月一日00:00:00是Unix纪元时间. 这个函数通过获取当前时间距离Unix纪元时间的时间来确定当前的时候. 两次调用这个函数得到的结果的差值就是我们所需要的时间间隔,当时间间隔大于我们通信协议中规定的时间时,就认为是超时了,则串口通信失败,停止串口升级.

串口通信函数有两个,一个是IAP固件刚开始升级的时候,用来判断0x5A 0xA5是否正常通信的,另一个是,进入IAP升级的时候,用来判断是否正常升级的函数.

两个函数之间的主要区别在于:

  1. 功能目的不同:
    • PortCommunicationRS232Begin的主要目的是建立串口通信连接,并等待设备返回特定的应答字节序列(0xCC 0xDD),以确认连接已建立。
    • PortCommunicationRS232的主要目的是通过已建立的串口连接发送和接收数据。
  2. 接收数据处理逻辑不同:
    • PortCommunicationRS232Begin在接收数据时,专门寻找特定的应答字节序列(0xCC 0xDD),并根据是否收到该序列来判断是否连接成功。
    • PortCommunicationRS232在接收数据时,只是简单地将接收到的字节存储到提供的接收缓冲区中,不做特殊处理。
  3. 超时处理逻辑不同:
    • PortCommunicationRS232Begin在等待应答时,如果超过5秒钟没有收到期望的应答序列,就会退出循环并返回失败。
    • PortCommunicationRS232在接收数据时,如果连续5次读取操作失败,就会认为超时并返回失败。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/744396.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无需编程技能:Python爬虫与数据可视化毕业论文代写服务

引言 作为一名在软件技术领域深耕多年的专业人士&#xff0c;我不仅在软件开发和项目部署方面积累了丰富的实践经验&#xff0c;更以卓越的技术实力获得了&#x1f3c5;30项软件著作权证书的殊荣。这些成就不仅是对我的技术专长的肯定&#xff0c;也是对我的创新精神和专业承诺…

四川古力未来科技抖音小店:行业标杆的崛起与未来展望

在当下这个数字化、网络化的时代&#xff0c;电商行业正以前所未有的速度迅猛发展。四川古力未来科技有限公司&#xff0c;凭借其敏锐的市场洞察力和创新精神&#xff0c;成功在抖音小店平台上崭露头角&#xff0c;成为行业内的佼佼者。今天&#xff0c;我们就来一起探讨四川古…

如何写一个react自定义的hooks?

使用过useState&#xff0c;也使用过ahook的useSetState&#xff0c;我们知道useState和useSetState左边赋值的第一个参数是接收初始值的变量和设置变量的方法&#xff0c;这里左边用的是数组解构实现的。所以&#xff0c;这里我们想一下&#xff0c;如何自定义一个hooks&#…

北京调研公司揭秘:问卷调查6大秘籍,让你领先对手一步!

民安智库作为一家专业的第三方市场调研公司&#xff0c;我们经常会遇到客户需要开展问卷调查的情况。为了帮助客户更好地进行问卷调查&#xff0c;我们总结出了以下6大秘籍&#xff1a; 1.明确调查目的和受众群体 在进行问卷调查之前&#xff0c;一定要明确调查的目的和受众群…

【学习总结】Python transformers TrainingArguments 重要参数说明

代码&#xff1a; from transformers import TrainingArgumentstraining_args TrainingArguments(output_dirmodel_dir,per_device_train_batch_size16,num_train_epochs5,logging_steps100)TrainingArguments 类在以下代码里&#xff1a; /xxx/anaconda/envs/your_env/lib/…

Navicat16安装时报错记录

1.安装过程中一定要断网 2.安装好后&#xff0c;先不要直接打开客户端&#xff0c;应该先打开激活破解软件&#xff0c;如下&#xff1a; 选择HOSTS--》再Patch-->是&#xff0c;然后生成注册码&#xff0c;打开客户端正常执行即可

从“断亲”到“自我养育”,看年轻一代消费变迁丨小红书热点

一、不爱走亲戚&#xff0c;年轻人“断亲潮”来袭 今年春节期间&#xff0c;关于“农村出现以家庭为单位的断亲”的话题登上热搜。小红书等社交媒体平台上&#xff0c;也涌现出许多“回怼亲戚”的短视频&#xff0c;娱乐性调侃亦或是“阴阳怪气”地攻击&#xff0c;内容背后是当…

全局Ceph节点宕机处理

在极端情况下&#xff0c;如数据中心断电&#xff0c;造成 Ceph 存储集群全局宕机&#xff0c;可以按照本节所示流程进行 Ceph 集群上电恢复操作。 4.1 手动上电执行步骤 如为 Ceph 集群上电&#xff0c;monitor server 应最先上电&#xff1b;集群上电前确认使用 Ceph 之前端…

IIS上部署.netcore WebApi项目及swagger

.netcore项目一般是直接双击exe文件&#xff0c;运行服务&#xff0c;今天有个需求&#xff0c;需要把.netcore项目运行在IIS上&#xff0c;遇到了一个小坑&#xff0c;在这里记录一下。 安装IIS&#xff0c;怎么部署站点&#xff0c;这些过于简单就不细说了&#xff0c;不知道…

C++:继承与派生

为什么会有继承这样的语法呢&#xff1f;&#xff1f;试想这样一个场景&#xff1a;假设我们这个App需要去获取不同类型用户的数据&#xff0c;并进行分类&#xff0c;那么就需要我们去写对应不同的类&#xff0c;比如说学生、老师、军人、公司职工…………每个类都需要有名字、…

品牌方如何借热点做话题?媒介盒子分享

每时每刻都有热点&#xff0c;品牌方总想着借热点来做话题营销&#xff0c;然而有些热点能让品牌有效曝光&#xff0c;有些热点稍不注意就会让品牌产生负面舆论&#xff0c;今天媒介盒子就来和大家好好聊聊&#xff1a;品牌方如何借热点做话题。 一、 热点选择 品牌方可以通过…

猿区 Node.js 版本控制工具介绍

Node.js 版本控制工具&#xff1a;nvm、n 和 fnm 如果你是一位刚开始学习 Node.js 的初学者&#xff0c;你可能已经注意到 Node.js 有多个版本。不同的项目可能需要不同的 Node.js 版本&#xff0c;而在本地环境中同时安装和管理这些版本可能会变得复杂。幸运的是&#xff0c;…

域内令牌窃取

前言 有这样一种场景&#xff0c;拿到了一台主机权限&#xff0c;是本地管理员&#xff0c;同时在这台主机上登录的是域管成员&#xff0c;这时我们可以通过dump lsass或通过 Kerberos TGT &#xff0c;但是这是非常容易被edr命中的。 本文就通过令牌窃取进行研究&#xff0c…

正则表达式笔记+demo

//1.正则表达式由普通字符和特殊字符(又称元字符)组成的文字模式,是一个模板 // 常用元符号示例&#xff1a;^ . \ * ? { 、} ( 、 ) [ 、 ] | $ // ★★★这些元符号都有其特殊含义&#xff0c;如果要表示其本来字符的含义&#xff0c;需要…

mysql基础之事务

简介 事务是数据库的逻辑工作单位&#xff0c;具有原子性、一致性、隔离性、持久性四大特性。 【原子性】&#xff1a;事务中的操作要么全部成功&#xff0c;要么操作失败全部回滚&#xff0c;不会出行部分完成的状态。 【一致性】&#xff1a;事务开始到结束时&#xff0c;数据…

pgsql常用索引简写

文章来源&#xff1a;互联网博客文章&#xff0c;后续有时间再来细化整理。 在数据库查询中&#xff0c;合理的使用索引&#xff0c;可以极大提升数据库查询效率&#xff0c;充分利用系统资源。这个随着数据量的增加得到提升&#xff0c;越大越明显&#xff0c;也和业务线有关…

《鸟哥的Linux私房菜》第6章——总结与习题参考答案

目录 一、 简介 二、一些新了解的指令 1.touch- 修改文件时间或创建新文件 2.umask-新建文件/目录的默认权限 3.文件隐藏属性 4.文件特殊权限 5.file-观察文件类型 三、简答题部分 一、 简介 本章介绍了一些常用的文件与目录指令&#xff0c;包括新建/删除/复制/移动/查…

2024HVV行动-进军蓝中研判(log4j2、fastjson、Struts2、Shiro)

1、log4j2 特征&#xff1a; 恶意请求中包含 JNDI 协议地址&#xff0c;如"ldap://"、"rmi://"等&#xff0c;被 log4j2 解析为 JNDI 查找。 原理&#xff1a; 在日志输出中&#xff0c;未对字符进行严格的过滤&#xff0c;执行了 JNDI 协议加载的远程恶…

教师如何搭建学生查询考试分数的平台?

随着信息技术的快速发展&#xff0c;搭建一个学生查询考试分数的平台已经成为现代教育管理的重要组成部分。这样的平台不仅可以提高成绩管理的效率&#xff0c;还能为学生提供便捷、及时的成绩查询服务。那么&#xff0c;作为教师&#xff0c;我们应该如何搭建这样一个平台呢&a…

Python中的惩罚分析:理论与实践指南

目录 写在开头1. 理论基础1.1 优化问题与约束条件简介1.2 什么是惩罚分析1.3 惩罚分析的应用场景1.4 惩罚方法的类型2. 惩罚分析在Python中的实现2.1 实现代码示例2.2 未加惩罚的模型2.3 加惩罚的模型(L1和L2正则化)2.4 选择合适的惩罚方法与调整强度2.5 惩罚过程改善过拟合问…