STM32问题记录:这回Keil编译器背锅

发布者:水云间梦最新更新时间:2018-12-18 来源: eefocus关键字:STM32  Keil  编译器 手机看文章 扫描二维码
随时随地手机看文章

最近写了个用环形缓冲区发送数据的STM32串口程序:使用头指针(front)指向下一个要发送数据,使用尾指针(rear)指向新数据存储的地方。中断里面会判断front和rear是否相等,如果相等则表示缓冲区为空,发送已经完成,关闭中断;反过来说,front和rear相等表示缓冲区还有数据要发送,那么就在中断里面把数据一个一个地发送出去。


那么问题来了,我在存数据的时候写了这么一行代码:


USART1_SendQueue[USART1_SendRear ++] = data;


也就是说,把数据存入缓冲区后,尾指针自+1。这看起来没毛病,但编译器给出汇编代码是这样的:


0x0800213C  LDR      r0,[pc,#492]      ;取出USART1_SendRear的地址存到r0

……

0x08002148  LDR      r1,[r0,#0x00]     ;将USART1_SendRear的值存入r1

0x0800214A  LDR      r0,[r0,#0x00]     ;将USART1_SendRear的值存入r0

0x0800214C  ADDS     r0,r0,#1        ;将r0自加1

0x0800214E  LDR      r2,[pc,#476]      ;取出USART1_SendRear的地址存到r2

0x08002150  STR      r0,[r2,#0x00]     ;将r0的值存入USART1_SendRear的地址

0x08002152  LDR      r0,[pc,#480]      ;取出USART1_SendQueue的首地址存到r0

0x08002154  STRH     r5,[r0,r1,LSL #1] ;将data(r5)存入r0+(USART1_SendRear<<1)的地址中(左移1位相当于*2,是因为数组一个元素有两个字节)


在C的代码的逻辑中


USART1_SendQueue[USART1_SendRear ++] = data; 


应该等效于:


USART1_SendQueue[USART1_SendRear] = data; 

USART1_SendRear ++;


然而汇编的代码的逻辑转换成C等效于:


temp = USART1_SendRear;

USART1_SendRear ++;

USART1_SendQueue[temp] = data;


那么问题来了,如果按照原来的C逻辑,因为数据存入后指针才会自+1,所以即使发送过程中触发中断,也只有数据存入缓冲区以后才会判断出缓冲区非空。而在汇编的逻辑中, 指针+1后才把数据存入缓冲区。如果指针+1之后突然来了个中断,那么有可能会把数据即将写入的那个地址的数据先发出去,然后再写入,发送就出错了!


形象一点就是说:


temp = USART1_SendRear;

USART1_SendRear ++;

//这个位置突然来了一个中断

//中断发送了当前USART1_SendQueue[temp] 的数据

//中断返回后再执行下面那句

USART1_SendQueue[temp] = data;


好吧,如果不考虑中断的话,汇编代码这么做不会带来错的结果,可惜中断来得就是这么巧。


这个问题找了好多天,今天终于找到了。编译器这么编译,也是很无奈。所以代码改成如下就好了:


//把这两步拆开写,免得编译器整出幺蛾子

USART1_SendQueue[USART1_SendRear] = data; 

USART1_SendRear ++;

T=T

关键字:STM32  Keil  编译器 引用地址:STM32问题记录:这回Keil编译器背锅

上一篇:STM32F4各外设时钟配置总结
下一篇:深度讨论32复位及SystemInit函数在程序中的作用

推荐阅读最新更新时间:2024-03-16 16:20

高效的C编程之:C编译器及其优化(中)
2.冗余代码的清除 下面例子显示了一段急待优化的代码。 intdummy() { inta=10,b=20; intc; c=a+b; return0; } 当使用arm–c–O0进行编译时,产生的汇编码如下所示。 dummy: 0000807CE3A0100AMOV r1,#0xa REDUNDANT#3inta=10,b=20; 00008080E3A02014MOV r2,#0x14 REDUNDANT#5c=a+b; 00008084E0813002ADD r3,r1,r2 REDUNDANT#6return0; 00008088E3A00000MO
[单片机]
ST-Link 在keil5无法下载程序解决办法
以前一直在用J-Link下载程序,由于工作需要,换成ST-Link下载程序。第一次用ST-Link怎么也下载不下去,后来差CSDN博客:https://blog.csdn.net/zeroice7/article/details/59483155 找到解决办法,就是,在Keil安装目录下,C:Keil_v5ARMSTLink下找到升级文件“ST-LinkUpgrade.exe”,点击,打开应用程序 对ST-Link/V2执行升级,重新插拔ST-Link,就可以下载程序了
[单片机]
ST-Link 在<font color='red'>keil</font>5无法下载程序解决办法
STM32——EEPROM
一、I2C接口读写EEPROM(AT24C02) ——主模式,分别用作主发送器和主接收器。通过查询事件的方式来确保正常通信。 1、I2C接口初始化 与其他对GPIO 复用的外设一样,它先调用了用户函数I2C_GPIO_Confi g() 配置好 I 2 C 所用的 I/O端口,然后再调用用户函数 I2C_Mode_Confi gu() 设置 I 2 C 的工作模式,并使能相关外设的时钟。 void I2C_EE_Init(void) { I2C_GPIO_Config(); I2C_Mode_Config(); /* 根据头文件 i2c_ee. 14 h 中的定义来选择 EEPROM 要写入的地址 */
[单片机]
<font color='red'>STM32</font>——EEPROM
基于STM32的多色温多星等输出的单星模拟器设计
随着近年来我国空间科学技术的快速发展,卫星、载人飞船等航天器需要更高的控制精度、可靠性和更长的寿命。星敏感器在各种航天器上大量应用,其性能指标直接影响到测量结果的可信度。单星模拟器是星敏感器的主要地面标定设备之一,所要实现的功能是在实验室内提供与单颗真实恒星在光度特性、光谱特性等方面趋于一致的模拟恒星 。传统单星模拟器大多体积大,精度低,稳定性不够好,可调节色温单一,实现星等范围小 。本项目采用模块化设计,将多束不同窄带光谱、不同强度的光线混合,并控制总体输出光强,最终实现不同等效黑体色温和不同星等。 1 结构设计 如图1 所示,单星模拟器系统总体结构由 电源 、光源、波段光强控制器、积分球、星等控制器、工控箱、P
[单片机]
基于<font color='red'>STM32</font>的多色温多星等输出的单星模拟器设计
stm32 HAL库分析之CAN
stm32 HAL库分析之CAN 阻塞发送 HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout) 565 { 566 uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX; 567 uint32_t tickstart = 0U; 5
[单片机]
<font color='red'>stm32</font> HAL库分析之CAN
关于C51编译器的声明标识符
data 128字节的内部数据数据存储空间(00h~7Fh)。可直接或间接访问。全部或部分的堆栈可能保存在此区域中。 idata 间接数据。256字节的内部数据存储空间(00h~FFh。全部或部分的堆栈可能保存在此区域中。此区域包括data区和data区以上的128字节。 sfr 特殊功能寄存器。CPU寄存器和外围部件控制/状态寄存器,只能通过直接地址访问。 pdata 分页的外部数据(256字节)或片上扩展RAM(XRAM)。MA805-64有256字节片上pdata存储器它与片上xdata存储器共存。 xdata 外部数据或片上扩展RAM(XRAM)。MA805-64有1024字节的片上xd
[单片机]
ST发布STSAFE-A100评估套件,扩大STM32 Nucleo生态系统
意法半导体发布了STSAFE-A100评估套件,将进一步扩大STM32 Nucleo生态系统的丰富资源,加快安全单元的集成设计,利用可复用源代码以简化安全物联网设备、医疗探针等高价耗材、IT配件和消费产品的开发设计流程。 该评估套件包括集成STSAFE-A100安全单元的X-NUCLEO-STSA100扩展板和STSW-STSA100软件包。软件包括设备驱动程序、STM32微控制器源代码和STSAFE-A100的用例源代码,包括品牌和生态系统保护、设备注册和安全云连接等用例。 STSAFE-A100是一款便于使用的8引脚安全单元,可为主机系统提供稳健的不可变的硬件身份验证和安全数据管理服务,具有极强的网络攻击防御能力
[单片机]
ST发布STSAFE-A100评估套件,扩大<font color='red'>STM32</font> Nucleo生态系统
STMCU应用过程中与电源相关的案例分享
我们在从事STM32单片机的应用开发及调试过程中,往往会碰到各类异常。其中有不少比例的问题跟电源有关。对于一个电子产品而言,电源部分很关键、很重要,但在实际开发调试中,我们偶尔会有意无意的忽视它。这里分享几个实际案例,以加强刺激,加深印象。 毕竟因为电源问题可能导致的异常很多很多,这里分享几个案例算是抛砖引玉,希望大家在调试中对电源方面加以重视。个人认为,往往电源出问题时导致的异常时并不太好分析。多数时候异常表现得更为诡异或没章法。 注:下面提到的案例中异常原因都与电源有关,但并不是说出现类似异常时一定是电源的原因。 下面主要分享五个基于STM32应用的案例。 案例1:STM32芯片的PLL无法正常工作。 有人使用STM3
[单片机]
STMCU应用过程中与电源相关的案例分享
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved