if(((*(vu32*)(0X20001000+4))&0xFF000000)==0x08000000)分析
(*(vu32*)(0X20001000+4))== (*(__IO uint32_t*)(0X20001000+4))
==(*(volatile unsigned int*)(0X20001000+4))
(*(vu32*)(0X20001000+4)) 通过内存寻址访问地址为(0x20001000 + 4)中的值
(0X20001000+4)只是一个常量;
(volatile unsigned int*)(0X20001000+4) 将0x20001000 + 4这个常量强制转化成volatile unsigned int类型的指针;
(*(volatile unsigned int*)(0X20001000+4)) 相对于取0x20001000 + 4地址处的值
串口接收来的数据从0x20001000开始存储,第一个4个字节为栈顶地址,第二个4字节为复位中断向量的入口地址。1) STM32正常运行流程图
STM32在复位后,先从0x08000004地址取出复位中断向量的地址,并跳转到复位中断复位程序,如图标号①所示;在复位中断复位程序执行完之后,会跳转到main函数,如图标号②所示;main函数一般是一个死循环,在main函数执行过程中,如果收到中断请求,此时STM32强制将PC指针指回中断向量表处,如图标号③所示;然后,根据中断源进入相应的中断服务程序,如图标号④所示;在执行完中断服务程序后,程序再次返回main函数执行,如图标号⑤所示。
2) volatile
1.volatile是一个类型修饰符(typespecifier);
2.volatile关键字声明的变量,编译器对访问该变量的代码就不再进行优化;
例如:
要往某一地址写数据:
int*a =0;
*a=1;
*a=2;
以上程序编译器可能做优化而成:
int*a =0;
*a=2;
结果第一个指令丢失。如果用volatile声明, 编译器就不允许做任何的优化,从而保证程序的原意:
int*a =0;
*a=1;
*a=2;
即使你要编译器做优化,它也不会把两次赋值语句简化为一。它只能做其它的优化。
3.volatile关键字声明的变量,每次都必须从内存中读取数据,而不能使用放在cache或寄存器中的备份;
例如:
volatilechar a;
a= 0;
while(!a)
{
//dosome things
}
doother();
如果变量没有声明为volatile,那么do other()不会被执行;
3) STM32内核(Cortex-M3)的存储器映射
存储器映射是指把芯片中或芯片外的FLASH,RAM,外设,BOOTBLOCK等进行统一编址。即用地址来表示对象。这个地址绝大多数是由厂家规定好的,用户只能用而不能改。用户只能在挂外部RAM或FLASH的情况下可进行自定义。