[结贴]请问,如何通过串口,使用 Arduino STK 协议上传 .hex-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 4944|回复: 7

[已解决] [结贴]请问,如何通过串口,使用 Arduino STK 协议上传 .hex

[复制链接]
发表于 2018-5-13 16:52 | 显示全部楼层 |阅读模式
本帖最后由 skypup 于 2018-5-15 17:30 编辑

如题。

如果想在自己的 C# 程序中加入给 Arduino 硬件上传 .hex 固件的功能,应当如何实现呢,有没有代码供参考?



关于校验码的计算,好像是这样的:
代码写的很随意,只是为了验证一下,协议的最后一位校验码是如何算出来的。
        public void WriteWithCheckSum()
        {
            byte[] aSendMessage = new byte[300];

            byte nMessageSizeLeft = (byte)(nMessageSize >> 4);
            byte nMessageSizeRight = (byte)nMessageSize;

            nCheckSum = 0x00;
            nCheckSum ^= MESSAGE_START; aSendMessage[0] = MESSAGE_START;
            nCheckSum ^= nSequenceNumber; aSendMessage[1] = nSequenceNumber;
            nCheckSum ^= nMessageSizeLeft; aSendMessage[2] = nMessageSizeLeft;
            nCheckSum ^= nMessageSizeRight; aSendMessage[3] = nMessageSizeRight;
            nCheckSum ^= TOKEN; aSendMessage[4] = TOKEN;
            for (int i = 0; i < nMessageSize; i++)
            {
                nCheckSum ^= aMessageBody;
                aSendMessage[5 + i] = aMessageBody;
            }
            aSendMessage[5 + nMessageSize] = nCheckSum;
            this.Write(aSendMessage, 0, 6 + nMessageSize);

            nSequenceNumber++;
        }


IntelHEX.png
发表于 2018-5-13 18:13 | 显示全部楼层
有源码:
http://www.arduino.cn/thread-1183-1-1.html就是调用avrdude
 楼主| 发表于 2018-5-13 21:17 | 显示全部楼层
奈何col 发表于 2018-5-13 18:13
有源码:
http://www.arduino.cn/thread-1183-1-1.html就是调用avrdude

那好吧,这也是  Arduino 官方 IDE 的做法。

没有哪位同学研究过 AVRISP 的串口通讯协议么?
 楼主| 发表于 2018-5-14 14:52 | 显示全部楼层
读取 Intel Hex 文件的例程,不仅仅针对 Arduino.

IntelHEX.png

        byte[] readIntelHEXv2(StreamReader sr)
        {
            byte[] FLASH = new byte[1024 * 1024];

            int optionoffset = 0;
            int total = 0;
            bool hitend = false;

            while (!sr.EndOfStream)
            {
                toolStripProgressBar1.Value = (int)(((float)sr.BaseStream.Position / (float)sr.BaseStream.Length) * 100);

                string line = sr.ReadLine();

                if (line.StartsWith(":"))
                {
                    int length = Convert.ToInt32(line.Substring(1, 2), 16);
                    int address = Convert.ToInt32(line.Substring(3, 4), 16);
                    int option = Convert.ToInt32(line.Substring(7, 2), 16);
                    Console.WriteLine("len {0} add {1} opt {2}", length, address, option);

                    if (option == 0)
                    {
                        string data = line.Substring(9, length * 2);
                        for (int i = 0; i < length; i++)
                        {
                            byte byte1 = Convert.ToByte(data.Substring(i * 2, 2), 16);
                            FLASH[optionoffset + address] = byte1;
                            address++;
                            if ((optionoffset + address) > total)
                                total = optionoffset + address;
                        }
                    }
                    else if (option == 2)
                    {
                        optionoffset = (int)Convert.ToUInt16(line.Substring(9, 4), 16) << 4;
                    }
                    else if (option == 1)
                    {
                        hitend = true;
                    }
                    int checksum = Convert.ToInt32(line.Substring(line.Length - 2, 2), 16);

                    byte checksumact = 0;
                    for (int z = 0; z < ((line.Length - 1 - 2) / 2); z++) // minus 1 for : then mins 2 for checksum itself
                    {
                        checksumact += Convert.ToByte(line.Substring(z * 2 + 1, 2), 16);
                    }
                    checksumact = (byte)(0x100 - checksumact);

                    if (checksumact != checksum)
                    {
                        MessageBox.Show("The hex file loaded is invalid, please try again.");
                        throw new Exception("Checksum Failed - Invalid Hex");
                    }
                }
                //Regex regex = new Regex(@"^..)(....)(..)(.*)(..)$"); // length - address - option - data - checksum
            }

            if (!hitend)
            {
                MessageBox.Show("The hex file did no contain an end flag. aborting");
                throw new Exception("No end flag in file");
            }

            Array.Resize<byte>(ref FLASH, total);

            return FLASH;
        }

 楼主| 发表于 2018-5-14 18:23 | 显示全部楼层
目前的进展:
1 弄明白 AVRISP STK500v2 协议的基本格式和校验码算法。
2 弄明白 .hex 文件的格式。
3 单线程的情况下,已经能烧录成功。但是有一定概率通讯出错,可能是接收数据前的延时未处理好。

余下的工作就是把整个流程做的靠谱一些,程序改为多线程的。
结贴。
等我把程序完善之后,重新开一个贴子。
 楼主| 发表于 2018-5-15 17:29 | 显示全部楼层
Mission Planner 软件已经改好了:

https://pan.baidu.com/s/1oCqlP8lMxM_INA6QDuoMSQ

文件比较大,所以放在网盘上面了。

"MP1.3.21_增加烧录Arduino固件功能.doc", 这个 Word 文档记录了全部的修改内容,如果想在其它版本的 Mission Planner 源码基础上修改,可以参考这个文档内容。

"MissionPlanner1.3.21_珍爱生命远离大疆_已编译的程序.rar",这个压缩包里面是可以直接运行的程序。

“MissionPlanner1.3.21_增加烧录Arduino固件功能.rar”,这个是源代码,我是在 VS2017 下修改的,理论上说只要是 VS2013 或更高的版本,都可以打开。
发表于 2019-10-10 17:37 | 显示全部楼层
你好,我是一名江苏高校毕业生,在用C#研究Arduino HEX文件烧写,我的QQ 1808088414,请问您QQ多少
发表于 2021-9-13 11:19 | 显示全部楼层
楼主好,请问哪里可以找到stk500的烧录协议相关文档。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 23:52 , Processed in 0.283075 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表