• 记一次stm8l程序跑飞


    项目使用stm8l051f3做主控,CC2500做数据接收,不发送。

    跑飞的现象就是,刚开始能运行,经过一段未知长度的时间,有可能是3分钟,有可能是30分钟,指示灯不再闪烁,中断按键单片机无反应。

    接入调试器发现跑到了一个非常大的地址,已经超过了mcu的内部flash空间。可以确定是程序跑飞。

    经验是:

    程序跑飞,查条件语句是否都有做处理。

    程序跑飞,查内存溢出。

    查了好久,查出是内存溢出导致。

    因为发送端发送的数据固定是32字节,所以在接收端只开辟了一个32字节的buffer去读取收到的数据。

    /*******************************************************************************  
    * @brief GDO2中断处理函 
    * @param None

    * @retval None ****************************************************************Author:Liming*
    */ void GDO2_Int(void) { uint8_t temp; unsigned char RecvBuffer[0x20]={0};//开辟32字节缓存 unsigned char RecvLength; if(EXTI_GetITStatus(EXTI_IT_Pin6) != RESET) { EXTI_ClearITPendingBit(EXTI_IT_Pin6); DelayNms(1);//等待接收完成 RecvLength = CC2500Recv(RecvBuffer); //获取收到的数据长度 temp = ProPacketCheck(RecvBuffer,RecvLength,0x0001,0x0003);//数据完整性校验 if((temp == 0x04)||(temp==0xff)) // 本机和广播信息需要处理 {
           //数据处理
    CC2500SetState(CC2500_STATUS_POWERDOWN_LEVEL2); } else CC2500SetState(CC2500_STATUS_RECEIVE); } }
    //接收数据
    unsigned char CC2500Recv(unsigned char *Buffer,unsigned char Mode)
    {
      unsigned char Result=0x00,Status=0x00;
      switch(CC2500State)
      {
      case 0x00:
      case 0x01:
        if(CC2500State) Delayms(0x07);
        else Delayus(0x30);
        Status=CC2500SpiReadStatus(RXBYTES);
        if(Status&0x80)//如果数据长度超过64字节
        {
          CC2500SpiReadBuffer(FIFO,Buffer,0x40);//读取64字节
          Result=0x40;
        }
        else if(Status&0x7F)
        {
          CC2500SpiReadBuffer(FIFO,Buffer,Status&0x7F);//读取收到的数据
          Result=Status&0x7F;
        }
        CC2500SetState(Mode);
        break;
      }
      return Result;//返回读取的数据长度
    }

    但由于无线信号的干扰,CC2500可能会收到大于32字节的数据(虽然不是本系统需要的),

    导致在从cc2500取出的时候,存入buffer的长度超过开辟的buffer空间。

    解决办法1:既然知道是32字节数据,可以在

        CC2500Recv接收函数里只接收32字节。
        if(Status&0x80)//如果数据长度超过64字节
        {
          CC2500SpiReadBuffer(FIFO,Buffer,0x20);//读取32字节
          Result=0x20;
        }
        else if(Status&0x7F)
        {
          CC2500SpiReadBuffer(FIFO,Buffer,0x20);//读取收到的数据
          Result=0x20;
        }
     

    解决办法2:

        GDO2_Int函数里开辟64字节空间即便是收到最多的数据也不会超出缓存空间。
        unsigned char RecvBuffer[0x40]={0};//开辟64字节缓存

     有了这次的程序跑飞的处理经历,再次验证了程序跑飞大部分都是内存溢出导致的说法。

  • 相关阅读:
    字符转换(2,8,10,16进制,ASCII码)
    js正则表达式验证
    不能在DropDownList 中选择多个项
    SQL中sum(),avg()等统计结果为null的解决方法
    文本框TextBox只允许输入数字,不用onkeyup
    ORA01830: 日期格式图片在转换整个输入字符串之前结束
    Oracle数据库中的左连接与右连接
    asp.net服务器验证控件失效的问题
    在博客园开通博客的第一天
    米勒拉宾素数测试
  • 原文地址:https://www.cnblogs.com/IdeaMing/p/10141525.html
Copyright © 2020-2023  润新知