STM32F7xx —— 看门狗
生活随笔
收集整理的這篇文章主要介紹了
STM32F7xx —— 看门狗
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?STM32F7xx —— 看門狗
?
?
看門狗:指定時間內不喂狗,就重啟系統。
?
最簡單的看門狗設計(喂狗就是指定時間內給寄存器寫一個固定值)
// 初始化獨立看門狗 // 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倍的任務-1typedef 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 —— 看门狗的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 揭开阿里巴巴复杂任务资源混合调度技术面纱
- 下一篇: 软考初级程序员常见类型题,错题个人笔记