STM32 Flash编程:为何需将32位地址强转为16位存储16位数据?
STM32 Flash半字编程的地址类型转换原因
这里的类型转换和volatile修饰是完全必要的,核心原因和STM32 Flash硬件的编程规则、编译器优化逻辑直接相关:
硬件访问宽度必须匹配
代码里已经配置了FLASH_PSIZE_HALF_WORD,这个位告诉Flash控制器要执行16位(半字)的编程操作。此时必须用16位宽度的内存访问来触发编程——如果强制转成uint32_t*做32位写入,硬件会检测到访问宽度和配置的PSIZE不匹配,直接导致编程失败,甚至触发总线错误。防止意外破坏数据
若用uint32_t*写入,你的16位Data会被自动扩展成32位(无符号的话高位补0),这会把当前地址的高16位也覆盖成0,直接破坏Flash中原本存储在该地址上半部分的数据。而uint16_t*的转换只会修改指定地址的16位,完全符合半字编程的需求。volatile(__IO)禁止编译器优化
__IO是STM32标准库定义的宏,本质就是volatile。Flash编程是硬件层面的操作,编译器如果发现这个写入操作后没有后续读取,可能会直接优化掉这条指令,导致Flash根本没被编程。volatile强制编译器每次都直接操作内存地址,确保写入指令被执行。地址对齐检查
STM32的Flash半字编程要求地址是16位对齐的(地址最低位为0)。uint16_t*的类型转换会让编译器在编译阶段(如果开启对齐检查)就识别出非对齐地址的错误,而uint32_t*要求32位对齐,用它转换半字地址会触发硬件对齐异常。
附上参考代码:
static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data) { /* Check the parameters */ assert_param(IS_FLASH_ADDRESS(Address)); /* If the previous operation is completed, proceed to program the new data */ CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE); FLASH->CR |= FLASH_PSIZE_HALF_WORD; FLASH->CR |= FLASH_CR_PG; *(__IO uint16_t*)Address = Data; }
内容的提问来源于stack exchange,提问作者Paulson Raja L
相关产品推荐
相关产品推荐

