OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4076|回复: 18

BootLoader只能升级一次

[复制链接]

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
发表于 2018-8-6 17:24:41 | 显示全部楼层 |阅读模式
3金钱
本帖最后由 午夜狼嚎 于 2018-8-7 17:13 编辑

单片机型号:STM32F103C8T6
模仿原子哥战舰V3里的IAP例程写了个BootLoader,但是只能进行一次升级。也就是将第一个APP程序通过串口发送给单片机后可以进行升级,但是我将另一个APP程序发送给单片机后没有实现升级。什么原因会导致这种情况啊?

或者我这么问:APP运行时怎么进入串口中断?我在BootLoader和APP里面都开启了串口中断,但是APP升级运行后,进不了中断了。

方法如下:
通过USART1发送APP程序,APP程序发送完后,再发送0101执行将APP程序从SRAM写入FLASH,然后在FLASH中写入一个2作为升级完成标志,最后通过判断这个标志执行跳转到APP程序的操作。

部分代码:
void USART1_IRQHandler(void)
{
        u8 res;        
        res=USART_ReceiveData(USART1);
        USART_RX_BUF[USART_RX_CNT]=res;
        USART_RX_CNT++;        
        if((USART_RX_BUF[USART_RX_CNT-1] == 0x01)&&(USART_RX_BUF[USART_RX_CNT-2] == 0x01))
                {
                if(((*(vu32*)(0X20001000+4))&0xFF000000)==0x08000000)                                                        
                        {         
                                iap_write_appbin(FLASH_APP1_ADDR,USART_RX_BUF,USART_RX_CNT);                   //将APP程序写入FLASH   
                                Test_Write(UPDATE_FLAG,2);                                                                            //跳转标志
                                USART_RX_CNT=0;
                        }
                }        
}


int main(void)
{               
        uart_init(115200);                                    
                                          
        while(1)
        {
                flag = STMFLASH_ReadHalfWord(UPDATE_FLAG);
                if(flag == 2)
                {
                        
                        if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)
                        {         
                                iap_load_app(FLASH_APP1_ADDR);                                              //跳转至APP
                        }         
                        Test_Write(UPDATE_FLAG,0);
                }
        }              
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

35

主题

560

帖子

2

精华

资深版主

Rank: 8Rank: 8

积分
17786
金钱
17786
注册时间
2018-3-3
在线时间
523 小时
发表于 2018-8-6 17:35:56 | 显示全部楼层
你升级后就没有运行bootloder程序了,怎么升级。。。。
/*
*
*
*
*
*
*/
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-8-6 17:46:41 | 显示全部楼层
Psheng 发表于 2018-8-6 17:35
你升级后就没有运行bootloder程序了,怎么升级。。。。

"在新程序 main 函数执行的过程中,当中断来临时PC指针仍会回跳转至地址为
0x8000004 中断向量表处,而并不是新程序的中断向量表,这是由STM32的硬件机制决定的"

它会自己跳回去的
回复

使用道具 举报

9

主题

796

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2038
金钱
2038
注册时间
2017-8-2
在线时间
522 小时
发表于 2018-8-6 17:51:21 | 显示全部楼层
会不会是你第二个程序有问题...还是固定第二个就出问题...
猪猪熊呢?
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-8-6 17:57:04 | 显示全部楼层
323232 发表于 2018-8-6 17:51
会不会是你第二个程序有问题...还是固定第二个就出问题...

两个APP程序单独升级都没问题(升级另一个之前需要重新下载BootLoader程序)。在下载好BootLoader和第一个APP后,再下载别的APP就不行。
回复

使用道具 举报

35

主题

560

帖子

2

精华

资深版主

Rank: 8Rank: 8

积分
17786
金钱
17786
注册时间
2018-3-3
在线时间
523 小时
发表于 2018-8-6 18:46:09 | 显示全部楼层
本帖最后由 Psheng 于 2018-8-6 18:48 编辑
午夜狼嚎 发表于 2018-8-6 17:46
"在新程序 main 函数执行的过程中,当中断来临时PC指针仍会回跳转至地址为
0x8000004 中断向量表处,而 ...

但是你升级没有复位呀,复位当然是重新运行bootloder程序。你那个app标志有没有优先级的呀
/*
*
*
*
*
*
*/
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-8-7 09:12:42 | 显示全部楼层
Psheng 发表于 2018-8-6 18:46
但是你升级没有复位呀,复位当然是重新运行bootloder程序。你那个app标志有没有优先级的呀

"在新程序 main 函数执行的过程中,当中断来临时PC指针仍会回跳转至地址为0x8000004 中断向量表处,而并不是新程序的中断向量表,这是由STM32的硬件机制决定的"

我的理解是0x08000004处的中断总是优先于APP的中断,也就是在BootLoader中我开启了USART1接收中断,在APP程序运行过程中,当USART1接收到东西时,PC指针会跳回0x08000004处开始查询中断,也就会执行USART1接收中断,所以不需要在APP执行过程中去复位再下载另一个APP。并且当我下载好一个APP后,不管怎么复位,程序都会跳转到这个APP执行,不然有何意义。所以APP标志也就更没有优先级了,因为在USART1中断里,我就已经对APP进行重写了,以前的APP会被覆盖掉
回复

使用道具 举报

15

主题

866

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7623
金钱
7623
注册时间
2016-11-30
在线时间
646 小时
发表于 2018-8-7 10:30:50 | 显示全部楼层
if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)
                        {         
                                Test_Write(UPDATE_FLAG,0);
                                iap_load_app(FLASH_APP1_ADDR);                                              //跳转至APP
                        }         
这样试试
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-8-7 11:03:59 | 显示全部楼层
lvkanger 发表于 2018-8-7 10:30
if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)
                        {         
    ...

这个bug已经找到了,但是还是只能升级一次。
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-8-7 14:11:28 | 显示全部楼层
@正点原子
原子哥,求助啊~
回复

使用道具 举报

6

主题

315

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1669
金钱
1669
注册时间
2018-1-29
在线时间
160 小时
发表于 2018-8-7 15:12:58 | 显示全部楼层
把我遇到的问题与楼主分享一下:
我遇到过一种情况BootLoader只能升级一次,就是 Bootloader程序的尺寸大于预留空间,
假设Bootloader预留空间是20KB,而Bootloader实际是20.5KB
第一次运行Bootloader时是好用的, Bootloader把应用程序从FLASH_BASE+20KB处开始写入,恰好破坏了原有Bootloader程序的最后一小部分.
这样第二次运行Bootloader就不会成功,无法再升级了!
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-8-7 16:24:55 | 显示全部楼层
backup2k 发表于 2018-8-7 15:12
把我遇到的问题与楼主分享一下:
我遇到过一种情况BootLoader只能升级一次,就是 Bootloader程序的尺寸大于 ...

这个已经反复核对过,空间大小没问题
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-8-7 17:16:34 | 显示全部楼层
或者我这么问:APP运行时怎么进入串口中断?我在BootLoader和APP里面都开启了串口中断,但是APP升级运行后,就进不了中断了。

"在新程序 main 函数执行的过程中,当中断来临时PC指针仍会回跳转至地址为0x8000004 中断向量表处,而并不是新程序的中断向量表,这是由STM32的硬件机制决定的"
根据上面这句话的理解,当APP运行时,串口接收到东西进入接收中断,就应该是跳转到0x8000004处,然后接着就是执行BootLoader里面的串口中断处理函数吧。我理解的到底对不对,如果对,那为什么进不了。
回复

使用道具 举报

6

主题

315

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1669
金钱
1669
注册时间
2018-1-29
在线时间
160 小时
发表于 2018-8-8 07:19:51 | 显示全部楼层
我的建议: bootloader的中断向量不好和APP的中断向量混用,在APP中重新定位一下中断向量即可.
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-8-8 09:01:47 | 显示全部楼层
backup2k 发表于 2018-8-8 07:19
我的建议: bootloader的中断向量不好和APP的中断向量混用,在APP中重新定位一下中断向量即可.

重新定位了的,也不行
回复

使用道具 举报

15

主题

866

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7623
金钱
7623
注册时间
2016-11-30
在线时间
646 小时
发表于 2018-8-8 09:26:54 | 显示全部楼层
你难道是想要在APP程序里接收新的程序,然后通过串口中断进行新程序的更新?如果是这样,那么问题就是,你旧的APP程序还在运行当中,是没有办法进行擦除操作的。你用新的APP覆盖旧的APP时,必须保证程序运行在BOOT区才行,可能是你的策略有问题,好好捋一捋。
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-8-8 10:18:04 | 显示全部楼层
lvkanger 发表于 2018-8-8 09:26
你难道是想要在APP程序里接收新的程序,然后通过串口中断进行新程序的更新?如果是这样,那么问题就是,你 ...

经过反复理解,多次尝试,现在已经初步解决了。我在APP里面开启了串口及接受中断,然后APP运行过程中,接收到新的串口数据时,会跳转到BootLoader的串口中断执行相关操作,这样就好了。但还是不够满意,总觉得还欠点什么。我再多找点资料,多理解理解,还是对整个系统的运行理解不够,后面慢慢优化程序吧。

谢谢各位了!
回复

使用道具 举报

62

主题

903

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3567
金钱
3567
注册时间
2016-1-8
在线时间
544 小时
发表于 2018-8-8 11:04:29 | 显示全部楼层
第二个程序不对,这么明显的道理
回复

使用道具 举报

17

主题

194

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1049
金钱
1049
注册时间
2016-9-3
在线时间
158 小时
 楼主| 发表于 2018-8-8 11:12:54 | 显示全部楼层
Sun_Fly 发表于 2018-8-8 11:04
第二个程序不对,这么明显的道理

程序功能是没问题的,单独下载都可以实现功能,是APP里串口没设置,导致无法进入串口中断
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-13 16:42

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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