记一次stm8l程序跑飞

Posted ideaming

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次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字节缓存

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






以上是关于记一次stm8l程序跑飞的主要内容,如果未能解决你的问题,请参考以下文章

记一次程序严重卡顿的经历

记一次idea性能调优

记一次因@Async引发的程序bug

记一次微信小程序在安卓的白屏问题

记一次 .NET 某工控MES程序 崩溃分析

记一次http网站换成https的处理