1. 程式人生 > >記一次stm8l程序跑飛

記一次stm8l程序跑飛

return 開始 else if val 取出 按鍵 clas etc 解決辦法

項目使用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程序跑飛