0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

结构体成员初始化不完整从而受到栈污染导致奇怪bug

冬至子 来源:吾爱单片机 作者:echigh 2023-05-25 11:11 次阅读

1.原因源于大家平时对网上大量不规范的例程的拷贝使用

2.比如在配置定时器输出pwm时候,一般网上抄的例程如下:

//4、初始化输出比较模式、配置输出比较模式的结构体参数
  TIM_OCStructInit(&TIM_OCInitStruct);//配置输出比较结构体的参数

  TIM_OCInitStruct.TIM_Pulse=50; //配置CCR寄存器,控制占空比
  TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1; //配置输出比较模式
  TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;//控制输出的极性
  TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;//输出使能
  TIM_OC1Init(TIM2,&TIM_OCInitStruct);

这里是有问题的,因为结构体TIM_OCInitStruct的成员不止这几个,如果不写全,那其他几个的值是栈里面的数据,栈数据是之前的函数执行后留下的,这样其他几个没写出来的成员就成了栈污染的受害者了。此时如果就这么初始化了,有时候会出现奇怪的BUG:比如通道关闭后IO仍然维持高电平。

3.正确的做法, 写全所有的结构体成员

//初始化TIM8 Channel3 PWM模式
  /*
  在PWM模式(模式1或模式2)下, TIMx_CNT和TIMx_CCRx始终在进行比较, 
  (依据计数器的计数方向)以确 定是否符合TIMx_CCRx≤TIMx_CNT或者TIMx_CNT≤TIMx_CCRx。
  */
  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputState_Disable; //所有成员初始化,否则数据不确定
  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High; //所有成员初始化,否则数据不确定
  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set; //所有成员初始化,否则数据不确定
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1
   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
//  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; //输出空闲状态是互补输出和死区插入那一节里面的知识,这里没影响
  TIM_OCInitStructure.TIM_Pulse=0;
  TIM_OC1Init(TIM8, &TIM_OCInitStructure);  //根据指定的参数初始化外设TIM8 OC3
  TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable);  //CH1预装载使能,预装载值在更新事件到来时被加载至当前寄存器中

4.辩论:

1)不明写,编译器也会给局部变量赋为0

答:

(1)或许有的编译器会将未幅值的局部变量赋0,但不能保证每个编译器都这么做。总之未幅值其值是不确定的(很容易验证:搞两个函数执行打印一下实测出来)

(2)在单片机程序里面,没写的寄存器不等于就是要赋0,所以即使编译器帮忙赋0了,也是不对的

2)可以用类似stm32单片机库函数中的deinit规避栈污染

答:

deinit只是将寄存器的值恢复到默认,不能清栈数据。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 寄存器
    +关注

    关注

    31

    文章

    5357

    浏览量

    120639
  • PWM
    PWM
    +关注

    关注

    114

    文章

    5193

    浏览量

    214211
  • 定时器
    +关注

    关注

    23

    文章

    3251

    浏览量

    115005
  • STM32单片机
    +关注

    关注

    59

    文章

    549

    浏览量

    58741
收藏 人收藏

    评论

    相关推荐

    esp32调试MQTT的程序,如何对.host初始化

    esp_mqtt_client_config_t mqtt_cfg这个结构的时候,你们例程里面只初始化url,但是我在网上看到很多地方的参考程序都是初始化这些
    发表于 06-11 07:55

    QT解决串口数据接收不完整问题

    1. 相关文章汇总(1)QT解决串口数据接收不完整问题(貌似贴出的代码可以存下串口接受的全部数据)(2)qt中使用串口类接收数据不完整 (3)Qt5.7串口接收数据不完整因为串口本来就不是一次接收
    发表于 08-18 06:58

    【原创分享】变量的初始化技巧

    ,第二种使用对结构成员变量赋值的方式。实质上,第1种方式编译器将自动生成一些指令完成变量a的初始化,而第2种方式编译器在处理Score a语句的时候只需要开辟
    发表于 09-08 15:28

    Keil使用结构数组的奇怪问题相关资料下载

    今天用keil的时候发现一个很奇怪的点,是关于结构数组的。首先说明我的keil版本是:V5.28.0.0问题是这样的:我在a.h文件定义了一个结构
    发表于 11-30 06:47

    stm32 printf打印出错导致信息不完整怎么解决?

    stm32 printf打印出错导致信息不完整怎么解决?
    发表于 12-02 08:02

    怎样去解决stm32串口DMA数据接收不完整的问题呢

    stm32串口DMA数据接收不完整问题说明最近做了一个项目需要用串口来接收模块端的应答数据,由于使用了实时操作系统,考虑中断嵌套或被打断的问题导致数据接收不完整的问题,使用串口dma接收数据,但
    发表于 02-21 06:19

    USART初始化结构详解

    USART 初始化结构详解标准库函数对每个外设都建立了一个初始化结构,比如USART_Ini
    发表于 02-22 06:08

    结构数组的初始化

    char i; TEST data1[5] = {{1,2},{3,4},{5,6},{7,8},{9,10}};//经常使用的初始化方式TEST data2[5] ={0};//初始全为0,否则
    发表于 05-21 15:24

    FAQ0066结构成员未完全初始化导致程序异常的解决方法

    使用非官方程序,由于某些外设驱动在配置结构时,未完全初始化所有成员导致程序运行异常。以 FSMC 为例,FSMC_NORSRAMInit
    发表于 10-20 06:59

    结构的定义、初始化和赋值

    type)的一类。结构可以被声明为变量、指针或数组等,用以实现较复杂的数据结构结构同时也是一些元素的集合,这些元素称为
    发表于 11-20 09:29 5.5w次阅读

    在51平台下初始化文件的引入导致全局变量无法初始化的问题如何解决

    本文档的主要内容详细介绍的是在51平台下初始化文件的引入导致全局变量无法初始化的问题如何解决。
    发表于 08-20 17:31 0次下载
    在51平台下<b class='flag-5'>初始化</b>文件的引入<b class='flag-5'>导致</b>全局变量无法<b class='flag-5'>初始化</b>的问题如何解决

    Keil使用结构数组的奇怪问题

    今天用keil的时候发现一个很奇怪的点,是关于结构数组的。首先说明我的keil版本是:V5.28.0.0问题是这样的:我在a.h文件定义了一个结构
    发表于 11-21 16:36 3次下载
    Keil使用<b class='flag-5'>结构</b><b class='flag-5'>体</b>数组的<b class='flag-5'>奇怪</b>问题

    stm32串口DMA数据接收不完整问题说明

    stm32串口DMA数据接收不完整问题说明最近做了一个项目需要用串口来接收模块端的应答数据,由于使用了实时操作系统,考虑中断嵌套或被打断的问题导致数据接收不完整的问题,使用串口dma接收数据,但
    发表于 12-24 19:37 21次下载
    stm32串口DMA数据接收<b class='flag-5'>不完整</b>问题说明

    浅谈C语言中的三种不完整类型

    不完整类型(Incomplete types)是缺少足够信息来确定该类型对象大小的对象类型,不完整类型可以在翻译单元的某些点完整
    发表于 12-16 09:52 515次阅读

    如何获取ChatGPT回答不完整的内容

    ____tz_zs 对于 ChatGPT 回答不完整的情况(篇幅限制,没有说完),可以输入“继续”指令,让其继续回答下去,获得完整内容。 如下图,发问 “使用web3js 调用 eth链智能合约” 直到这里才是获得了刚刚问题 “使用web3js 调用 eth链智能合约”
    发表于 02-10 10:48 0次下载
    如何获取ChatGPT回答<b class='flag-5'>不完整</b>的内容