linalinb 发表于 2018-8-27 14:04:53

本帖最后由 linalinb 于 2018-8-27 14:06 编辑

wenyangzeng 发表于 2018-8-27 13:26
其实喂狗只放在主循环并不很安全。在所有do{}while()都要放。你不能保证这些do{}while()里会出现何种意外 ...
我的理解是这样的不知道对不对,如果在所有的while里面都喂狗的话,如果程序跑飞时,恰好是执行到了while里面的喂狗指令,那死机时岂不是更容易出现不会复位的情况?

linalinb 发表于 2018-8-27 14:09:37

wenyangzeng 发表于 2018-8-27 13:26
其实喂狗只放在主循环并不很安全。在所有do{}while()都要放。你不能保证这些do{}while()里会出现何种意外 ...

我的理解是这样的也不知道对不对,如果在所有的while里面都放喂狗指令,若当程序跑飞时,如果刚好执行到里面的喂狗指令,那岂不是死机时更不会复位?

wenyangzeng 发表于 2018-8-27 14:22:04

如果某个因素使while循环超时,就会启动看门狗了。

linalinb 发表于 2018-8-27 14:36:15

wenyangzeng 发表于 2018-8-27 14:22
如果某个因素使while循环超时,就会启动看门狗了。

问题是如果while里面放有喂狗指令的话,看门狗就不会复位了。

wenyangzeng 发表于 2018-8-27 15:20:53

linalinb 发表于 2018-8-27 14:36
问题是如果while里面放有喂狗指令的话,看门狗就不会复位了。
除非你能100%肯定这个while退出后能够及时跳到主循环里清看门狗。我的做法是:凡是有循环等待就清看门狗

jy04706985 发表于 2018-8-27 15:39:23

我觉得这种情况并没有死机,也会正常喂狗,只不过主循环内的程序执行的比较慢,导致按键或者显示响应不及时。串口数据接收出现异常的时候会不停的进出中断,中断中又没有清理异常标志,所以造成假死机现象。

linalinb 发表于 2018-8-27 16:03:36

jy04706985 发表于 2018-8-27 15:39
我觉得这种情况并没有死机,也会正常喂狗,只不过主循环内的程序执行的比较慢,导致按键或者显示响应不及时 ...

int main(void)
{
    // u8 ChkSum,j;
    //===============================================//
#ifdef DEBUG
    debug();
#endif
    SysInit();
    __nop();
    //=====================================//
    //=====================================//
    //01 10 00 00 00 0F 1E (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00) E9 D6
    Send_To_PLC_Data=0x01;
    Send_To_PLC_Data=0x10;
    Send_To_PLC_Data=0x00;
    Send_To_PLC_Data=0x00;
    Send_To_PLC_Data=0x00;
    Send_To_PLC_Data=0x0f;
    Send_To_PLC_Data=0x1e;

    //01 03 00 32 00 04 E5 C6
    Read_PLC=0x01;
    Read_PLC=0x03;
    Read_PLC=0x00;
    Read_PLC=0x32;
    Read_PLC=0x00;
    Read_PLC=0x04;
    Read_PLC=0xe5;
    Read_PLC=0xc6;
    //=====================================//
    GPIO_ResetBits( GPIOB, GPIO_Pin_3);
    while(1)
    {
      IWDG_ReloadCounter();
      Run();
    }
}
我的程序如上,主程序很简单,没有按键与显示处理功能,只是将产品数据与PLC数据交换,所有功能都在Run();函数完成,此函数完成时间约4秒左右,如上所示就一条喂狗指令,我设想是如果超时6秒在Run()函数没有正确返回,就不能喂狗,程序应该就能复位,在实验室测试也可以,但在车间实际使用一段时间就会偶尔出现死机现象,只有关电重启才能恢复正常工作。

linalinb 发表于 2018-8-27 16:22:38

void USART2_IRQHandler(void)
{
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
    {
      if(kk==0)
      {
            Tm3=20;
            ch2 = USART_ReceiveData(USART2);
            if(ch2==0x01)
            {
                kk=1;
                return;
            }
      }
      if(kk==1)
      {
            Tm3=20;
            ii++;
            ch2= USART_ReceiveData(USART2);
      }
    }


    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
    {
      USART_ClearFlag(USART2, USART_FLAG_RXNE);
      USART_ClearITPendingBit(USART2, USART_IT_RXNE);
    }

    if (USART_GetFlagStatus(USART2, USART_FLAG_PE) != RESET)
    {
      USART_ReceiveData(USART2);
      USART_ClearFlag(USART2, USART_FLAG_PE);
    }

    if (USART_GetFlagStatus(USART2, USART_FLAG_ORE) != RESET)
    {
      USART_ReceiveData(USART2);
      USART_ClearFlag(USART2, USART_FLAG_ORE);
    }

    if (USART_GetFlagStatus(USART2, USART_FLAG_FE) != RESET)
    {
      USART_ReceiveData(USART2);
      USART_ClearFlag(USART2, USART_FLAG_FE);
    }
}

==========================================
我这个中断处理函数也有点问题,那个return会导致不会执行后面的清标志位的语句,但是如果不断的进出中断的话,如果没喂狗应该也会复位吧,而测试却也很正常。

发表于 2018-8-27 17:17:51

用系统的时候,就会遇到这样的问题。多个任务调用之间。如果有一个任务死掉了怎么办?这个时候一般使用的是任务监控,比如规定指定时间内进行对应的定时器赋值,当某个任务的定时器赋值和当前的时间超过规定时间就认为是有任务死掉了。强制进行复位。

chifen 发表于 2018-8-28 08:41:49

加一个灯 在while里,看程序 是不是一直这样运行, 还要再加一条 Run();里面进入条件 时也要加一个不一样的灯做对比,正常硬件狗不会出问题的,可能是你程序有问题
页: 1 2 [3] 4
查看完整版本: STM32死机,内部硬件看门狗也不复位