正点原子stm32论坛摄像头实验中的res=40是怎么来的

21ic官方微信
后使用快捷导航没有帐号?
大家怎么看正点原子的代码?
&&已结帖(5)
主题帖子积分
实习生, 积分 3, 距离下一级还需 47 积分
实习生, 积分 3, 距离下一级还需 47 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
实习生, 积分 3, 距离下一级还需 47 积分
实习生, 积分 3, 距离下一级还需 47 积分
理工科的东西还是先会用再去研究深入的事吧,上来就搞那么高深会不会显得门槛太高?这点原子和野火还是很不错的,至少能保证新手能顺利做项目~
主题帖子积分
中级技术员, 积分 246, 距离下一级还需 54 积分
中级技术员, 积分 246, 距离下一级还需 54 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
中级技术员, 积分 246, 距离下一级还需 54 积分
中级技术员, 积分 246, 距离下一级还需 54 积分
我个人觉得正点原子的和51的思想也是一样的,可以用同一种思路来学习。。。
主题帖子积分
助理工程师, 积分 1137, 距离下一级还需 863 积分
助理工程师, 积分 1137, 距离下一级还需 863 积分
主题帖子积分
专家等级:结帖率:45%
主题帖子积分
助理工程师, 积分 1137, 距离下一级还需 863 积分
助理工程师, 积分 1137, 距离下一级还需 863 积分
没有按部就班的看,需要什么就学习什么,用到哪块就去学习哪块。
主题帖子积分
初级技术员, 积分 69, 距离下一级还需 31 积分
初级技术员, 积分 69, 距离下一级还需 31 积分
主题帖子积分
专家等级:结帖率:50%
主题帖子积分
初级技术员, 积分 69, 距离下一级还需 31 积分
初级技术员, 积分 69, 距离下一级还需 31 积分
对于初学者来说,是非常好的入门,进阶教程。
主题帖子积分
主题帖子积分
专家等级:结帖率:96%打赏:0.00受赏:43.10
主题帖子积分
寄存器编程能帮助理解底层,还是有存在的必要的!
单片机编程最主要的两个思想“结构分层”跟“时间片轮”,
个人感觉原子的东西做的还是不错的!
年轻不是资本,奋斗才是良策!
主题帖子积分
中级技术员, 积分 123, 距离下一级还需 177 积分
中级技术员, 积分 123, 距离下一级还需 177 积分
主题帖子积分
专家等级:结帖率:25%
主题帖子积分
中级技术员, 积分 123, 距离下一级还需 177 积分
中级技术员, 积分 123, 距离下一级还需 177 积分
总的来说还是不错的
主题帖子积分
中级技术员, 积分 256, 距离下一级还需 44 积分
中级技术员, 积分 256, 距离下一级还需 44 积分
主题帖子积分
专家等级:结帖率:100%
主题帖子积分
中级技术员, 积分 256, 距离下一级还需 44 积分
中级技术员, 积分 256, 距离下一级还需 44 积分
oipklll85 发表于
我不否认正点原子的板子以及代码对于初学者的意义。但是个人比较倾向于用库函数。软件开发其实就是看着API ...
估计你是纯软过来,的确pc开发都用库,比如mfc,关键人家的库是正规军,也有详细说明,st的库烂大街,mcu里面最好的是飞思卡尔的pe,比起飞思卡尔,st芯片真水,毕竟价格差太远,m3的富士通都比st的规范多了,而且现在大公司都直接用geny来生成芯片级代码,几十万一个模块软件
主题帖子积分
初级技术员, 积分 61, 距离下一级还需 39 积分
初级技术员, 积分 61, 距离下一级还需 39 积分
主题帖子积分
专家等级:结帖率:0%打赏:0.00受赏:10.00
主题帖子积分
初级技术员, 积分 61, 距离下一级还需 39 积分
初级技术员, 积分 61, 距离下一级还需 39 积分
寄存器就像找**交了钱就可以干,库函数就是娶媳妇得一步一步来
主题帖子积分
实习生, 积分 18, 距离下一级还需 32 积分
实习生, 积分 18, 距离下一级还需 32 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
实习生, 积分 18, 距离下一级还需 32 积分
实习生, 积分 18, 距离下一级还需 32 积分
看来兄弟恨我不浅啊。。。
我们也有库函数版本例程,兄台是否有看到?
其实,做一件事会有很多种不同的方式,各种方式都会有不一样的原因和理由。
就我个人而言,我喜欢的和崇尚的方式 和 原子君 的也不一样。
曾经,我也对此(当然不只是原子君)愤世嫉俗。
但做的时间久了,遇到的时间多了,我发现,正点原子,是stm32,至少是例程无法绕过去的。
现在大把大把的例程都是基于stm32,而且就是f103,不是别的。
就像曾经的51,是事实上的标准。
而国内的资料和例程里,正点原子 是相当无可挑剔的,非常详细,比起ST官方,他更懂我们开发者真正需要的东西。
当然,我木有买原子君的板子,因为我很多的时候都是基于特定的,自己的板子在做东西,当然,原子君也木有给我广告费,所以那个啥,就不多说这种看起来像广告的东西。
说回 程序怎么写,,XX的代码怎么看这个问题。
我觉得,不同的人看原子的代码肯定有不一样的看法,我们不必夸到天上去,但也不能随便贬到地下十八层,先不说自己有没人家那个水平,也不说有没做出人家的成就。
不管如何,我现在开始认为,各种不一样的方式和事物同时共存才是应该有的状况。
各取所需便是。
不能太偏激。
主题帖子积分
中级技术员, 积分 266, 距离下一级还需 34 积分
中级技术员, 积分 266, 距离下一级还需 34 积分
主题帖子积分
专家等级:结帖率:83%
主题帖子积分
中级技术员, 积分 266, 距离下一级还需 34 积分
中级技术员, 积分 266, 距离下一级还需 34 积分
楼主,你这样想就大错特错了,刚学STM32的时候,也是楼主这个思想,在实际做项目的过程中,你会慢慢发现库函数写个简单的代码,底层还是可以用用的,等到真正做到速度要求很快的时候,那你还用库函数那就只能说你牛逼,千万不要图省事,高手是库函数和寄存器用,而且上升到算法层次,我相信90%的人都是用寄存器来操作的,毕竟库函数可读性比寄存器的可读性差的好多!!
这个我很同意&
主题帖子积分
助理工程师, 积分 1442, 距离下一级还需 558 积分
助理工程师, 积分 1442, 距离下一级还需 558 积分
主题帖子积分
专家等级:结帖率:78%
主题帖子积分
助理工程师, 积分 1442, 距离下一级还需 558 积分
助理工程师, 积分 1442, 距离下一级还需 558 积分
不得不讲楼主有些脑残, 正点原子费尽心思做了寄存器和库函数两个版本软件及教程,满足了绝大部分客户需求,ST公司都敬为座上宾,你懂多少呢,在这里评论,该去上吊了!
主题帖子积分
助理工程师, 积分 1116, 距离下一级还需 884 积分
助理工程师, 积分 1116, 距离下一级还需 884 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
助理工程师, 积分 1116, 距离下一级还需 884 积分
助理工程师, 积分 1116, 距离下一级还需 884 积分
开发板的例程本来就不是用来移植的,想可移植的程序,交钱。
主题帖子积分
资深技术员, 积分 330, 距离下一级还需 170 积分
资深技术员, 积分 330, 距离下一级还需 170 积分
主题帖子积分
专家等级:结帖率:100%
主题帖子积分
资深技术员, 积分 330, 距离下一级还需 170 积分
资深技术员, 积分 330, 距离下一级还需 170 积分
支持正点原子,开源最全
主题帖子积分
初级工程师, 积分 2451, 距离下一级还需 549 积分
初级工程师, 积分 2451, 距离下一级还需 549 积分
主题帖子积分
专家等级:结帖率:100%
主题帖子积分
初级工程师, 积分 2451, 距离下一级还需 549 积分
初级工程师, 积分 2451, 距离下一级还需 549 积分
没有HAL版本的,这个才是现在的发展方向。
主题帖子积分
中级工程师, 积分 3371, 距离下一级还需 1629 积分
中级工程师, 积分 3371, 距离下一级还需 1629 积分
主题帖子积分
专家等级:结帖率:100%打赏:0.00受赏:5.00
主题帖子积分
中级工程师, 积分 3371, 距离下一级还需 1629 积分
中级工程师, 积分 3371, 距离下一级还需 1629 积分
用寄存器误导新手,食古不化,应该挂路灯上吊死!
主题帖子积分
实习生, 积分 6, 距离下一级还需 44 积分
实习生, 积分 6, 距离下一级还需 44 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
实习生, 积分 6, 距离下一级还需 44 积分
实习生, 积分 6, 距离下一级还需 44 积分
原子大哥的板子还是不错的,比较适合新手,虽然我买的是别的牌子的板子,但是有时候一些问题还是帮了我不少。。。。
主题帖子积分
资深技术员, 积分 311, 距离下一级还需 189 积分
资深技术员, 积分 311, 距离下一级还需 189 积分
主题帖子积分
专家等级:结帖率:87%
主题帖子积分
资深技术员, 积分 311, 距离下一级还需 189 积分
资深技术员, 积分 311, 距离下一级还需 189 积分
学的时候可以从寄存器学,这样能更深入了解这款单片机。实际项目的时候节省项目周期就可以用库函数
主题帖子积分
中级工程师, 积分 3934, 距离下一级还需 1066 积分
中级工程师, 积分 3934, 距离下一级还需 1066 积分
主题帖子积分
专家等级:结帖率:100%打赏:0.00受赏:5.00
主题帖子积分
中级工程师, 积分 3934, 距离下一级还需 1066 积分
中级工程师, 积分 3934, 距离下一级还需 1066 积分
好像也有库函数版本的
主题帖子积分
助理工程师, 积分 1307, 距离下一级还需 693 积分
助理工程师, 积分 1307, 距离下一级还需 693 积分
主题帖子积分
专家等级:结帖率:100%
主题帖子积分
助理工程师, 积分 1307, 距离下一级还需 693 积分
助理工程师, 积分 1307, 距离下一级还需 693 积分
愚人之见,真正好的稳定代码都是基于寄存器版本的,,
主题帖子积分
中级技术员, 积分 166, 距离下一级还需 134 积分
中级技术员, 积分 166, 距离下一级还需 134 积分
主题帖子积分
专家等级:结帖率:100%打赏:0.00受赏:33.00
主题帖子积分
中级技术员, 积分 166, 距离下一级还需 134 积分
中级技术员, 积分 166, 距离下一级还需 134 积分
我们代码有寄存器库函数两个版本。
所以,看我们的代码,请看全面了再做定论。
我正在用正点原子的开发板,感觉资料什么的都非常的丰富。至于库函数这些,我觉得例程里面没有很好的分析这一段代码的架构,所以学习起来也是有一定的难度的。
时间类勋章
技术高手奖章
人才类勋章
晶莹之水滴
发帖类勋章
甘甜之泉水
发帖类勋章
时间类勋章
技术奇才奖章
人才类勋章
希望之星奖章
等级类勋章
社区建设奖章
等级类勋章
欢快之小溪
发帖类勋章
技术新星奖章
人才类勋章
坚毅之洋流
发帖类勋章
时间类勋章
核心会员奖章
等级类勋章查看: 6580|回复: 22
【正点原子探索者STM32F407开发板例程连载+教学】第55章 串口IAP实验
主题帖子精华
在线时间32 小时
第五十五章 串口IAP实验
&1.硬件平台:正点原子探索者STM32F407开发板&&2.软件平台:MDK5.1&&3.固件库版本:V1.4.0
IAP,即在应用编程。很多单片机都支持这个功能,STM32F4也不例外。在之前的FLASH模拟EEPROM实验里面,我们学习了STM32F4的FLASH自编程,本章我们将结合FLASH自编程的知识,通过STM32F4的串口实现一个简单的IAP功能本章分为如下几个部:
55.1 IAP简介
55.2 硬件设计
55.3 软件设计
55.4 下载验证
55.1 IAP简介&&&
IAP(In Application Programming)即在应用编程,IAP是用户自己的程序在运行过程中对User Flash的部分区域进行烧写,目的是为了在产品发布后可以方便地通过预留的通信口对产品中的固件程序进行更新升级。 通常实现IAP功能时,即用户程序运行中作自身的更新操作,需要在设计固件程序时编写两个项目代码,第一个项目程序不执行正常的功能操作,而只是通过某种通信方式(如USB、USART)接收程序或数据,执行对第二部分代码的更新;第二个项目代码才是真正的功能代码。这两部分项目代码都同时烧录在User Flash中,当芯片上电后,首先是第一个项目代码开始运行,它作如下操作:
1)检查是否需要对第二部分代码进行更新
2)如果不需要更新则转到4)
3)执行更新操作
4)跳转到第二部分代码执行
第一部分代码必须通过其它手段,如JTAG或ISP烧入;第二部分代码可以使用第一部分代码IAP功能烧入,也可以和第一部分代码一起烧入,以后需要程序更新时再通过第一部分IAP代码更新。
我们将第一个项目代码称之为Bootloader程序,第二个项目代码称之为APP程序,他们存放在STM32F4
FLASH的不同地址范围,一般从最低地址区开始存放Bootloader,紧跟其后的就是APP程序(注意,如果FLASH容量足够,是可以设计很多APP程序的,本章我们只讨论一个APP程序的情况)。这样我们就是要实现2个程序:Bootloader和APP。
STM32F4的APP程序不仅可以放到FLASH里面运行,也可以放到SRAM里面运行,本章,我们将制作两个APP,一个用于FLASH运行,一个用于SRAM运行。
我们先来看看STM32F4正常的程序运行流程,如图55.1.1所示:
5d9cbde17db3d_525.png (0 Bytes, 下载次数: 0)
22:54 上传
图55.1.1 STM32F4正常运行流程图
&&&&&& STM32F4的内部闪存(FLASH)地址起始于0x,一般情况下,程序文件就从此地址开始写入。此外STM32F4是基于Cortex-M4内核的微控制器,其内部通过一张“中断向量表”来响应中断,程序启动后,将首先从“中断向量表”取出复位中断向量执行复位中断程序完成启动,而这张“中断向量表”的起始地址是0x,当中断来临,STM32F4的内部硬件机制亦会自动将PC指针定位到“中断向量表”处,并根据中断源取出对应的中断向量执行中断服务程序。
&&&&&& 在图55.1.1中,STM32F4在复位后,先从0X地址取出复位中断向量的地址,并跳转到复位中断服务程序,如图标号①所示;在复位中断服务程序执行完之后,会跳转到我们的main函数,如图标号②所示;而我们的main函数一般都是一个死循环,在main函数执行过程中,如果收到中断请求(发生重中断),此时STM32F4强制将PC指针指回中断向量表处,如图标号③所示;然后,根据中断源进入相应的中断服务程序,如图标号④所示;在执行完中断服务程序以后,程序再次返回main函数执行,如图标号⑤所示。
&&&&&& 当加入IAP程序之后,程序运行流程如图55.1.2所示:
fe61bec5e457d30273a70fecd25c59ee_279.png (0 Bytes, 下载次数: 0)
22:54 上传
图55.1.2 加入IAP之后程序运行流程图
&&&&&& 在图55.1.2所示流程中,STM32F4复位后,还是从0X地址取出复位中断向量的地址,并跳转到复位中断服务程序,在运行完复位中断服务程序之后跳转到IAP的main函数,如图标号①所示,此部分同图55.1.1一样;在执行完IAP以后(即将新的APP代码写入STM32F4的FLASH,灰底部分。新程序的复位中断向量起始地址为0X+N+M),跳转至新写入程序的复位向量表,取出新程序的复位中断向量的地址,并跳转执行新程序的复位中断服务程序,随后跳转至新程序的main函数,如图标号②和③所示,同样main函数为一个死循环,并且注意到此时STM32F4的FLASH,在不同位置上,共有两个中断向量表。
&&&&&& 在main函数执行过程中,如果CPU得到一个中断请求,PC指针仍强制跳转到地址0X中断向量表处,而不是新程序的中断向量表,如图标号④所示;程序再根据我们设置的中断向量表偏移量,跳转到对应中断源新的中断服务程序中,如图标号⑤所示;在执行完中断服务程序后,程序返回main函数继续运行,如图标号⑥所示。
&&&&&& 通过以上两个过程的分析,我们知道IAP程序必须满足两个要求:
1)& 新程序必须在IAP程序之后的某个偏移量为x的地址开始;
2)& 必须将新程序的中断向量表相应的移动,移动的偏移量为x;
本章,我们有2个APP程序,一个为FLASH的APP,另外一个位SRAM的APP,图55.1.2虽然是针对FLASH APP来说的,但是在SRAM里面运行的过程和FLASH基本一致,只是需要设置向量表的地址为SRAM的地址。
1.APP程序起始地址设置方法
随便打开一个之前的实例工程,点击Options for TargetàTarget选项卡,如图55.1.3所示:
4bf38b3c513bd7da15dd88aab3cfec83_117.jpg (0 Bytes, 下载次数: 0)
22:54 上传
图55.1.3 FLASH APP Target选项卡设置
&&&&&& 默认的条件下,图中IROM1的起始地址(Start)一般为0X,大小(Size)为0X100000,即从0X开始的1024K空间为我们的程序存储区。而图中,我们设置起始地址(Start)为0X,即偏移量为0X10000(64K字节),因而,留给APP用的FLASH空间(Size)只有0XX00(960K字节)大小了。设置好Start和Szie,就完成APP程序的起始地址设置。
&&&&&& 这里的64K字节,需要大家根据Bootloader程序大小进行选择,比如我们本章的Bootloader程序为36K左右,理论上我们只需要确保APP起始地址在Bootloader之后,并且偏移量为0X200的倍数即可(相关知识,请参考:)。这里我们选择64K(0X10000)字节,留了一些余量,方便Bootloader以后的升级修改。
&&&&&& 这是针对FLASH
APP的起始地址设置,如果是SRAM APP,那么起始地址设置如图55.1.4所示:
bfc4cac388c4024daae5d694_753.jpg (0 Bytes, 下载次数: 0)
22:54 上传
图55.1.4 SRAM APP Target选项卡设置
&&&&&& 这里我们将IROM1的起始地址(Start)定义为:0X,大小为0X19000(100K字节),即从地址0X偏移0X1000开始,存放APP代码。因为整个STM32F407ZGT6的SRAM大小(不算CCM)为128K字节,所以IRAM1(SRAM)的起始地址变为0X,大小只有0X6000(24K字节)。这样,整个STM32F407ZGT6的SRAM(不含CCM)分配情况为:最开始的4K给Bootloader程序使用,随后的100K存放APP程序,最后24K,用作APP程序的内存。这个分配关系大家可以根据自己的实际情况修改,不一定和我们这里的设置一模一样,不过也需要注意,保证偏移量为0X200的倍数(我们这里为0X1000)。
&&&&&& 2.中断向量表的偏移量设置方法
&&&&&& 之前我们讲解过,在系统启动的时候,会首先调用SystemInit函数初始化时钟系统,同时SystemInit还完成了中断向量表的设置,我们可以打开SystemInit函数,看看函数体的结尾处有这样几行代码:
VECT_TAB_SRAM
SCB-&VTOR = SRAM_BASE | VECT_TAB_OFFSET;
&/* Vector Table Relocation in
Internal SRAM. */
SCB-&VTOR = FLASH_BASE | VECT_TAB_OFFSET;
/* Vector Table Relocation in Internal FLASH. */
从代码可以理解,VTOR寄存器存放的是中断向量表的起始地址。默认的情况VECT_TAB_SRAM是没有定义,所以执行SCB-&VTOR = FLASH_BASE | VECT_TAB_OFFSET;&
对于FLASH APP,我们设置为FLASH_BASE+偏移量0x10000,所以我们可以在SystemInit函数里面修改SCB-&VTOR的值。当然为了尽可能不修改系统级别文件,我们可以也可以在FLASH
APP的main函数最开头处添加如下代码实现中断向量表的起始地址的重设:
SCB-&VTOR = FLASH_BASE | 0x10000;
&&&&&& 以上是FLASH APP的情况,当使用SRAM APP的时候,我们设置起始地址为:SRAM_BASE+0x1000,同样的方法,我们在SRAM APP的main函数最开始处,添加下面代码:
SCB-&VTOR = SRAM_BASE | 0x1000;
&&&&&& 这样,我们就完成了中断向量表偏移量的设置。
通过以上两个步骤的设置,我们就可以生成APP程序了,只要APP程序的FLASH和SRAM大小不超过我们的设置即可。不过MDK默认生成的文件是.hex文件,并不方便我们用作IAP更新,我们希望生成的文件是.bin文件,这样可以方便进行IAP升级(至于为什么,请大家自行百度HEX和BIN文件的区别!)。这里我们通过MDK自带的格式转换工具fromelf.exe,来实现.axf文件到.bin文件的转换。该工具在MDK的安装目录\ARM\BIN40文件夹里面。
fromelf.exe转换工具的语法格式为:fromelf [options]
input_file。其中options有很多选项可以设置,详细使用请参考光盘《mdk如何生成bin文件.doc》.
本章,我们通过在MDK点击Options for
TargetàUser选项卡,在Run User Programs After Build/Rebuild 栏,勾选Run #1,并写入:D:\MDK5.11A\ARM\ARMCC\bin\fromelf.exe& --bin -o ..\
OBJ\TEST.bin ..\OBJ\TEST.axf ,如图55.1.5所示:
98e1d8aec1cf1_317.jpg (0 Bytes, 下载次数: 0)
22:54 上传
图55.1.5 MDK生成.bin文件设置方法
&&&&&& 通过这一步设置,我们就可以在MDK编译成功之后,调用fromelf.exe(注意,我的MDK是安装在D:\MDK5.11A文件夹下,如果你是安装在其他目录,请根据你自己的目录修改fromelf.exe的路径),根据当前工程的TEST.axf,生成一个TEST.bin的文件。并存放在axf文件相同的目录下,即工程的OBJ文件夹里面。在得到.bin文件之后,我们只需要将这个bin文件传送给单片机,即可执行IAP升级。
&&&&&& 最后再来看看APP程序的生成步骤:
1) 设置APP程序的起始地址和存储空间大小
对于在FLASH里面运行的APP程序,我们只需要设置APP程序的起始地址,和存储空间大小即可。而对于在SRAM里面运行的APP程序,我们还需要设置SRAM的起始地址和大小。无论哪种APP程序,都需要确保APP程序的大小和所占SRAM大小不超过我们的设置范围。
2) 设置中断向量表偏移量
这一步按照上面讲解,重新设置SCB-&VTOR的值即可。
3) 设置编译后运行fromelf.exe,生成.bin文件.
通过在User选项卡,设置编译后调用fromelf.exe,根据.axf文件生成.bin文件,用于IAP更新。&
以上3个步骤,我们就可以得到一个.bin的APP程序,通过Bootlader程序即可实现更新。
55.2 硬件设计
本章实验(Bootloader部分)功能简介:开机的时候先显示提示信息,然后等待串口输入接收APP程序(无校验,一次性接收),在串口接收到APP程序之后,即可执行IAP。如果是SRAM APP,通过按下KEY0即可执行这个收到的SRAM APP程序。如果是FLASH APP,则需要先按下KEY_UP按键,将串口接收到的APP程序存放到STM32F4的FLASH,之后再按KEY2既可以执行这个FLASH APP程序。通过KEY1按键,可以手动清除串口接收到的APP程序。DS0用于指示程序运行状态。
本实验用到的资源如下:
1)& 指示灯DS0
2)& 四个按键(KEY0/KEY1/KEY2/KEY_UP)
4)& TFTLCD模块
这些用到的硬件,我们在之前都已经介绍过,这里就不再介绍了。
55.3 软件设计
本章,我们总共需要3个程序:1,Bootloader;2,FLASH APP;3)SRAM APP;其中,我们选择之前做过的RTC实验(在第二十章介绍)来做为FLASH APP程序(起始地址为0X),选择触摸屏实验(在第三十三章介绍)来做SRAM APP程序(起始地址为0X)。Bootloader则是通过TFTLCD显示实验(在第十八章介绍)修改得来。本章,关于SRAM APP和FLASH APP的生成比较简单,我们就不细说,请大家结合光盘源码,以及55.1节的介绍,自行理解。本章软件设计仅针对Bootloader程序。
复制第十八章的工程(即实验13),作为本章的工程模版(命名为:IAP Bootloader V1.0),并复制第三十九章实验(FLASH模拟EEPROM实验)的STMFLASH文件夹到本工程的HARDWARE文件夹下,打开本实验工程,并将STMFLASH文件夹内的stmflash.c加入到HARDWARE组下,同时将STMFLASH加入头文件包含路径。
在HARDWARE文件夹所在的文件夹下新建一个IAP的文件夹,并在该文件夹下新建iap.c和iap.h两个文件。然后在工程里面新建一个IAP的组,将iap.c加入到该组下面。最后,将IAP文件夹加入头文件包含路径。
打开iap.c,输入如下代码:
iapfun jump2
u32 iapbuf[512];
& //2K字节缓存&
//appxaddr:应用程序的起始地址
//appbuf:应用程序CODE.
//appsize:应用程序大小(字节).
iap_write_appbin(u32 appxaddr,u8 *appbuf,u32 appsize)
&&&&&& u32 u16 i=0; &u32
&&&&&& u32 fwaddr=//当前写入的地址
&&&&&& u8 *dfu=
&&&&&& for(t=0;t&t+=4)
&&&&&& {&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&
&&&&&&&&&&&&& temp=(u32)dfu[3]&&24;&&
&&&&&&&&&&&&& temp|=(u32)dfu[2]&&16;&&&
&&&&&&&&&&&&& temp|=(u32)dfu[1]&&8;
&&&&&&&&&&&&& temp|=(u32)dfu[0]; &
&&&&&&&&&&&&& dfu+=4;//偏移4个字节
&&&&&&&&&&&&& iapbuf[i++]=& &&&
&&&&&&&&&&&&& if(i==512)
&&&&&&&&&&&&& {&&
&&&&&&&&&&&&&&&&&&&& STMFLASH_Write(fwaddr,iapbuf,512);
&&&&&&&&&&&&&&&&&&&& fwaddr+=2048;//偏移=2048
&&&&&&&&&&&&& }
&&&&&& if(i)STMFLASH_Write(fwaddr,iapbuf,i);//将最后的一些内容字节写进去.&
//跳转到应用程序段
//appxaddr:用户代码起始地址.
iap_load_app(u32 appxaddr)
&&&&&& if(((*(vu32*)appxaddr)&0x2FFE0000)==0x)//检查栈顶地址是否合法.
&&&&&&&&&&&&& jump2app=(iapfun)*(vu32*)(appxaddr+4);&
//用户代码区第二个字为程序开始地址(复位地址)&&&&&&&&&
&&&&&&&&&&&&& MSR_MSP(*(vu32*)appxaddr);&&&&&&&&&&
//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
&&&&&&&&&&&&& jump2app();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //跳转到APP.
&&&&&& 该文件总共只有2个函数,其中,iap_write_appbin函数用于将存放在串口接收buf里面的APP程序写入到FLASH。iap_load_app函数,则用于跳转到APP程序运行,其参数appxaddr为APP程序的起始地址,程序先判断栈顶地址是否合法,在得到合法的栈顶地址后,通过MSR_MSP函数(该函数在sys.c文件)设置栈顶地址,最后通过一个虚拟的函数(jump2app)跳转到APP程序执行代码,实现IAPàAPP的跳转。
&&&&&& 保存iap.c,打开iap.h输入如下代码:
#ifndef __IAP_H__
#define __IAP_H__
#include "sys.h"&&&
void (*iapfun)(void);&&&&&&&&&&&&&&&&&&&&&&&&& //定义一个函数类型的参数.&&
#define FLASH_APP1_ADDR&&&&&&&&&&& 0x& &&&&&&
//第一个应用程序起始地址(存放在FLASH)
//保留0XX0800FFFF的空间为Bootloader使用(共64KB)& &&
void iap_load_app(u32 appxaddr);&&&&&& //跳转到APP程序执行
void iap_write_appbin(u32 appxaddr,u8 *appbuf,u32
applen);//在指定地址开始,写入bin
&&&&&& 这部分代码比较简单,保存iap.h。本章,我们是通过串口接收APP程序的,我们将usart.c和usart.h做了稍微修改,在usart.h中,我们定义USART_REC_LEN为120K字节,也就是串口最大一次可以接收120K字节的数据,这也是本Bootloader程序所能接收的最大APP程序大小。然后新增一个USART_RX_CNT的变量,用于记录接收到的文件大小,而USART_RX_STA不再使用。在usart.c里面,我们修改USART1_IRQHandler部分代码如下:
//串口1中断服务程序
//注意,读取USARTx-&SR能避免莫名其妙的错误&& &&&&
u8 USART_RX_BUF[USART_REC_LEN] __attribute__
((at(0X)));
//接收缓冲,最大USART_REC_LEN个字节,起始地址为0X.&&&
//接收状态
//bit15, 接收完成标志&& bit14,&&&& 接收到0x0d
//bit13~0,接收到的有效字节数目
u16 USART_RX_STA=0;&&&&&& &&&&&& //接收状态标记&&&& &
u32 USART_RX_CNT=0;&&&&&&&&&&&&&&&&&& //接收的字节数&&&& &
void USART1_IRQHandler(void)
#ifdef OS_CRITICAL_METHOD
//如果OS_CRITICAL_METHOD定义了,说明使用ucosII了.
&&&&&& OSIntEnter();&&&
&&&&&& if(USART_GetITStatus(USART1,
USART_IT_RXNE) != RESET)
&&&&&&&&&&&&& Res
=USART_ReceiveData(USART1);//(USART1-&DR);&& //读取接收到的数据
&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&& if(USART_RX_CNT&USART_REC_LEN)
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& USART_RX_BUF[USART_RX_CNT]=R
&&&&&&&&&&&&&&&&&&&& USART_RX_CNT++;&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&
&&&&&&&&&&&&& }&&&&
& } #ifdef
OS_CRITICAL_METHOD &&&&&&
//如果OS_CRITICAL_METHOD定义了,说明使用ucosII了.
&&&&&& OSIntExit();& &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &
&&&&&& 这里,我们指定USART_RX_BUF的地址是从0X开始,该地址也就是SRAM APP程序的起始地址!然后在USART1_IRQHandler函数里面,将串口发送过来的数据,全部接收到USART_RX_BUF,并通过USART_RX_CNT计数。代码比较简单,我们就不多说了。
改完usart.c和usart.h之后,我们在main.c修改main函数如下:
int main(void)
{&&&&&&&&&&&
u8 u8 clearflag=0;
&&&&&& u16
oldcount=0;&&&& //老的串口接收数据值
&&&&&& u32
applenth=0;&&&& //接收到的app代码长度
&&&&&& NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
&&&&&& delay_init(168);& //初始化延时函数
&&&&&& uart_init(460800);&&&&&&&& //初始化串口波特率为115200
&&&&&& LED_Init();&&&&&&&&&&&&&&&&&&&&&&&& //初始化LED
&&&&& LCD_Init();&&&&&&&&&&&&&&&&&&&&&&&& //LCD初始化&
&&&&& KEY_Init();&&&&&&&&&&&&&&&&&&&&&&&& //按键初始化
&&&&& POINT_COLOR=RED;//设置字体为红色
&&&&&& LCD_ShowString(30,50,200,16,16,"Explorer
STM32F4");&&&&&&
&&&&&& LCD_ShowString(30,70,200,16,16,"IAP
TEST");&&&&&
&&&&&& LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
&&&&&& LCD_ShowString(30,110,200,16,16,"");&
&&&&&& LCD_ShowString(30,130,200,16,16,"KEY_UP:Copy
APP2FLASH");
&&&&&& LCD_ShowString(30,150,200,16,16,"KEY1:Erase
SRAM APP");
&&&&&& LCD_ShowString(30,170,200,16,16,"KEY0:Run
SRAM APP");
&&&&&& LCD_ShowString(30,190,200,16,16,"KEY2:Run
FLASH APP");
&&&&&& POINT_COLOR=BLUE;
&&&&&& //显示提示信息
&&&&&& POINT_COLOR=BLUE;//设置字体为蓝色 &
&&&&&& while(1)
&&&&&& &&&&& if(USART_RX_CNT)
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& if(oldcount==USART_RX_CNT)//新周期内,没收到数据,认为本次接收完成.
&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&& applenth=USART_RX_CNT;
&&&&&&&&&&&&&&&&&&&&&&&&&&& oldcount=0;
&&&&&&&&&&&&&&&&&&&&&&&&&&& USART_RX_CNT=0;
&&&&&&&&&&&&&&&&&&&&&&&&&&& printf("用户程序接收完成!\r\n");
&&&&&&&&&&&&&&&&&&&&&&&&&&& printf("代码长度:%dBytes\r\n",applenth);
&&&&&&&&&&&&&&&&&&&& }else
oldcount=USART_RX_CNT;&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&& }
&&&&&&&&&&&&& t++;
&&&&&&&&&&&&& delay_ms(10);
&&&&&&&&&&&&& if(t==30)
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& LED0=!LED0;& t=0;
&&&&&&&&&&&&&&&&&&&& if(clearflag)
&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&& clearflag--;
&&&&&&&&&&&&&&&&&&&&&&&&&&& if(clearflag==0)LCD_Fill(30,210,240,210+16,WHITE);//清除显示
&&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&& }&&&& & &&& &
&&&&&&&&&&&&& key=KEY_Scan(0);
&&&&&&&&&&&&& if(key==WKUP_PRES) //WK_UP按键按下
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& if(applenth)
&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&& printf("开始更新固件...\r\n");&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&& LCD_ShowString(30,210,200,16,16,"Copying
APP2FLASH...");
&&&&&&&&&&&&&&&&&&&&&&&&&& if(((*(vu32*)(0X))&0xFF000000)==0x)
//判断是否为0X08XXXXXX.
&&&&&&&&&&&&&&&&&&&&&&&&&&& {&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& iap_write_appbin(FLASH_APP1_ADDR,USART_RX_BUF,applenth);
//更新FLASH代码&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& LCD_ShowString(30,210,200,16,16,"Copy
APP Successed!!");
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& printf("固件更新完成!\r\n");&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&& }else
&&&&&&&&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& LCD_ShowString(30,210,200,16,16,"Illegal
FLASH APP!& ");&&&&&& &&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& printf("非FLASH应用程序!\r\n");
&&&&&&&&&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&&&&&& }else
&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&& printf("没有可以更新的固件!\r\n");
&&&&&&&&&&&&&&&&&&&&&&&&&&& LCD_ShowString(30,210,200,16,16,"No
&&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&&&&&&& clearflag=7;//标志更新了显示,并且设置7*300ms后清除显示&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&& }
&&&&&&&&&&&&& if(key==KEY1_PRES)& //KEY1按下
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& if(applenth)
&&&&&&&&&&&&&&&&&&&& {&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&& printf("固件清除完成!\r\n");&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&& LCD_ShowString(30,210,200,16,16,"APP
Erase Successed!");
&&&&&&&&&&&&&&&&&&&&&&&&&&& applenth=0;
&&&&&&&&&&&&&&&&&&&& }else
&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&& printf("没有可以清除的固件!\r\n");
&&&&&&&&&&&&&&&&&&&&&&&&&&& LCD_ShowString(30,210,200,16,16,"No
&&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&&&&&&& clearflag=7;//标志更新了显示,并且设置7*300ms后清除显示&&&&&&&&&&&&&&
&&&&&&&&&&&&& }
&&&&&&&&&&&&& if(key==KEY2_PRES)& //KEY2按下
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& printf("开始执行FLASH用户代码!!\r\n");
&&&&&&&&&&&&&&&&&&&& if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x)
//判断是否为0X08XXXXXX.
&&&&&&&&&&&&&&&&&&&& {&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&& iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码
&&&&&&&&&&&&&&&&&&&& }else
&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&& printf("非FLASH应用程序,无法执行!\r\n");
&&&&&&&&&&&&&&&&&&&&&&&&&&& LCD_ShowString(30,210,200,16,16,"Illegal
FLASH APP!");&&& &&
&&&&&&&&&&&&&&&&&&&& }&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&& clearflag=7;//标志更新了显示,并且设置7*300ms后清除显示 &
&&&&&&&&&&&&& }
&&&&&&&&&&&&& if(key==KEY0_PRES)& //KEY0按下
&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& printf("开始执行SRAM用户代码!!\r\n");
&&&&&&&&&&&&&&&&&&&& if(((*(vu32*)(0X))&0xFF000000)==0x)
//判断是否为0X20XXXXXX.
&&&&&&&&&&&&&&&&&&&& {&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&& iap_load_app(0X);//SRAM地址
&&&&&&&&&&&&&&&&&&&& }else
&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&&&&&&&&& printf("非SRAM应用程序,无法执行!\r\n");
&&&&&&&&&&&&&&&&&&&&&&&&&&& LCD_ShowString(30,210,200,16,16,"Illegal
SRAM APP!");&&&& &&
&&&&&&&&&&&&&&&&&&&& }&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&& clearflag=7;//标志更新了显示,并且设置7*300ms后清除显示
&&&&&&&&&&&&& }&&&&
&&&&&& 该段代码,实现了串口数据处理,以及IAP更新和跳转等各项操作。Bootloader程序就设计完成了,但是一般要求bootloader程序越小越好(给APP省空间嘛),实际应用时,可以尽量精简代码来得到最小的IAP。本章例程我们仅作演示用,所以不对代码做任何精简,最后得到工程截图如图55.3.1所示:
d52fec22f8f9c9a.jpg (0 Bytes, 下载次数: 0)
22:54 上传
图55.3.1 Bootloader 工程截图
&&&&&& 从上图可以看出,Bootloader大小为36K左右,比较大,主要原因是液晶驱动和printf占用了比较多的flash,如果大家想删减代码,可以去掉不用的LCD部分代码和printf等,不过我们在本章为了演示效果,所以保留了这些代码。至此,本实验的软件设计部分结束。
&&&&&& FLASH APP和SRAM APP两部分代码,根据55.1节的介绍,大家自行修改都比较简单,我们这里就不介绍了,不过要提醒大家:FLASH APP的起始地址必须是0X,而SRAM APP的起始地址必须是0X。
55.4 下载验证
在代码编译成功之后,我们下载代码到ALIENTEK探索者STM32F4开发板上,得到,如图55.4.1所示:
2a82f82effb622fa3d20_715.jpg (0 Bytes, 下载次数: 0)
22:54 上传
图55.4.1 IAP程序界面
此时,我们可以通过串口,发送FLASH APP或者SRAM APP到探索者STM32F4开发板,如图55.4.2所示:
0dc31db8b9ce11c99d992a_479.jpg (0 Bytes, 下载次数: 0)
22:54 上传
图55.4.2 串口发送APP程序界面
&&&&&& 首先找到开发板USB转串口的串口号,打开串口(我电脑是COM3),然后设置波特率为460800(图中标号1所示),然后,点击打开文件按钮(如图标号2所示),找到APP程序生成的.bin文件(注意:文件类型得选择所有文件!!默认是只打开txt文件的),最后点击发送文件(图中标号3所示),将.bin文件发送给探索者STM32F4开发板,发送完成后,XCOM会提示文件发送完毕。
开发板在收到APP程序之后,我们就可以通过KEY0/KEY2运行这个APP程序了(如果是FLASH APP,则先需要通过KEY_UP将其存入对应FLASH区域)。&&&&&
实验详细手册和源码下载地址:
正点原子探索者STM32F407开发板购买地址:
14:17 上传
点击文件名下载附件
849.92 KB, 下载次数: 743
14:17 上传
点击文件名下载附件
1.66 MB, 下载次数: 1006
我是开源电子网?网站管理员,对网站有任何问题,请与我联系!
主题帖子精华
新手上路, 积分 34, 距离下一级还需 16 积分
在线时间0 小时
你好,我想问个问题,代码中&&
temp=(u32)dfu[3]&&24;&&&
&temp|=(u32)dfu[2]&&16;&&&&
temp|=(u32)dfu[1]&&8;&
temp|=(u32)dfu[0];
为什么不是&&&
temp=(u32)dfu[0]&&24;&&&
&temp|=(u32)dfu[1]&&16;&&&&
temp|=(u32)dfu[2]&&8;&
temp|=(u32)dfu[3];
这是设置产生bin文件的参数设置决定的吗?
谢谢
主题帖子精华
新手上路, 积分 34, 距离下一级还需 16 积分
在线时间0 小时
理论上生成的bin文件顺序写入Flash就可以了,你的代码相当于对接收的bin文件的每四个字节做了顺序颠倒?
主题帖子精华
初级会员, 积分 138, 距离下一级还需 62 积分
在线时间15 小时
原子哥,我有一个问题,你的文章中有“也就是串口最大一次可以接收120K字节的数据,这也是本Bootloader程序所能接收的最大APP程序大小。”这么一句话,那如果我的代码大于120K字节该怎么办呢,我仔细看了一下,应该是USART_REC_LEN就可以了,但是USART接收的数据是放在SRAM中的,f407的sRAM好像只有256KB,那如果我的代码有700KB,该怎么处理呢,现在项目遇到了这样的问题,请原子哥指点一二~
主题帖子精华
初级会员, 积分 104, 距离下一级还需 96 积分
在线时间8 小时
想请问一下,怎么操作从中断函数跳转到主函数任意指定地址并能依次执行下一条指令,请各位高人指点明津。谢谢
固步自封于FLASH,只能机械性的运作,人应像翱翔天际的雄鹰,装载高速变化的CPU及强大的存储能力,摆脱老旧的结构束缚,翱翔在智能化信息的海洋。
主题帖子精华
在线时间254 小时
回复【4楼】阿拓:
---------------------------------
写协议,传输一点,写一点。
我的淘宝小店:
主题帖子精华
初级会员, 积分 55, 距离下一级还需 145 积分
在线时间5 小时
原子哥,我想问一下,在Bootloader接收到APP的bin文件,写入并跳转到APP执行之后,在Bootloader程序中定义的一些占用SRAM的接收数组和一些变量,它们占用的SRAM是不是又被释放了,APP程序也可以使用这些SRAM了呢?
主题帖子精华
在线时间254 小时
回复【7楼】aa40111:
---------------------------------
是的,全部释放了.
我的淘宝小店:
主题帖子精华
初级会员, 积分 55, 距离下一级还需 145 积分
在线时间5 小时
回复【8楼】正点原子:
---------------------------------
感谢原子哥回答,我还想问一下,是因为在APP程序运行之前,也有一段汇编的引导程序(startup_stm32f10x_md.s),这个汇编程序里面释放的SRAM吗?汇编程序完全看不懂呀。。
主题帖子精华
在线时间254 小时
回复【9楼】aa40111:
---------------------------------
不存在释放问题,是相当于你单片机重新下了个代码。。。。
我的淘宝小店:
主题帖子精华
初级会员, 积分 55, 距离下一级还需 145 积分
在线时间5 小时
回复【10楼】正点原子:
---------------------------------
那我这样理解对不对呢?写的APP程序,在编译的时候,已经确定好他的变量所分配在SRAM中的地址了,所以在跳转到APP程序后,APP可以直接利用以前的SRAM,也就是即使以前SRAM中存有bootloader的数据,也直接被app的变量覆盖保存了。
主题帖子精华
在线时间254 小时
回复【11楼】aa40111:
---------------------------------
相当于运行一个新代码,但是没有复位mcu
我的淘宝小店:
主题帖子精华
初级会员, 积分 55, 距离下一级还需 145 积分
在线时间5 小时
回复【12楼】正点原子:
---------------------------------
感谢原子哥解答
主题帖子精华
初级会员, 积分 50, 距离下一级还需 150 积分
在线时间3 小时
原子哥,求救啊!!!我用的战舰系列开发板 stm32f407系列,最近在做IAP,但是出现一个问题,自带的例程bin文件能够通过IAP下进去成功运行,但是例程一点不改动,只是修改一下生成BIN文件的路径,然后从新编译一下,重新生成bin文件后,这个新生成的bin文件能够下载,但是不能正常运行了,这是为什么呢?另外,我对比了一下新生成的bin和例程自带的bin文件,他们的前几行(应该是中断向量那一块)是不一样的,这是为什么呢?
主题帖子精华
在线时间254 小时
回复【14楼】感知新生:
---------------------------------
说明你改了一些不该改的地方.
我的淘宝小店:
主题帖子精华
初级会员, 积分 50, 距离下一级还需 150 积分
在线时间3 小时
回复【15楼】正点原子:
---------------------------------
这是例程里面的User&&&&D:\tools\MDK5\ARM\ARMCC\bin\fromelf.exe&--bin&-o&&..\OBJ\RTC.bin&..\OBJ\RTC.axf
我就改了一下文件安装路径:C:\Keil_v5\ARM\ARMCC\bin\fromelf.exe&--bin&-o&&..\OBJ\RTC.bin&..\OBJ\RTC.axf
然后生成的BIN文件就悲催了,文件中断向量表和文件存储地址也都没动,完全按照例程原封不动啊,这是什么问题呢?
主题帖子精华
初级会员, 积分 50, 距离下一级还需 150 积分
在线时间3 小时
回复【15楼】正点原子:
---------------------------------
终于找到原因了,我用的是摄像头实验,由于实验板上没有摄像头,所以显示屏上显示的还是Bootloader&的图像,但是实际上程序已经运行了,只是在显示屏上看不到执行效果!
主题帖子精华
初级会员, 积分 59, 距离下一级还需 141 积分
在线时间7 小时
赞一个,写的非常详细,准备接下来自己试一试
主题帖子精华
新手上路, 积分 25, 距离下一级还需 25 积分
在线时间6 小时
主题帖子精华
初级会员, 积分 59, 距离下一级还需 141 积分
在线时间7 小时
已经调试成功,加了xmodem协议传输比较可靠!
主题帖子精华
初级会员, 积分 59, 距离下一级还需 141 积分
在线时间7 小时
回复【4楼】阿拓:
---------------------------------
写协议,传输一点,写一点。
原子哥,我有个问题,如果我的的app程序已经跑起来了,在app程序运行的过程中进行升级的话,是不是要在flash中划分两个app的区域了?一个是正在运行的(不能破坏掉),另一个是要被更新的new_app区域。
主题帖子精华
新手上路, 积分 13, 距离下一级还需 37 积分
在线时间1 小时
疑问1: & &&&原子哥,关于中断向量表的重新映射这一块有点疑问。理论上bootload的启动文件和APP的启动文件是一样的,如果不进行映射,产生中断后,直接跳转到bootload 的中断向量表,也是一样可以执行的。这里映射是不是可以省略掉?
疑问2: & &对于cortex内核的MCU,可以通过CB-&VTOR = SRAM_BASE | VECT_TAB_OFFSET;进行映射,但是之前调试过LPC的ARM7,好像没有这重映射的寄存器进行设置。
主题帖子精华
中级会员, 积分 247, 距离下一级还需 253 积分
在线时间9 小时
回复【14楼】感知新生:
---------------------------------
说明你改了一些不该改的地方.
原子哥,理论上STM8也支持IAP吧?
Powered by

我要回帖

更多关于 正点原子stm32开发板 的文章

 

随机推荐