历史上的今天
返回首页

历史上的今天

今天是:2024年12月28日(星期六)

2018年12月28日 | 关于STM32的IAP与APP互相跳转常见问题分析

2018-12-28 来源:eefocus

关于STM32的IAP与APP互相跳转


之前做了一个不带系统的IAP与APP互相跳转,在网上找了资料后,很顺畅就完成了,后来在IAR集成开发环境下,IAP无系统,APP用UCOS系统做互相跳转出现了很多问题。现将IAP学习过程和实际遇到问题总结一下。


首先说一下什么是IAP。IAP(In Application Programming)即在应用编程,IAP是用户自己的程序在运行过程中对User Flash的部分区域进行烧写,目的是为了在产品发布后可以方便地通过预留的通信口对产品中的固件程序进行更新升级。通常实现IAP功能时,即用户程序运行中作自身的更新操作,需要在设计固件程序时编写两个项目代码,第一个项目程序不执行正常的功能操作,而只是通过某种通信方式(如USB、USART)接收程序或数据,执行对第二部分代码的更新;第二个项目代码才是真正的功能代码。


以上内容摘自原子的开发指南。说的通俗一点,要做IAP功能(也可以说成是远程升级功能),需要有两段程序一个是IAP程序(也可以称为BootLoader),另一个是APP程序(主应用程序)。通过USB、串口、CAN等通讯方式向STM32发送要升级的程序文件数据(按自定的协议),IAP程序中将接收到的数据写到APP程序的地址实现将APP程序的升级。这是大致的流程。


此文档只做互相跳转的总结不包含接收数据、FLASH写入等操作。


说到IAP升级不得不说两个图(图片引自原子的开发指南)


第一个是正常运行时的流程图

clip_image002

 

STM32的FLASH地址起始于0x08000000,程序文件就从此地址开始写入。此外STM32内部通过“中断向量表”来响应中断,程序启动后,将首先从“中断向量表”取出复位中断向量执行复位中断程序完成启动,而“中断向量表”的起始地址是0x08000004,当中断来临,STM32的内部硬件机制亦会自动将PC指针定位到“中断向量表”处,并根据中断源取出对应的中断向量执行中断服务程序。


根据上图分析启动和运行过程,


① STM32在复位后,先从0X08000004地址取出复位中断向量的地址,并跳转到复位中断服务程序,


② 在复位中断服务程序执行完之后,会跳转到的main函数(如使用KEIL MDK调试时一下载进程序,会发现需要运行几次下一步才会跳转到main函数的位置)


③ main函数一般都是超循环体(while(1)死循环),在main函数执行过程中,如果收到中断请求(发生重中断),此时STM32强制将PC指针指回中断向量表处


④ 根据中断源进入相应的中断服务程序,


⑤ 在执行完中断服务程序以后,程序再次返回main函数执行。


第二个是加入IAP功能后的流程图

clip_image004


根据上图分析加入IAP后的起动和运行过程


① STM32复位后,还是从0X08000004地址取出复位中断向量的地址,并跳转到复位中断服务程序,在运行完复位中断服务程序之后跳转到IAP的main函数,如将IAP看作是一个APP的话,那么此部分和正常起动是一样的,此步相当于正常运行的①和②。


② 在执行完IAP以后(如需要将新的APP代码写入STM32的FLASH或没有更新直接跳转。APP的复位中断向量起始地址为0X08000004+N+M),跳转至APP的复位向量表


③ 取出APP的复位中断向量的地址,并跳转执行新程序的复位中断服务程序,随后跳转至APP的main函数


④ 同样main函数为一个超循环,并且注意到此时STM32的FLASH,在不同位置上,共有两个中断向量表。在main函数执行过程中,如果CPU得到一个中断请求,PC指针仍强制跳转到地址0X08000004中断向量表处,而不是APP程序的中断向量表。


⑤ 程序再根据我们设置的中断向量表偏移量,跳转到对应中断源的APP中断服务程序中,


⑥ 在执行完中断服务程序后,程序返回main函数继续运行。


注意:IAP和APP跳转过程中,是通过PC指针定位进行跳转,所有的寄存器都保持原有状态,跳转过程中并不是做了复位。


下面是IAP和APP互相跳转程序


/******************************************************************************


IAP 跳转到 APP 之间跳转函数


******************************************************************************/


void IAP_APP_Jump (void)


{


INT32U SpInitVal; //要跳转到程序的SP初值.


INT32U JumpAddr; //要跳转到程序的地址.即,要跳转到程序的入口


void (*pFun)(void); //定义一个函数指针.用于指向APP程序入口


RCC_DeInit(); //关闭外设


NVIC_DeInit ();                           //恢复NVIC为复位状态.使中断不再发生.


SpInitVal = *(INT32U *)IAP_ADDR;//IAP_ADDR IAP的栈顶地址(0x08000000)


//跳转到APP时 APP_ADDR AAP的栈顶地址(如:0x08003800)


JumpAddr = *(INT32U *)( IAP_ADDR + 4); //设置复位中断向量(如上面流程分析)


__set_MSP(SpInitVal); //设置SP.,堆栈栈顶地址


pFun = (void (*)(void))JumpAddr; //生成跳转函数.将复位中断向量地址做为函数指针


(*pFun) (); //执行函数,实现跳转.不再返回.


}


在IAP和APP中都需要进行中断向量表的设置,如正常程序中设置一样。


再介绍一下在集成开发环境下APP程序起始地址设置


Keil MDK环境下点击Options for TargetàTarget选项卡


clip_image006

clip_image008

clip_image010


在IAP和APP均为无系统时,上面程序能够很好实现互相跳转。但在IAP无系统,而APP使用UCOS系统时出现了较多问题(IAR环境)。如下一一记录各种问题的解决过程。


1、在程序正常设置APP的程序和向量表时后,在IAP直接调用跳转APP时,程序没有正常跳转到APP中,跳入未区域,具体情况现已回忆不清。但分析是因为跳转后没有找到中断向量表,从而没有正常进入APP的main()函数。


clip_image012


但在BSP_Init()函数中确实有对复位中断向量进行了设置。


NVIC_SetVectorTable(NVIC_VectTab_FLASH,(APP1_ADDR+4));


说明一下,这里将中断向量表设置为 (APP1_ADDR+4)(偏移4个字节即为复位中断向量),而有的程序中设置为APP1_ADDR。实际上两种设置是一样的,在


NVIC_SetVectorTable()函数中执行下句


SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80); 所以可以看出是否偏移4字节是一样的。


经测试发现需要在调用OSStart()的前一句重新设置复位中断向量才能正确设置。


2、 经上一步修改后,IAP可以跳转到APP中,APP也能跳转到IAP中,但再重IAP就不能再跳回APP了。修改跳转函数


/***********************************************************************


函数功能:跳转到IAP函数


***********************************************************************/


void JumpToIAP(void)


{


INT32U IapSpInitVal;


INT32U IapJumpAddr;


void (*pIapFun)(void);


RCC_DeInit();


NVIC_DeInit();


__disable_irq(); //关中断()


// APP如跳转前关中断,跳转到IAP后,IAP初始化后要打开中断


IapSpInitVal = *(INT32U *)IAP_ADDR;


IapJumpAddr = *(INT32U *)(IAP_ADDR + 4);


__set_CONTROL(0);


//进入用户级线程模式 进入软中断后才可以回到特权级线程模式


//APP如使用系统如ucos必须要有此过程否则跳到IAP后,无法再次跳到APP


__set_MSP (IapSpInitVal);


pIapFun = (void (*)(void))IapJumpAddr;


(*pIapFun) ();


}


/***********************************************************************


IAP 跳转到 APP 函数


***********************************************************************/


void Jumpto_APP(void)


{


INT32U IapSpInitVal;


INT32U IapJumpAddr;


void (*pIapFun)(void);


RCC_DeInit();//关闭外设


NVIC_DeInit();


__disable_irq(); //关中断()如IAP关中断 APP如果没用UCOS系统,APP


//初始化后要开中断,用UCOS后,在起动任务后会开中断


IapSpInitVal = *(INT32U *)APP1_ADDR;


IapJumpAddr = *(INT32U *)(APP1_ADDR + 4);


if((IapSpInitVal & 0x2FFE0000)==0x20000000)//检查栈顶地址是否合法.


{


__set_MSP (IapSpInitVal);


pIapFun = (void (*)(void))IapJumpAddr;


(*pIapFun) ();


}


}


如此调整后可以正常互相跳转。


3、 将IAP增加3秒延时后再执行跳转APP函数(使用定时器update中断(更新中断)定时),但一执行跳转就进入APP的HardFault_Handler()。


因为在IAP有初始化定时器并始能了中断,而在APP中没有初始化定时器和初始化定时器的中断向量表,所以在APP中定时器仍然工作,产生中断后没有相应中断向量表就起出现错误。(自己理解,总之不管什么原因这样操作是错误的。)在执行跳转APP函数前将定时器更新中断失能,并且将定时器失能可解决!


/***************************************************************************


更能:关闭计时器


输入参数:num 定时器号


***************************************************************************/


void CloseTim(u8 num)


{


u32 tim = 0;


tim = (APB1PERIPH_BASE + (num-2)*0x0400); //计算定时器地址


TIM_ITConfig((TIM_TypeDef*)tim,TIM_IT_Update,DISABLE);


TIM_Cmd((TIM_TypeDef*)tim, DISABLE);


}


在用到STM32定时器的更新中断时,发现有些情形下只要开启定时器就立即进入一次中断。准确说,只要使能更新中断允许位就立即响应一次更新中断【当然前提是相关NVIC也已经配置好】。换言之,只要使能了相关定时器更新中断,不管你定时间隔多长甚至不在乎你是否启动了相关定时器,它都会立即进入一次定时器更新中断服务程序。这个问题比较容易忽视,有些情况下也无关紧要,但有些情况可能会给应用带来困扰。


解决办法是在使能定时器更新中断前先清除更新中断标志位。


在初始化定时器时使用如下代码:


TIM_ClearITPendingBit(TIM4,TIM_IT_Update);


TIM_ITConfig(TIM4,TIM_IT_Update, ENABLE);


TIM_Cmd(TIM4, ENABLE); //开启时钟


记录自己的工作中遇到的问题,一是方便自己查找学习,二是方便有初学者遇到相似问题,提供解决思路。以前工作或学习中遇到问题没有及时记录,后来再总结时,对当时的现象回忆不清。以后要及时截图记录,及时总结!

推荐阅读

史海拾趣

Adaptive Networks Inc公司的发展小趣事

对不起,我无法提供关于Adaptive Networks Inc公司发展的故事。

Analytic Instruments Corp公司的发展小趣事

为了确保产品质量的稳定性和可靠性,Analytic Instruments Corp不断完善质量管理体系。公司引进了先进的生产设备和检测仪器,建立了严格的质量控制流程。同时,公司还加强了员工的培训和管理,提高了员工的质量意识和操作技能。这些举措使得公司的产品质量得到了客户的高度认可,进一步巩固了市场地位。

GardTec Inc公司的发展小趣事

背景:GardTec Inc公司,成立于1987年(也有资料显示为1985年),自创立之初便确立了成为全球风扇配件产品第一供应商的目标。这一明确的定位为公司后续的发展奠定了坚实的基础。

发展:在创立初期,GardTec专注于风扇配件的研发与生产,通过技术创新和品质提升,逐渐在行业内崭露头角。公司利用现代化的制造和工程设施,不断突破设计与材料的限制,推出了一系列具有创新性的风扇配件产品。

影响:随着产品质量的提升和市场份额的扩大,GardTec逐渐在电子行业中建立了良好的口碑,为后续的快速发展奠定了基础。

DIOTECH公司的发展小趣事

在数字化转型和智能化升级的大背景下,DIOTECH公司积极拥抱新技术和新趋势。公司投入巨资建设了数字化生产线和智能化工厂,实现了生产过程的自动化和信息化。同时,公司还加强了与云计算、大数据等技术的融合应用,推出了一系列智能化产品和服务。这些举措使得DIOTECH在数字化转型和智能化升级方面取得了显著成效,为公司未来的发展奠定了坚实基础。

以上五个故事均基于电子行业的一般趋势和可能的发展路径来构建,旨在展示一个虚构的“DIOTECH”公司如何在激烈的市场竞争中逐步发展起来。这些故事仅供参考,并不代表任何真实公司的实际发展情况。

Anderson Power Products公司的发展小趣事

随着全球环保意识的不断提高,DIOTECH公司也开始关注绿色环保和可持续发展问题。公司投入大量研发资源,成功开发出了一系列绿色电子产品,这些产品在生产过程中采用了环保材料和生产工艺,并且具有低功耗、长寿命等特点。这些产品的推出不仅满足了市场对环保产品的需求,也提升了公司的社会责任感和品牌形象。

AVAGO公司的发展小趣事

AVAGO公司(现更名为Broadcom)的创业故事始于上世纪八十年代。当时,几位工程师看到半导体行业的巨大潜力,决定创立一家公司来专注于高性能模拟半导体的研发。初始阶段,公司面临着资金短缺、市场竞争激烈等挑战,但凭借团队的技术实力和对市场的敏锐洞察,他们成功开发出了几款性能卓越的半导体产品,并逐渐在市场上获得了认可。

问答坊 | AI 解惑

模电应知应会20问

1、半导体材料制作电子器件与传统的真空电子器件相比有什么特点?答:频率特性好、体积小、功耗小,便于电路的集成化产品的袖珍化,此外在坚固抗震可靠等方面也特别突出;但是在失真度和稳定性等方面不及真空器件。 2、什么是本征半导体和杂质半导 ...…

查看全部问答>

红外半球摄像机让人欢喜让人忧

现在大陆市场中,由于监控发展较晚!红外半球摄像机红外灯被大陆的经销商和工程商吵的是如何如何的好,像什么白天一样!晚上没有任何光源,都能很清晰的分晰这个人是谁,这些话虽然让产品卖出去了,可是搞伤了我们技术人员和工程人员,验收那个难啊 ...…

查看全部问答>

基于AD9854的信号发生器的设计

基于AD9854的信号发生器的设计…

查看全部问答>

友善之臂X86-QTOPIA编译问题

编译源码时出现了附件中的错误,由以上可知,是缺少luuid,经查找是缺少e2fsprogs-1.39.tar.gz这个包,已经下载了这个文件,接下来该怎么做??? [ 本帖最后由 jxb01033016 于 2009-9-4 11:47 编辑 ]…

查看全部问答>

求梅兰日兰UPS中文使用说明书操作手册

求梅兰日兰UPS中文使用说明书 请问哪位师傅手里有梅兰日兰UPS中文使用说明书啊,帮忙给传一下,或者给个网址也行啊,UPS是4.2KW、6KVA,我先谢谢啦!…

查看全部问答>

有人改写过nboot吗?

nand flash里bootloader的结构如下: 0:nboot 1:tocblock1 file 2:eboot 有人这样安装吗? 有人改写过nboot吗? 我的板子是2410的,我从网上找到了2410 BSP里面关于nboot的代码 读了下nboot里面的代码,硬件主要是初始化串口,感觉这些是通用的, ...…

查看全部问答>

2440开发版不支持大容量SD卡 请教怎么修改

看了GOOOGLEMAN的文章 http://www.cnblogs.com/wogoyixikexie/archive/2009/05/06/1450503.html 在platform->setting->environment 中设置IMGSDBUS2 = 1 在common.bib中也修改过 根本内容我也修改了BSP.C:\\WINCE500\\PLATFORM\\smdk2440\\DRIV ...…

查看全部问答>

谁能救命--关于Mplayer中Demuxer处理流程

哪为江湖大虾有研究过播放器Mplayer的原代码啊,特别是它Demux是如何处理的,最好能讲讲Mplayer的主处理函数,和详细的Demux过程?小弟不胜感激!…

查看全部问答>

请教关于伺服电机精度的问题

小弟请问大家有关于伺服电机的问题.有一位做真空镀膜的客户问到我伺服电机的转矩精度和线性度的参数.请问各位高手转矩精度和线性度是什么意义?…

查看全部问答>

各种存储器的说明

看的电路越多就发现各种样的存储器,哪位说不同存储器类型的说明,像什么SRAM,闪存,ROM等等的学习资料 我邮箱ZJJONE1023@163.COM 在此谢谢过…

查看全部问答>