一、串口升级思路
1)第一步先能发送文件,并实现进度条功能;
2)制定升级协议,升级需要开始帧、结束校验帧、文件数据的校验等内容;
3)发送文件加上起始帧、结束校验帧和升级文件校验,增加容错性;
4)升级.bin文件测试。
二、代码实现
1)打开文件,文件路径显示在文本框
//声明变量
static bool flagUpdata = true;
static bool flagUpgradeTimer = true;
static byte[] startFrame = { 0x5A, 0x01, 0x02, 0x08, 0x02, 0x00, 0x01, 0x0, 0x0 };
System.Timers.Timer UpgradeTimer = new System.Timers.Timer(100);
static UInt16 upgradeBarTime = 0;
static bool upgradePanelFlag = true;
static bool upgradeEndFlag = true;
static byte[] endFrame = { 0x5A, 0x01, 0x02, 0x08, 0x04, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0 };
byte[] updataFileData = new byte[1024 * 200];
int readByte = 0;
//打开文件
private void btnOpenFile_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog(); //点击弹出对话框
ofd.Title = "请选择要打开的文本文件"; //设置对话框标题
ofd.Multiselect = true; //设置对话框多选
ofd.InitialDirectory = @"C:\Users\Andy\Desktop"; //设置对话框初始目录
ofd.Filter = "文本文件|*.bin"; //打开对话框文件类型
ofd.ShowDialog(); //展示对话框
string path = ofd.FileName; //获得在打开对话框中选中文件的路径
if (path == "")
{
return;
}
using (FileStream fsRead = new FileStream(path, FileMode.OpenOrCreate,FileAccess.Read))
{
readByte = fsRead.Read(updataFileData, 0, updataFileData.Length);//实际读取到的字节数
txbFileAddr.Text = path; //文件路径显示在文本框
}
upgradeBarTime = 0;
this.pgbProcessBar.Value = 0;
flagUpdata = true;
upgradeEndFlag = true;
upgradePanelFlag = true;
UpgradeTimer.Start();
btnStartUpgrade.Text = "开始升级";
}
2)开始帧校验成功--->串口发送文件--->结束校验帧
发送文件时,显示进度条,当前进度条是计时的,待优化,实际应该根据文件的大小,显示进度条。
//发送开始帧,初始化Timer事件
private void btnStartUpgrade_Click(object sender, EventArgs e)
{
if (txbFileAddr.Text=="")
{
MessageBox.Show("请打开升级文件");
return;
}
if (btnStartUpgrade.Text == "正在升级")
{
MessageBox.Show("正在升级,请勿操作!");
return;
}
else
{
byte[] crc16BmsData = CrcCheck.CRC16(startFrame);
startFrame[7] = crc16BmsData[0]; //高八位
startFrame[8] = crc16BmsData[1]; //低八位
MainForm.SerialPort1.Write(startFrame, 0, startFrame.Length);
if (flagUpgradeTimer)
{
flagUpgradeTimer = false;
UpgradeTimer.Elapsed += new
System.Timers.ElapsedEventHandler(UpgradeAnalysis);
UpgradeTimer.Enabled = true; //设置执行System.Timers.Elapsed事件
UpgradeTimer.AutoReset = true; //设置一直执行
UpgradeTimer.Start();
}
}
}
//开始帧应答判断、发送文件、发送结束校验帧及应答数据判断
private void UpgradeAnalysis(object sender, System.Timers.ElapsedEventArgs e)
{
//开始帧应答数据判断
if (MainForm.readData.Length == 9)
{
//判断帧头、通信目标
if ((MainForm.readData[0] == 0x5A) && (MainForm.readData[1] == 2))
{
byte[] crc16StartFrameData = CrcCheck.CRC16(MainForm.readData);
if ((crc16StartFrameData[0] == MainForm.readData[MainForm.readData.Length - 2]) && (crc16StartFrameData[1] == MainForm.readData[MainForm.readData.Length - 1]))
{
//升级进度条
if (upgradeBarTime == 100)
{
return;
}
upgradeBarTime++;
this.pgbProcessBar.Value = upgradeBarTime;
if (flagUpdata)
{
flagUpdata = false;
btnStartUpgrade.Text = "正在升级";
}
if (upgradePanelFlag)
{
upgradePanelFlag = false;
MainForm.SerialPort1.Write(updataFileData, 0, readByte);//发送升级文件
byte[] crc16upgradeFile = CrcCheck.CRC16(updataFileData);
endFrame[7] = crc16upgradeFile[0];
endFrame[8] = crc16upgradeFile[1];
byte[] crc16EndFrame = CrcCheck.CRC16(endFrame);
endFrame[9] = crc16EndFrame[0];
endFrame[10] = crc16EndFrame[1];
MainForm.SerialPort1.Write(endFrame, 0, endFrame.Length);
}
}
else
{
MainForm.readData = null;
this.pgbProcessBar.Value = 0;
txbFileAddr.Text = "";
btnStartUpgrade.Text = "开始升级";
MessageBox.Show("开始帧校验错误,请重新升级");
return;
}
}
else
{
MainForm.readData = null;
this.pgbProcessBar.Value = 0;
txbFileAddr.Text = "";
btnStartUpgrade.Text = "开始升级";
MessageBox.Show("帧头或通信目标错误,请重新升级");
return;
}
}
//结束校验帧
if (MainForm.readData.Length == 11)
{
//判断帧头、通信目标、数据长度、第一个数据02
if ((MainForm.readData[0] == 0x5A) && (MainForm.readData[1] == 2) && (MainForm.readData[4] == 4) && (MainForm.readData[6] == 2))
{
//文件校验值和上报的校验值比对
if ((endFrame[7] == MainForm.readData[7]) && (endFrame[8] == MainForm.readData[8]))
{
//结束帧CRC16校验比对
byte[] crc16StartFrameData = CrcCheck.CRC16(MainForm.readData);
if ((crc16StartFrameData[0] == MainForm.readData[MainForm.readData.Length - 2]) && (crc16StartFrameData[1] == MainForm.readData[MainForm.readData.Length - 1]))
{
if (upgradeEndFlag)
{
upgradeEndFlag = false;
btnStartUpgrade.Text = "升级完成";
MessageBox.Show("升级完成!");
}
UpgradeTimer.Close();
MainForm.readData = null;
}
else
{
MainForm.readData = null;
this.pgbProcessBar.Value = 0;
txbFileAddr.Text = "";
btnStartUpgrade.Text = "开始升级";
MessageBox.Show("结束校验帧错误,请重新升级");
return;
}
}
else
{
MainForm.readData = null;
this.pgbProcessBar.Value = 0;
txbFileAddr.Text = "";
btnStartUpgrade.Text = "开始升级";
MessageBox.Show("升级文件验帧错误,请重新升级");
return;
}
}
else
{
MainForm.readData = null;
upgradeBarTime = 0;
txbFileAddr.Text = "";
btnStartUpgrade.Text = "开始升级";
MessageBox.Show("帧头、通信目标、数据长度或数据错误,请重新升级");
return;
}
}
}