搜索
bottom↓
回复: 144

stm32 Bootloader设计(YModem协议)

  [复制链接]

出0入0汤圆

发表于 2013-11-19 12:55:59 | 显示全部楼层 |阅读模式
stm32 Bootloader设计(YModem协议)
相信很多人都希望,不开盖就可以对固件进行升级吧,就像手机那些。下文中的bootload就来实现这样的功能。

         前段时间有项目关于Bootload设计。所以就仔细的去了研究了一翻。以前都是用的stm32官方的,没有去深入了解。这次做完了过后,发现官方的版本存在一些问题。比如说YModem传送过程中,完全没有对数据区进行效验,只是核对了下编号,就进行烧写。整个程序完全为阻塞式,浪费了大量的cpu做无用功。当然这在升级程序方面也用不了多少时间。有一个重要的问题,官方代码只可以用超级终端进行传输。这样如果你用的是64位的win7,那就没有办法升级。因为只有xp或32位的win7才可以使用 超级终端。64位的win7下超级终端没办法使用。 不过SecureCRT工具到是可以在64位win7使用,但是官方代码不对其支持。SecureCRT下支持的是最原始的YModem协议,第一帧数据包中不包含总字节数。超级终端下的YModem应该是改进版的,所以官方的dome只可以在超级终端下传输。下面会对YModem进行详细说明。就会知道其中的原因。

         首先奉上一个精简的Bootloader工程。

         http://pan.baidu.com/share/link?shareid=373630&uk=118334538

         支持协议:YModem, YModem-G。

         所支持的PC软件:超级终端,SecureCRT。

         http://pan.baidu.com/share/link?shareid=373637&uk=118334538



YModem协议:
         YModem协议是由XModem协议演变而来的,每包数据可以达到1024字节,是一个非常高效的文件传输协议。下面有一些相关的文档。这里要感谢关注我微博的一些朋友提供的资料。省去了不少时间。

         下面先看下YModem协议传输的完整的握手过程:先看下图




SENDER:发送方。

RECEIVER:接收方。

第一步先由接收方,发送一个字符'C'

发送方收到'C'后,发送第一帧数据包,内容如下:

SOH 00 FF Foo.c NUL[123] CRC CRC

第1字节SOH:表示本包数据区大小有128字节。如果头为STX表示本包数据区大小为1024

第2字节00: 编号,第一包为00,第二包为01,第三包为02依次累加。到FF后继续从0循环递增。

第3字节FF: 编号的反码。 编号为00 对应FF,为01对应FE,以此类推。



第4字节到最后两字节:若第1字节为SOH时有128字节,为STX时有1024字节,这部分为数据区。“Foo.c” 文件名, 超级终端下,在文件名后还有文件大小。官方dome也是因为使用了这个文件大小进行比对。这就是为什么用SecureCRT中的YMODEM协议而无法正确传输的原因。

         在文件名和文件大小之后,如果不满128字节,以0补满。

最后两字节:这里需要注意,只有数据部分参与了效CRC验,不包括头和编码部分。

16位CRC效验,高字节在前,低字节在后。



接收方收到第一帧数据包后,发送ACK正确应答。

然后再发送一个字符'C'。

发送方收到'C'后,开始发送第二帧,第二帧中的数据存放的是第一包数据。

接收方收到数据后,发送一个ACK然后等待下一包数据传送完毕,继续ACK应答。直到所有数据传输完毕。

数据传输完毕后,发送方发EOT,第一次接收方以NAK应答,进行二次确认。

发送方收到NAK后,重发EOT,接收方第二次收到结束符,就以ACK应答。

最后接收方再发送一个'C',发送方在没有第二个文件要传输的情况下,

发送如下数据

SOH 00 FF 00~00(共128个) CRCH CRCL

接收方应答ACK后,正式结束数据传输。



以上部分,为YMODEM协议的基本操作流程。



STM32 Bootloader软件设计
         笔者一开始软件的基本思想,串口接收数据,和写数据到ROM中,两者可以同步进行。这样可以让cpu得到最大程度的有效利用。

         比如说接收一帧1024的数据,所用的时间= 当前波特率单字符所用时间 * (1024 + 1头 + 2编码 + 2CRC)= (1/115200 * 10) * (1024 + 1 + 2 + 2) = 89.323ms

也是就是,在接收的这90ms左右的时间里,在接收下一帧结束这一期间内,可以把上一帧的数据写入到ROM中。 串口接收数据是中断的方式,所以收写操作基本上算同步运行。程序流程如下

        

STM32 Bootloader使用方法:
         这个STM32 Bootloader程序使用起来很简单,如果你以前没有用过IAP升级方式,也没关系下面会详细说明。



准备工作:

         硬件:有串口目标板1,串口连接线。

         软件:PC工具:超级终端 或SecureCRT,stm32目标板程序.bin,stm32 Bootloader。



1)         先把上面的工程stm32 Bootloader下载到目标板中;

2)         打开超级终端 或SecureCRT,设置波特特115200,停止位1,数据位8,效验无。

3)         先按下‘C’再给目标板上电;(注意先后顺序)



4)         选择1,然后使用YModem, YModem-G协议发送"stm32目标板程序.bin"文件。

5)         传输完毕后,会自动运行。



注意:以下两处根据自己的需求调整

stm32 Bootloader修改:

找到工程下的common.h文件:

以下三个宏定义根据自己目标板的需求来定:

#define ApplicationAddress      0x8002000        //程序首地址

#define ApplicationSize         120000           //目标程序预留空间

#define STM32F10X_HD                         //目标板芯片类型



stm32目标板程序.bin偏移地址修改:

有两个地方:

1找到system_stm32f10x.c

#define VECT_TAB_OFFSET  0x2000 /*!< Vector Table base offset field.



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2013-11-19 12:57:50 | 显示全部楼层
还是上传一个文件吧

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-11-19 13:02:54 来自手机 | 显示全部楼层
不错,标记一下。

出0入0汤圆

发表于 2013-11-19 13:07:25 | 显示全部楼层
mark 帮顶。            

出0入4汤圆

发表于 2013-11-19 13:09:41 | 显示全部楼层
灰常不错  

出0入0汤圆

发表于 2013-11-19 13:09:50 | 显示全部楼层
收藏待学习。

出0入0汤圆

发表于 2013-11-19 14:16:10 | 显示全部楼层
收蔵学习

出0入0汤圆

发表于 2013-11-19 14:24:04 | 显示全部楼层
收藏学习

出0入0汤圆

发表于 2013-11-19 17:16:30 | 显示全部楼层
非常好,帮顶

出0入0汤圆

发表于 2013-11-19 17:20:54 | 显示全部楼层
不久就会用到,先MARK

出0入0汤圆

发表于 2013-11-19 18:21:42 来自手机 | 显示全部楼层
这个要学习下

出0入0汤圆

发表于 2013-11-19 18:50:14 | 显示全部楼层
mark....thanks

出0入0汤圆

发表于 2013-11-19 19:17:08 | 显示全部楼层
牛人啊。。。

出0入0汤圆

发表于 2013-11-19 19:19:33 | 显示全部楼层
很有用,先学习学习了。这个以前尝试过,没做成功,多谢楼主经验了

出0入4汤圆

发表于 2013-11-19 19:28:50 | 显示全部楼层
收下,不谢!

出0入0汤圆

发表于 2013-11-19 20:18:03 来自手机 | 显示全部楼层
留下记号

出0入0汤圆

发表于 2013-11-20 09:51:09 | 显示全部楼层
下载楼主网盘的东西了,谢谢楼主,帮楼主上传

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-11-20 10:21:30 | 显示全部楼层
单个可以这样搞……用到产品的话,还有很多东西需要考虑,要考虑到通信中断了怎么办,上位机突然死机了怎么办……

我们的做法是自定义协议(带加密),自编上位机软件,这样在集中监控系统中可以根据列表批量升级。

出0入0汤圆

发表于 2013-11-20 10:33:44 | 显示全部楼层
我先下载楼主的SecureCRT,感谢

出0入0汤圆

发表于 2013-11-20 16:52:48 | 显示全部楼层
好资料,谢谢分享!

出0入0汤圆

发表于 2013-11-20 19:04:33 | 显示全部楼层
感谢!收藏.

出0入0汤圆

发表于 2013-11-20 20:06:07 | 显示全部楼层
mark,弄过一段时间DFU,但是奇怪只能升级一次,第二次升级会失败

出0入8汤圆

发表于 2013-11-20 20:06:43 来自手机 | 显示全部楼层
顶一下,明天仔细看看

出0入0汤圆

发表于 2013-11-20 21:38:02 来自手机 | 显示全部楼层
太好了!不帮顶都不好意思啦

出0入0汤圆

发表于 2013-11-21 11:57:04 | 显示全部楼层
ding ding

出0入0汤圆

发表于 2013-11-21 12:52:12 来自手机 | 显示全部楼层
不错,收藏了

出0入0汤圆

发表于 2014-1-17 15:07:33 | 显示全部楼层
对STM32不怎么熟悉,想知道

#define ApplicationAddress 0x8002000 //程序首地址
#define ApplicationSize 120000 //目标程序预留空间

这个目标程序预留空间ApplicationSize 是什么意思,是怎么算出来的啊???

出0入0汤圆

发表于 2014-1-17 20:37:24 | 显示全部楼层
谢谢分享!!!

出0入0汤圆

发表于 2014-1-17 22:33:09 | 显示全部楼层
赞!
在官方的包里也有。

出0入0汤圆

发表于 2014-1-17 22:34:20 | 显示全部楼层
SOFTWARE\APP\common.c(263): error:  #167: argument of type "void (*)(void)" is incompatible with parameter of type "void *"
SOFTWARE\APP\common.c(264): error:  #167: argument of type "void (*)(u8)" is incompatible with parameter of type "void *"

出0入0汤圆

发表于 2014-1-21 12:29:35 | 显示全部楼层
不错,讲解挺详细的

出0入0汤圆

发表于 2014-1-21 14:55:23 | 显示全部楼层
学习了,厉害啊,学无止境!

出100入101汤圆

发表于 2014-2-8 14:49:30 | 显示全部楼层
“在接收的这90ms左右的时间里,在接收下一帧结束这一期间内,可以把上一帧的数据写入到ROM中。 串口接收数据是中断的方式,所以收写操作基本上算同步运行”

是先把APP区全部擦除么?如果是擦一部分,然后写一部分,可能会有问题。擦除Flash时候,中断不会被执行。

出0入0汤圆

发表于 2014-2-11 22:56:29 来自手机 | 显示全部楼层
好资料,标记一下。

出0入0汤圆

发表于 2014-2-11 23:02:02 | 显示全部楼层
mark

出0入8汤圆

发表于 2014-2-16 09:24:45 来自手机 | 显示全部楼层
标记一下

出0入0汤圆

发表于 2014-2-18 08:51:14 | 显示全部楼层
谢谢共享

出0入0汤圆

发表于 2014-2-18 10:19:21 | 显示全部楼层
mark 收藏

出0入0汤圆

发表于 2014-2-23 11:56:28 | 显示全部楼层
讲得相当不错呀。

出0入0汤圆

发表于 2014-2-23 13:11:58 | 显示全部楼层
ymodem 多谢楼主。

出0入0汤圆

发表于 2014-2-24 14:01:27 | 显示全部楼层
先看看,还不知道怎么操作。

出0入0汤圆

发表于 2014-2-25 05:20:01 | 显示全部楼层
可以用putty吗?

出0入0汤圆

发表于 2014-2-26 10:06:16 | 显示全部楼层
这个真的还是不错的了!!

出0入0汤圆

发表于 2014-2-26 10:14:23 | 显示全部楼层
赞一个!

出0入0汤圆

发表于 2014-2-26 10:30:47 | 显示全部楼层
赞,回去慢慢看

出0入0汤圆

发表于 2014-2-26 12:25:04 | 显示全部楼层
不错,mark

出0入0汤圆

发表于 2014-3-5 14:14:20 | 显示全部楼层
下载来慢慢研究

出0入0汤圆

发表于 2014-6-18 20:23:41 | 显示全部楼层
移植到我的板子上之后,串口打印出来的全是乱码    不知是哪里的问题啊。。。

出0入0汤圆

发表于 2014-6-18 21:05:17 | 显示全部楼层
这个是很不错的,MARK一下。

出0入0汤圆

发表于 2014-6-19 09:15:35 | 显示全部楼层
支持楼主,收藏。。。

出0入0汤圆

发表于 2014-7-19 23:55:10 | 显示全部楼层
Mark 。学习思路。

出0入0汤圆

发表于 2014-8-3 20:58:56 | 显示全部楼层
明天移植下。多谢。

出0入0汤圆

发表于 2014-8-15 17:42:29 | 显示全部楼层
谢谢 ,楼主  下载试下

出0入0汤圆

发表于 2014-8-15 17:46:03 | 显示全部楼层
这个可以哦。支持一个。

出0入0汤圆

发表于 2014-8-16 11:33:29 | 显示全部楼层
这个要学习下

出0入0汤圆

发表于 2014-8-16 12:50:42 | 显示全部楼层
mark........

出0入0汤圆

发表于 2014-8-30 09:02:37 | 显示全部楼层
你好,最近在研究BootLoader 程序 ,通过研读了你写的代码  ,感觉非常不错 。但现在我遇到了一点问题是:

图片2中的问题是,字符C是调用哪个函数实现的,pData参数怎么获取的?

图片1中的问题是,当用xp系统的超级终端发送的文件时,一直跳转至  case eYM_END 执行,再跳转至ReceiveData函数中执行 case YM_EXIT ?  一直找不到什么原因,求解释?

你能否把你的QQ号留给我?
我的QQ:1012015251 ,谢谢!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-8-30 09:07:34 | 显示全部楼层
现在的问题是一直执行图片中的  case eYM_INIT  和  case eYM_RECE_HEAD_PACKET: 并通过if中的break 跳出循环。
if (IS_TIMEOUT_1MS(eTimYModem, NAK_TIMEOUT))            //若等待超时
        {         
            YmodemSendChar(CRC16, &stat, &sErrorCount);         //发送 'C'
            Print("\r\n ");
            stat = eYM_INIT;
            break;
        }


int YmodemReceive(char *pRece, int *sReceLen, char *pData, int *sResLen)
{
    int cRes = YM_VOIDER;
    static eYM_STAT stat= eYM_INIT;          //当前状态
   
    static char affirmCount = 0;                //确认次数   
    static int iNumber = 0;                     //数据包编号
    static int sErrorCount = 0;                 //错误包次数

    s8 cTmp = 0;
   
    switch (stat)
    {
    case eYM_INIT:
        iNumber = 0;
        sErrorCount = 0;   
        affirmCount = 0;
        stat = eYM_RECE_HEAD_PACKET;
        IS_TIMEOUT_1MS(eTimYModem, 0);          //清超时计数器
        Print("\r\n waite");
        break;

    case eYM_RECE_HEAD_PACKET:  //这个地方需注意 NAK_TIMEOUT
        //YmodemSendChar(CRC16, &stat, &sErrorCount);         //发送 'C'
        if (IS_TIMEOUT_1MS(eTimYModem, NAK_TIMEOUT))            //若等待超时
        {         
            YmodemSendChar(CRC16, &stat, &sErrorCount);         //发送 'C'
            Print("\r\n ");
            stat = eYM_INIT;
            break;
        }
            
        if (*sReceLen == 0)
            break;
  
        cTmp = ReceivePacket(pRece, *sReceLen, pData, sResLen, iNumber & 0xFF);
         Print("\r\n Incoming header files ");
        *sReceLen = 0;                  //读完数据后,允许接收新数据
        switch (cTmp)
        {
        case TRUE:                      //接收正确
         //下行代码由pData[PACKET_HEADER]   改为pData[PACKET_HEADER-1]
            if (pData[PACKET_HEADER] == 0)                      //无文件发送
                    {
                  stat = eYM_END;
                    Print("\r\n no file ");
                    }
            else
            {
                stat = eYM_RECE_DATA_START;                     //有文件发送
                cRes = YM_FILE_INFO;    //返回接收头文件
               
                Print("\r\n YES");
        //////////////////////////////////////////////////////////////////                       
                 //while(!IS_TIMEOUT_1MS(eTimYModem, 100));
        //////////////////////////////////////////////////////////////////
                iNumber++;
                affirmCount = 0;     
                          //  printf("\r\n 有文件发送,正准备发送数据");
            }
            break;

        case 0:                         //接收到结束标志
            if (affirmCount)
            {
                iNumber = 0;  
                 //while(!IS_TIMEOUT_1MS(eTimYModem, 50));
                YmodemSendChar(ACK, &stat, &sErrorCount);       //正确应答
                   Print("\r\nThe end of the ACK ");
               
            }
            else
            {      
                //while(!IS_TIMEOUT_1MS(eTimYModem, 50));
                 YmodemSendChar(NAK, &stat, &sErrorCount);       //错误应答 二次确认
                 Print("\r\n NAK");
                //while(!IS_TIMEOUT_1MS(eTimYModem, 50));
            }
            affirmCount++;
            break;

        default:                        //接收数据有误  
            affirmCount = 0;
            YmodemSendChar(NAK, &stat, &sErrorCount);           //错误应答
             Print("\r\n NAK NAK");
            break;
        }
        IS_TIMEOUT_1MS(eTimYModem, 0);                          //清超时计数器
        break;
        
    case eYM_RECE_DATA_START:
        stat = eYM_RECE_DATA;
        YmodemSendChar(ACK, &stat, &sErrorCount);               //正确应答
        YmodemSendChar(CRC16, &stat, &sErrorCount);             //发送 'C'
           Print("\r\n Begin to receive data");
        break;
               
    case eYM_RECE_DATA:
        if (IS_TIMEOUT_1MS(eTimYModem, NAK_TIMEOUT))            //若等待超时
        {
            stat = eYM_END;
            break;
        }
            
        if (*sReceLen == 0)
            break;
  
        cTmp = ReceivePacket(pRece, *sReceLen, pData, sResLen, iNumber & 0xFF);
        *sReceLen = 0;                  //读完数据后,允许接收新数据
        switch (cTmp)
        {
        case TRUE:                      //接收正确
            cRes = YM_FILE_DATA;        //返回接收数据正确
            iNumber++;                  //
            affirmCount = 0;
            YmodemSendChar(ACK, &stat, &sErrorCount);        //正确应答
            Print("\r\n ACK");
            break;

        case 0:                         //接收到结束标志
            if (affirmCount)
            {
                iNumber = 0;
                stat = eYM_RECE_HEAD_PACKET;
                 while(!IS_TIMEOUT_1MS(eTimYModem, 50));
                YmodemSendChar(ACK, &stat, &sErrorCount);    //正确应答
                Print("\r\nThe end of the ACK NUM ");
            }
            else
            {
                while(!IS_TIMEOUT_1MS(eTimYModem, 50));
                  YmodemSendChar(NAK, &stat, &sErrorCount);    //错误应答
                  Print("\r\nThe end of the NAK ");
            }
            affirmCount++;
            break;

        default:                        //接收数据有误  
            affirmCount = 0;
            YmodemSendChar(NAK, &stat, &sErrorCount);       //错误应答
            break;
        }
        IS_TIMEOUT_1MS(eTimYModem, 0);                      //清超时计数器        
        break;
        
    case eYM_END:
        YmodemSendChar(ACK, &stat, &sErrorCount);           //中止
        Print("\r\n suspend ACK");
        YmodemSendChar(CA, &stat, &sErrorCount);            //中止
        Print("\r\n suspend ACK");
        YmodemSendChar(CA, &stat, &sErrorCount);            //中止
        Print("\r\n suspend ACK");
        cRes = YM_EXIT;
        stat = eYM_INIT;
        break;
    }
   
    return cRes;
}

出0入0汤圆

 楼主| 发表于 2014-9-2 17:33:47 | 显示全部楼层
简简单单  单单简简   单单简简  简简单单   抛砖引玉   共同学习

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-9-9 15:42:51 | 显示全部楼层
FASHAOYIHAOAMO 发表于 2014-9-2 17:33
简简单单  单单简简   单单简简  简简单单   抛砖引玉   共同学习

怎么还需要密码啊,楼主,请告知,谢谢

出0入0汤圆

发表于 2014-9-9 15:46:48 | 显示全部楼层
yixingxing19 发表于 2014-9-9 15:42
怎么还需要密码啊,楼主,请告知,谢谢

密码居然试出来了......
密码:123456

出0入0汤圆

发表于 2014-9-9 16:20:40 | 显示全部楼层
谢谢分享,先收藏了。

出0入0汤圆

发表于 2014-9-9 16:29:38 | 显示全部楼层
妈的,这个真是极好的。

出0入0汤圆

发表于 2014-9-10 15:37:04 | 显示全部楼层
MARK,学习

出0入0汤圆

发表于 2014-9-10 16:46:16 | 显示全部楼层
不错 前段时间刚做过一个 比较下

出0入0汤圆

发表于 2014-10-6 09:35:07 | 显示全部楼层
bli19 发表于 2014-2-25 05:20
可以用putty吗?

putty可以发送文件吗?

出0入0汤圆

发表于 2014-10-7 00:22:21 | 显示全部楼层
mark,stm32 Bootloader设计(YModem协议)

出0入0汤圆

发表于 2014-10-9 17:37:36 | 显示全部楼层
正好要用到!

出0入0汤圆

发表于 2014-10-11 19:16:18 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2014-10-11 20:15:48 | 显示全部楼层
mask 好东西

出0入0汤圆

发表于 2014-10-11 20:36:45 | 显示全部楼层
不错,标记一下。

出0入0汤圆

发表于 2014-10-11 22:10:51 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2014-11-11 21:31:07 | 显示全部楼层
MARK,学习

出0入0汤圆

发表于 2015-8-5 21:23:20 | 显示全部楼层
FASHAOYIHAOAMO 发表于 2013-11-19 12:57
还是上传一个文件吧

请教:
1.bootloader.bin和stm32目标板程序.bin单独运行 没问题
2.同时下载bootloader.bin和stm32目标板程序.bin,进入boot(按C,然后选2,程序正常启动)

3.通过bootloader下载stm32目标板程序.bin,程序运行,但不能正常运行,请问这是什么问题

出0入0汤圆

发表于 2015-8-5 21:52:22 | 显示全部楼层
FASHAOYIHAOAMO 发表于 2013-11-19 12:57
还是上传一个文件吧

通过bootloader下载stm32目标板程序.bin,目标板程序堆栈地址FFFFFFFF,什么鬼?

出0入0汤圆

发表于 2015-8-6 09:40:20 | 显示全部楼层
谢谢,不错啊

出0入0汤圆

发表于 2015-8-7 00:17:27 | 显示全部楼层
帮顶下,辛苦了

出0入0汤圆

发表于 2015-8-7 13:19:41 | 显示全部楼层
好东西,学习一下

出0入0汤圆

发表于 2015-8-7 16:21:21 | 显示全部楼层
好东西!这个得收藏了!

出0入0汤圆

发表于 2015-8-8 16:12:47 | 显示全部楼层
WIN7 64bit 可以运行超级终端啊~ 我的电脑用的好好的~

出0入0汤圆

发表于 2015-8-9 08:09:36 | 显示全部楼层
灰常不错,好好学习

出0入0汤圆

发表于 2015-8-9 08:14:06 | 显示全部楼层

好东西,学习一下

出0入0汤圆

发表于 2015-8-9 10:09:44 | 显示全部楼层
这次让我看见了Ymodem协议真实面目,以前只是知道用。。。。

出0入0汤圆

发表于 2015-8-13 14:36:51 | 显示全部楼层
mhw 发表于 2013-11-20 10:21
单个可以这样搞……用到产品的话,还有很多东西需要考虑,要考虑到通信中断了怎么办,上位机突然死机了怎么 ...

如果需要,能出售一份么!

出0入0汤圆

发表于 2015-8-15 17:45:13 | 显示全部楼层
mark一下,收藏了

出0入0汤圆

发表于 2015-8-16 11:28:41 | 显示全部楼层
学习了,收藏一下

出0入0汤圆

发表于 2015-8-16 12:11:24 | 显示全部楼层
MARK一下!

出0入25汤圆

发表于 2015-8-16 12:43:20 | 显示全部楼层
把XP的超级终端抠出来,Win7 x64用得上好的飘过。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2015-8-16 13:06:24 | 显示全部楼层
mark!!!~~

出0入0汤圆

发表于 2015-8-16 23:34:01 | 显示全部楼层
这个要收藏一下

出0入0汤圆

发表于 2015-8-20 08:54:17 | 显示全部楼层
很不错,感谢楼主

出0入0汤圆

发表于 2015-10-31 12:58:46 | 显示全部楼层
huangfeian0527 发表于 2014-8-30 09:02
你好,最近在研究BootLoader 程序 ,通过研读了你写的代码  ,感觉非常不错 。但现在我遇到了一点问题是:
...

你好,请问你图二的问题有没有解决?我最近开始研究这个代码,也感到很困惑。

出0入0汤圆

发表于 2015-10-31 13:01:50 | 显示全部楼层
谢谢,学习一下  

出0入13汤圆

发表于 2015-11-2 00:10:58 来自手机 | 显示全部楼层
这么好的东西,支持一下

出0入0汤圆

发表于 2015-11-5 08:48:16 | 显示全部楼层
最近在学习STM32跑rt-thread  ,搞个bootloader来启动系统
学习下

出0入0汤圆

发表于 2016-1-11 15:44:35 | 显示全部楼层
非常感谢楼主分享,会研究下楼主的方法。

出0入0汤圆

发表于 2016-1-12 10:34:33 | 显示全部楼层
不错,可以参考下~

出0入0汤圆

发表于 2016-1-12 11:13:44 | 显示全部楼层
mark一下

出0入0汤圆

发表于 2016-2-21 15:13:18 | 显示全部楼层

出0入0汤圆

 楼主| 发表于 2016-3-20 20:26:18 | 显示全部楼层
大家可以好好看看启动文件,好长时间不搞了,想想当时最主要的还是那里!!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-23 18:56

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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