历史上的今天
今天是: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;
}
}
}
上一篇:STM32F7xx —— ADC
史海拾趣
|
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)兄弟俩把他们的 ...… 查看全部问答> |
|
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,程序调完了,无聊的时候用手摸摸芯片的IO口,发现凡是输入口,摸多几次芯片必复位(最惨 ...… 查看全部问答> |
|
TI的文档通过设置 P1DIR 来改变SCL 和SDA的高低, 为何不把P1设为输出,再通过改变P1OUT来给SCL,SDA 置0 或 1 呢??… 查看全部问答> |




