13.3-“制作一款私有IAP串口下载小工具”之上位机软件设计说明(包含源码)

一、原理简要说明

实现IAP下载,本质上相当于把单片机编程软件编译生成的bin文件,传递到“单片机的Flash”中。而在传递的过程中可以使用任何数据传输通道,比如:串口,蓝牙,网络等。而传输bin文件的协议可以采用一些标准的格式,也可以完全自定义一个协议。总之,只要满足把bin文件传输到单片机的Flash即可。本文所描述的传递方式采用:串口+私有协议。

二、上位机IAP下载工具的功能设计

  1. bin文件选择框和选择按钮
    用于从电脑磁盘上选择一个要传输到单片机的bin文件。
  2. 串口通信以及协议实现
    用于和下位机单片机中的bootloader建立串口通信,并依据设计好的协议,完成bin文件的传递。
  3. 下载状态提示与进度条显示
    为了给用户反馈下载进度与状态,特意给软件设计了“进度条”和“状态提示栏”
  4. 使用唯一的一个”下载“按钮,完成“查找设备”和“bin文件下载”
    使用唯一的一个“下载”按钮,去掉了串口端口、波特率等的参数选择。实现了“自动查找串口设备”功能和“下载过程完全自动化”。提高下载效率的同时,简化用户的学习软件的负担。

三、小工具的“原型图”设计

13.3-“制作一款私有IAP串口下载小工具”之上位机软件设计说明(包含源码)_第1张图片

四、软件结构设计与设计思想

在编写一个软件的时候,一定要先设计“模块组成”与“关键数据结构”。并不是直接上手就写代码。直接上手写的情况是在测试某个功能的情况下。比如测试串口通信、测试按钮逻辑、测试波形显示等。
模块化设计的作用是各个模块之间互不影响。以后修改其中一个模块的代码。并不会影响其他模块的正常使用。其次写好的功能模块还可以单独拿出来直接给其他项目使用。比如,写一个串口通信模块,一个网络通信模块。模块完全独立于软件,甚至可以把这些模块单独编译成独立的库(dll/so)。软件只需要通过库的头文件调用库的功能即可。编译成库的另一个好处是,库的代码不用每次和应用程序的源码一起编译,从而加快开发时候代码的编译速度。

开发本小工具,用到的模块如下:

  • 串口通信模块
  • 通信构架模块
  • 查找设备模块
  • 读取bin文件模块
  • 主程序模块

五、通信模块设计与通信构架说明

通信构架采用“3.1,3.2,3.3章节”所描述的框架。

六、查找串口设备的原理与代码设计

  1. 查找设备的基本原理
    上位机软件获取当前电脑上的所有串口设备名称,并储存到一个List数据结构中。编程依次打开list列表中的串口设备,并使用定义好的“握手”协议,依次给串口设备发送“握手”命令。如果某个串口设备能正确的回复这个握手命令。说明这个串口设备就是我们要找的串口设备。对于我们现在的使用场景中,只能同时给一个串口设备下载固件。因此,在接收到多个串口设备返回来的握手命令后。只挑选第一个串口设备,作为目标设备。

  2. 实际编程实现方法(设计思想)
    给所有查找出的串口设备new一个对象,把这些对象的串口接收回调函数都指向同一个函数。并调用这些对象的“通信参数设置函数”,
    “打开函数”,“发送函数并发送握手数据包“。在接收回调函数处等待,看那个设备给回复了数据,并且回复的数据满足握手协议。那么这个就是要查找的设备(只保留第一个设备)。使用signal 把找到的设备信息返回给调用者。技术实现上注意;要在串口回调函数中,返回设备识别信息否则不知道是哪个设备给回复的消息。
    测试了实现查找串口设备的很多方法,最终测试发现这种实现方式,可用,稳定,好用。

七、读取bin文件的原理模块设计

使用Qt的二进制文件读写类直接去读即可,使用到的函数如下:

QFile file_;
QDataStream out_;
 
file_.setFileName(full_path);   //设置要打开的文件绝对路径
file_.open(QIODevice::ReadWrite);   //打开文件
file_.seek(pos);                //指定操作文件的新的位置
file_.size();                   //获取文件的大小
file_.flush();                  //把缓存的内容写入到实际文件
file_.close();                  //关闭文件
file_.isOpen();                 //文件是否被打开

out_.setDevice(&file_);            //设置要操作哪个文件
out_.writeRawData(data.data(), data.length()); //写二进制数据
out_.readRawData(data, len);                 //读二进制数据

八、获取源码与源码目录说明

软件实现并不复杂,想了解实现细节的话,直接阅读源码吧!

点此获取源码

你可能感兴趣的:(哈喽,上位机(上位机开发指南))