1、关键字volatile
volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,告诉编译器对该变量不做优化,都会直接从变量内存地址中读取数据,从而可以提供对特殊地址的稳定访问。
①并行设备的硬件寄存器。(对硬件寄存器进行映射时,要加volatile,其可能随时被外设修改)
存储器映射的硬件寄存器(寄存器映射:给已经分配好地址的具有特定功能的内存单元取别名的过程就叫寄存器映射)通常也要加 volatile,因为每次对它的读写都可能有不同意义。
如#define GPIOB_ODR volatile *(unsigned int*)(GPIOB_BASE + 0x0C)
②中断服务程序中修改的供其它程序检测的变量,需要加volatile
中断发生后,子程序中的变量改变,而编译器认为主程序中变量没有修改,因此只进行一次从内存到寄存器的读操作,之后从寄存器中读取变量副本,使得中断操作被“短路”。
③多任务环境下各任务间共享的标志,应该加volatile
在多线程中,编译器会在读取一个变量时,将其放到寄存器中,这样以后读取变量就直接从寄存器中取值,但是,当此变量由于别的线程改变后,寄存器的值不会相应改变,加入volatile后,可以共享寄存器,保证应用程序读取的值一致。
【注意:频繁地使用volatile很可能会增加代码尺寸和降低性能】
2、M3内核架构
CPU内核基于总线进行处理,I-Code(Flash)总线用于取指令&执行指令,按字(32位)进行。D-Code(SRAM)总线用于对数据进行读取,支持非对齐访问(一般不)。AHB系统总线负责取值令和数据访问,直接处理静态RAM和外部RAM,管理设备和外设。
APB1外设时钟使能寄存器(RCC_APB1ENR) 低速APB使能,最大允许频率36MHz,外设时钟有DAC、CAN、IIC、SPI和USRAT2\3\4\5等。
APB2外设时钟使能寄存器(RCC_APB2ENR) 高速APB使能,最大允许频率72MHz,外设时钟有ADC、SPI1、USART1、IO、TIM等。
总线矩阵用于主控总线之间的访问仲裁管理,仲裁采用循环调度算法,可以在一条总线上同时访问指令和数据。