1、函数原型:
void Jump_Address(void)
{
if (((*(volatile u32*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
{
test = (*(volatile u32*)ApplicationAddress);
JumpAddress = *(volatile u32*) (ApplicationAddress + 4);
Jump_To_Application = (pFunction) JumpAddress;
__set_MSP(*(volatile u32*) ApplicationAddress);
Jump_To_Application();
}
}
2、if (((*(volatile u32*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)分析:
ApplicationAddress存放的是用户程序Flash的首地址,(*(volatile u32*)ApplicationAddress)的意思是取用户程序首地址里面的数据,这个数据就是用户代码的堆栈地址,堆栈地址指向RAM,而RAM的起始地址是0x20000000,因此上面的判断语句执行:判断用户代码的堆栈地址是否落在:0x20000000~0x2001ffff区间中,这个区间的大小为128K,笔者查阅STM32各型号的RAM大小,目前RAM最大的容量可以做到192K+4K,时钟频率为168MHZ。一般情况下,我们使用的芯片较多的落在<128K RAM的区间,因此上面的判断语句是没有太大问题的。
3、经过2的分析,test保存的就是堆栈地址(并且是应用程序堆栈的栈顶地址),查看STM32的向量表,可以知道:栈顶地址的地址 + 4 存放的是复位地址,因此JumpAddress存放的是复位地址。
4、调用__set_MSP函数后,将把用户代码的栈顶地址设为栈顶指针
5、Jump_To_Application();的意思就是设置PC指针为复位地址。
CORTEX-M3上电后后检测BOOT引脚的电平来决定PC的位置。例:BOOT设置为FLASH启动,启动后CPU会先取两个地址:一个是栈顶地址,另一个是复位地址。因此才有了第4、第5点的写法。
关键字:STM32 boot跳转到 APP
引用地址:
STM32 boot跳转到APP的Jump_Address()分析
推荐阅读最新更新时间:2024-03-16 15:38
曝iOS 11或将强制采用64位APP
iOS 10.3还没开推,iOS 11的消息就来了,而且还可能令你吃惊。下面就随嵌入式小编一起来了解一下相关内容吧。 一直以来,iOS就以丰富海量、高质量的应用资源力压Android。但最新消息称,iOS 11可能有18.7万个APP惨遭抛弃,这意味着苹果庞大的应用资源将少了一大块。 据美国网站Apple Insider称,新版iOS将会删除所有支持32位处理器的应用程序,很大原因在于苹果需要普及64位应用。我们知道,苹果推出的全球首款64位移动处理器A7距今已经将近4年,但目前绝大部分的iOS应用都是采用32位开发,这样的话,势必会造成一个问题:可以使用,但无法物尽其用。 曝iOS 11或将强制采用64位APP 打个
[嵌入式]
stm32局部变量过大,导致栈溢出
在做一个以stm32为主控的项目时发现自己程序中一个机构体里面的数据总是一运行就被改变,刚开始以为是自己不小心在哪个地方用了extern扩展了变量的作用域,重新赋了值, 自己忘记了,后来查找了好久都没有其他地方使用这个结构体变量,于是开始单步调试,结果进入一个函数的时候(里面定义了一个200个数据float型的数组),发现只要定了一个这个数组,这时前文提到的那个结构的值就发生改变,通过在keil软件中的Memory窗口查看结构体的变量可以清楚看到结构体的地址里面的数据在这个时候发生改变, 然后修改,这个局部变量数组的大小,把它改小之后,就没有发生问题。因为局部变量是储存在栈中的,于是猜想,这种问题应该是stm32的栈的内存的溢出造
[单片机]
基于STM32的四种波形发生器设计
(1) 可以实现四种波形:正弦波、方波、三角波、锯齿波; (2) 通过按键进行选择,频率可以调整; (3) LCD液晶显示; (4)设计出来之后用Proteus软件仿真出效果; 主要硬件设备:STM32F103单片机、DAC0832数模转换芯片、矩阵键盘、LCD12864液晶屏幕。 效果图 正弦波 方波 三角波 锯齿波 单片机源程序如下: #include stm32f10x.h #include sys.h #include delay.h #include 12864.h #include key4_4.h #include timer.h //LYF #define KE
[单片机]
STM32开发中常用库函数
1.GPIO初始化函数 用法: voidGPIO_Configuration(void) { GPIO_InitTypeDefGPIO_InitStructure;//GPIO状态恢复默认参数 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_标号|GPIO_Pin_标号; //管脚位置定义,标号可以是NONE、ALL、0至15。 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//最高输出速度为50MHz GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出 GPIO_
[单片机]
关于STM32串口接收中断中只能接收一个字节
最近调试STM32的串口接收时发现例程中只能接收一个字节 例程如下: 1 //初始化串口1 2 void uart_init(u32 bound){ 3 //GPIO端口设置 4 GPIO_InitTypeDef GPIO_InitStructure; 5 USART_InitTypeDef USART_InitStructure; 6 NVIC_InitTypeDef NVIC_InitStructure; 7 8 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USA
[单片机]
STM32笔记---DMA(USART)的演示
这里有个小小的例子,来演示DMA模块与系统程序并行工作。 用串口以低波特率发送一个10K的数据,花费近10s时间,此时按照以往方法,CPU要不断等待数据发送、送数据;或者送数据、进中断、送数据,处理起来比较消耗时间。 使用了DMA功能以后,用户程序中只需配置好DMA,开启传输后,再也不需要操心,10K数据完成后会有标志位或中断产生,期间可以做任何想做的事,非常方便。 这个是相应的代码例子,基于STM32F103VBT6 /****************************************************************************** * 本文件实现串口发送功能(通过重构
[单片机]
STM32常用通信——USART,IIC,SPI,CAN
STM32常用通信 CAN通信 CAN根据两根线上电位差来判断总线电平,总线电平分为显性电平和隐形电平,两者必居其一,发送方通过控制总线电平发送信息给接收方。 显性电平对应逻辑0,两根线压差2.5V左右,隐形电平对应逻辑1,压差为0。总线上可以挂很多单元,显性电平具有优先权,一个单元显性电平,则总线为显性。CAN总线起止断有120R的电阻,用于做阻抗匹配,减少回波反射。 CAN的位时序: 同步段SS SS 传播时间段PTS 相位缓冲段1 PBS1 BS1 相位缓冲段2 PBS2 BS2 1位分为四段,每段由若干Tq组成, 波特率=1/(Tq+TBS1+TBS2) TBS1=Tq*(TS1 +1) TBS2=T
[单片机]
STM32如何收发float类型数据?
在之前文章里提到了共用体用来传输浮点数的用法,但那篇笔记中没有详细介绍,这篇笔记我们一起来看一看具体实例。 实际应用中,我们可能需要两个设备通过串口传输浮点数据: 本篇笔记为了方便演示,使用串口助手模拟其中一个设备,本篇笔记内容如下: 我们创建一个用于管理float类型数据的共用体: unionfloat_data { floatf_data; uint8_tbyte ; }; 数据的流向如: 本次使用串口助手模拟发送设备,省略了第一步,主要看第②、③步。 创建两个共用体变量,用于发送与接收: unionfloat_datarx_float_data,tx_float_data; 收发相关代码: 左
[单片机]