历史上的今天
返回首页

历史上的今天

今天是:2024年12月17日(星期二)

正在发生

2020年12月17日 | STM32F7xx —— 看门狗

2020-12-17 来源:eefocus

看门狗:指定时间内不喂狗,就重启系统。


最简单的看门狗设计(喂狗就是指定时间内给寄存器写一个固定值)


// 初始化独立看门狗

// prer:分频数:0~7(只有低 3 位有效!)

// rlr:自动重装载值,0~0XFFF.

// 分频因子=4*2^prer.但最大值只能是 256!

// rlr:重装载寄存器值:低 11 位有效.

// 时间计算(大概):Tout=((4*2^prer)*rlr)/32 (ms).

static IWDG_HandleTypeDef iwdg_handle;

void WatchdogInit(void)

{

  iwdg_handle.Instance = IWDG;

  iwdg_handle.Init.Prescaler = 5;

  iwdg_handle.Init.Reload = 250;

  iwdg_handle.Init.Window = IWDG_WINDOW_DISABLE; // 关闭窗口功能

 

  HAL_IWDG_Init(&iwdg_handle);

 

  os_watchdog_lock = xSemaphoreCreateMutex();

}

 

void WatchdogFeed(void)

{

  HAL_IWDG_Refresh(&iwdg_handle);

}

 


FreeRTOS看门狗设计(系统看门狗+任务看门狗)(其他操作系统也可以用这种思路)


任务看门狗:监控每个任务的活动状态,如果任务卡死,会导致系统重启。核心思想是使用计数,计数减为0后说明任务卡死。


TaskHandle_t os_watchdog_handle;

 

// 互斥信号量

static SemaphoreHandle_t os_watchdog_lock;

#define WATCHDOG_LOCK()    xSemaphoreTake(os_watchdog_lock, 100);

#define WATCHDOG_UNLOCK()  xSemaphoreGive(os_watchdog_lock)

 

#define WATCHDOG_CHECK_INTERVAL  100  // 100ms喂一次狗

#define WATCHDOG_POOL_SIZE       (OS_PRIO_MAX + OS_PRIO_MAX - 1) // 任务池 2倍的任务-1

 

typedef struct

{

  TaskHandle_t handle; // 任务句柄

  const char *name;    // 任务看门狗名称

  uint16_t timeout;    // 任务看门狗超时

  uint16_t time;       // 任务看门狗计数

  uint8_t suspended;   // 任务看门狗暂停

} watchdog_t;

 

static watchdog_t watchdogs[WATCHDOG_POOL_SIZE];

 

static void task_watchdog(void *params)

{

  int i;

 

  while(1)

  {

    WatchdogFeed();

 

    for(i = 0; i < WATCHDOG_POOL_SIZE; ++i)

    {

      if(0 == watchdogs[i].handle)

      {

        continue;

      }

 

      if(!watchdogs[i].suspended && watchdogs[i].time)

      {

        --(watchdogs[i].time);

      }

      if(!watchdogs[i].suspended && (0 == watchdogs[i].time))

      {

        printf("!!!!!!!!!!!!!!!! Watchdog %s timeout !!!!!!!!!!!!!!!!n", watchdogs[i].name);

        while(1);  // reset

      }

    }

 

    vTaskDelay(WATCHDOG_CHECK_INTERVAL);

  }

}

 

// 初始化独立看门狗

// prer:分频数:0~7(只有低 3 位有效!)

// rlr:自动重装载值,0~0XFFF.

// 分频因子=4*2^prer.但最大值只能是 256!

// rlr:重装载寄存器值:低 11 位有效.

// 时间计算(大概):Tout=((4*2^prer)*rlr)/32 (ms).

static IWDG_HandleTypeDef iwdg_handle;

void WatchdogInit(void)

{

  iwdg_handle.Instance = IWDG;

  iwdg_handle.Init.Prescaler = 5;

  iwdg_handle.Init.Reload = 250;

  iwdg_handle.Init.Window = IWDG_WINDOW_DISABLE; // 关闭窗口功能

 

  HAL_IWDG_Init(&iwdg_handle);

 

  os_watchdog_lock = xSemaphoreCreateMutex();

 

  xTaskCreate((TaskFunction_t)task_watchdog,

              (const char*   )"task_watchdog",

              (uint16_t      )OS_WATCHDOG_STK_SIZE,

              (void*         )NULL,

              (UBaseType_t   )OS_PRIO_WATCHDOG,

              (TaskHandle_t* )&os_watchdog_handle);

}

 

void WatchdogFeed(void)

{

  HAL_IWDG_Refresh(&iwdg_handle);

}

 

//===============================================================================================================

// 任务看门狗注册

void WatchdogRegister(const char *name, uint16_t timeout)

{

  int i;

  TaskHandle_t handle = xTaskGetCurrentTaskHandle();

 

  WATCHDOG_LOCK();

  for(i = 0; i < WATCHDOG_POOL_SIZE; ++i)

  {

    if (handle == watchdogs[i].handle)

    {

      WATCHDOG_UNLOCK();

      return;

    }

  }

  for(i = 0; i < WATCHDOG_POOL_SIZE; ++i)

  {

    if (0 == watchdogs[i].handle)

    {

      watchdogs[i].handle = handle;

      watchdogs[i].name = name;

      watchdogs[i].timeout = (timeout + WATCHDOG_CHECK_INTERVAL - 1) / WATCHDOG_CHECK_INTERVAL;

      watchdogs[i].time = watchdogs[i].timeout;

      watchdogs[i].suspended = 0;

      break;

    }

  }

  WATCHDOG_UNLOCK();

}

 

// 任务看门狗喂狗

void WatchdogKick(void)

{

  int i;

  TaskHandle_t handle = xTaskGetCurrentTaskHandle();

 

  for(i = 0; i < WATCHDOG_POOL_SIZE; ++i)

  {

    if (handle == watchdogs[i].handle)

    {

      WATCHDOG_LOCK();

      watchdogs[i].time = watchdogs[i].timeout;

      WATCHDOG_UNLOCK();

      break;

    }

  }

}

 

// 任务看门狗暂停

void WatchdogSuspend(void)

{

  int i;

  TaskHandle_t handle = xTaskGetCurrentTaskHandle();

 

  for(i = 0; i < WATCHDOG_POOL_SIZE; ++i)

  {

    if (handle == watchdogs[i].handle)

    {

      WATCHDOG_LOCK();

      watchdogs[i].suspended = 1;

      WATCHDOG_UNLOCK();

      break;

    }

  }

}

 

// 任务看门狗恢复

void WatchdogResume(void)

{

  int i;

  TaskHandle_t handle = xTaskGetCurrentTaskHandle();

 

  for(i = 0; i < WATCHDOG_POOL_SIZE; ++i)

  {

    if (handle == watchdogs[i].handle)

    {

      WATCHDOG_LOCK();

      watchdogs[i].time = watchdogs[i].timeout;

      watchdogs[i].suspended = 0;

      WATCHDOG_UNLOCK();

      break;

    }

  }

}


推荐阅读

史海拾趣

DESOUTTER公司的发展小趣事

Desoutter公司一直注重技术创新和产品升级。公司拥有一支专业的研发团队,不断投入资源进行新产品的研发和现有产品的改进。例如,公司成功开发了一系列新型气动螺丝起子、气动钻和气动冲击扳手等,这些产品不仅提高了工作效率,还降低了劳动强度。同时,Desoutter公司还利用先进的电脑辅助技术,实现了产品设计和生产的自动化,进一步提升了产品的质量和性能。

ECS公司的发展小趣事

ECS公司始终坚持以客户为中心的服务理念。他们深入了解客户的需求和痛点,为客户量身定制解决方案。例如,针对某些行业对数据安全性的特殊要求,ECS公司推出了专用的安全加密方案;针对一些大型企业对于大规模计算资源的需求,ECS公司提供了定制化的高性能计算服务。这些定制化服务不仅满足了客户的特殊需求,还增强了客户对ECS公司的信任和忠诚度。

Eurotechnique公司的发展小趣事

Eurotechnique公司成立于XXXX年,由几位具有远见卓识的电子工程师和企业家共同创立。他们看到了当时电子行业快速发展的趋势,尤其是数字电路和微控制器领域的巨大潜力。因此,公司决定专注于这两个领域的技术研发和产品生产。在创立初期,Eurotechnique通过不断的技术创新和产品优化,逐渐在市场上树立了良好的口碑。

ALLEN BRADLEY公司的发展小趣事

Eurotechnique公司成立于XXXX年,由几位具有远见卓识的电子工程师和企业家共同创立。他们看到了当时电子行业快速发展的趋势,尤其是数字电路和微控制器领域的巨大潜力。因此,公司决定专注于这两个领域的技术研发和产品生产。在创立初期,Eurotechnique通过不断的技术创新和产品优化,逐渐在市场上树立了良好的口碑。

Danaher Corporation公司的发展小趣事

在十九世纪80年代,丹纳赫集团面对日益严峻的市场竞争,开始推行以精益生产为核心的全新运营方式。这种管理方式不仅强化了其在行业中的领导地位,还逐渐形成了独特的丹纳赫商业系统(Danaher Business System,DBS)。DBS注重持续改进、客户导向和团队合作,成为丹纳赫集团在电子行业取得成功的关键因素。

台湾富致(FUZETEC)公司的发展小趣事

Futaba Electric最初起源于收音机收讯真空管的制造,但在1970年,公司做出了重大的战略调整,决定结束真空管业务,专注于萤光表示管(VFD)的生产。这一决策标志着公司从传统电子元件向高级显示技术的转型。随着VFD技术的不断发展,Futaba凭借其在清晰度、视角和亮度方面的卓越表现,逐渐在全球VFD市场中占据领先地位,目前市场份额超过60%。这一转型不仅使Futaba成为VFD技术的领导者,还为其在汽车仪表盘和抬头显示器等领域的广泛应用奠定了基础。

问答坊 | AI 解惑

笔试时候遇到的一个题,高手帮忙解答

Vcc=5V, VoH(min)=3.4V, VoL(max)=0.2V, ViH(min)=2.0V, ViL(max)=0.8V, IiH=0.04ma 问后面的非门要能正确识别前一级送出的信号,R的值最大取多少…

查看全部问答>

世界著名汽车品牌标识演化历史------标致

标致 Peugeot 法国标致公司在1812年创办于蒙特伯里亚德(Montbeliard),得名于家族祖先让·贾克斯·标致(Jean-Jaques Peugeot,1699~1741)。让·皮埃尔(Jean-Pierre)和让·弗雷德里克(Jean-Frederic)兄弟俩把他们的 ...…

查看全部问答>

车载电源逆变器电路

一 市场上常见款式车载逆变器产品的主要指标     输入电压:DC 10V~14.5V;输出电压:AC 200V~220V±10%;输出频率:50Hz±5%;输出功率:70W ~150W;转换效率:大于85%;逆变工作频率:30kHz~50kHz。 二 常见车载逆变器产品的 ...…

查看全部问答>

电源完整性(PI)的详细说明

电源完整性(PI)的详细说明…

查看全部问答>

protel99se 三个小问:请勿见笑

1.在用protel99绘制三极管(或其它分立元件)符号时,需不需要加上含电气热点的PIN脚啊?还是只要画好原理图符号就可以了呢(直接可以调用的了)? 2.采用SMD表贴元件时,是不是只要在SCH编辑器中将元件的封装设定为贴片类型(如0603,0402)即可?生成PCB ...…

查看全部问答>

QT:multiple definition of错误????????

源码:tem.h中定义Tem类 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class Tem : pub ...…

查看全部问答>

计数器小问题求救!!!

TIM时钟选择: ●     1> 内部时钟CK_INT ●     2> 外部时钟模式1:外部输入脚(Tix) ●     3> 外部时钟模式2:外部触发输入(ETR) ●     4> ...…

查看全部问答>

我晕死,STM8S103K3T6抗干扰能力巨差无比

                                 手头上一个项目用STM8S103K3T6,程序调完了,无聊的时候用手摸摸芯片的IO口,发现凡是输入口,摸多几次芯片必复位(最惨 ...…

查看全部问答>

请问刘工:i2c程序中设置I/O?

TI的文档通过设置 P1DIR 来改变SCL 和SDA的高低, 为何不把P1设为输出,再通过改变P1OUT来给SCL,SDA 置0 或 1 呢??…

查看全部问答>

徒步者探险装备

制作一款大小约为5*5cm的探险手持机,可挂在腰间。拥有的功能:电子指南针、计步器、大气压检测(高度度量)、温度计、野外照明、充电和电量检测功能等。TFT彩色液晶翻页显示测量数据,仅用两个按键却能提供快捷操作。 [ 本帖最后由 drjloveyou ...…

查看全部问答>