模塊介紹
N32L40XCL 內(nèi)置獨立看門狗(IWDG)和窗口看門狗(WWDG)定時器,解決軟件錯誤導致的問題。看門狗定時器使用非常靈活,提高了系統(tǒng)的安全性和定時控制的準確性。
獨立看門狗(IWDG)由運行在 40KHz 的低速內(nèi)部時鐘(LSI 時鐘)驅(qū)動,在死循環(huán)事件或 MCU 卡死發(fā)生時,它仍然可以運行。這可以提供更高的安全級別、定時精度和看門狗的靈活性。它可以通過重置來解決由于軟件故障引起的系統(tǒng)故障。IWDG 最適合需要看門狗在主應用程序之外作為完全獨立進程運行但時序精度限制較低的應用程序。
窗口看門狗(WWDG)的時鐘是由 APB1 時鐘頻率除以 4096 得到的,通過時間窗口的配置來檢測程序運行是否異常。因此,WWDG 適用于精確定時,常用于監(jiān)控因外部干擾或無法預見的邏輯條件導致應用程序偏離其正常操作順序的軟件故障。當 WWDG 遞減計數(shù)器在達到窗口寄存器值之前或 WWDG_CTRL.T6 位變?yōu)?0 之后刷新時,系統(tǒng)復位發(fā)生。
官方WDT驅(qū)動實現(xiàn)的是獨立看門狗(IWDG)。
開發(fā)軟件
開發(fā)環(huán)境:
RT-Thread Studio 2.2.6
RT-Thread版本:4.0.2
下載工具:pyocd
步驟說明
新建工程
打開RT-Thread settings,使能Watchdog Timer,如下圖所示。
添加保存后,進行編譯,若無問題,則進行下一步。
編寫測試程序
編寫測試程序如下:
#include
#include
#include
/* defined the LED3 pin: PB5 /
#define LED3_PIN GET_PIN(B, 5)
#define WDT_DEVICE_NAME "wdt" / 看門狗設備名稱 /
static rt_device_t wdg_dev; / 看門狗設備句柄 /
static void idle_hook(void)
{
/ 在空閑線程的回調(diào)函數(shù)里喂狗 /
rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, NULL);
//rt_kprintf("feed the dog!n ");
}
int main(void)
{
/ set LED3 pin mode to output /
rt_pin_mode(LED3_PIN, PIN_MODE_OUTPUT);
rt_err_t ret = RT_EOK;
rt_uint32_t timeout = 3000; / 溢出時間,單位:毫秒 /
char device_name[RT_NAME_MAX];
rt_strncpy(device_name, WDT_DEVICE_NAME, RT_NAME_MAX);
/ 根據(jù)設備名稱查找看門狗設備,獲取設備句柄 /
wdg_dev = rt_device_find(device_name);
if (!wdg_dev)
{
rt_kprintf("find %s failed!n", device_name);
return RT_ERROR;
}
/ 設置看門狗溢出時間 /
ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);
if (ret != RT_EOK)
{
rt_kprintf("set %s timeout failed!n", device_name);
return RT_ERROR;
}
/ 啟動看門狗 /
ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_START, RT_NULL);
if (ret != RT_EOK)
{
rt_kprintf("start %s failed!n", device_name);
return -RT_ERROR;
}
/ 根據(jù)設備名稱查找看門狗設備,獲取設備句柄 /
wdg_dev = rt_device_find(device_name);
if (!wdg_dev)
{
rt_kprintf("find %s failed!n", device_name);
return RT_ERROR;
}
/ 設置空閑線程回調(diào)函數(shù) */
rt_thread_idle_sethook(idle_hook);
while (1)
{
rt_pin_write(LED3_PIN, PIN_HIGH);
rt_thread_mdelay(500);
rt_pin_write(LED3_PIN, PIN_LOW);
rt_thread_mdelay(500);
}
}
代碼驗證
程序很簡單,初始化看門狗后,在空閑線程回調(diào)函數(shù)中不斷喂狗即可。在正式使用看門狗時,取消回調(diào)函數(shù)中的打印。
下載程序后運行。
如果終端打印提示“warning: tidle0 stack is close to end of stack address.”,請在rtconfig.h文件中搜索IDLE_THREAD_STACK_SIZE,并擴大該棧空間。默認值是256,可以擴大到512。
程序中使用RT_DEVICE_CTRL_WDT_SET_TIM命令設置超時時間,需要注意對于N32L40XCL開發(fā)板的驅(qū)動程序而言,這個超時時間的單位是毫秒,而有些RT-Thread的驅(qū)動程序這個超時時間的單位是秒。
此外,這個超時時間不能設置過長,因為過長會超過N32L40XCL寄存器的范圍。對于默認配置,這個超時時間不能超過376ms。否則程序會打印如下錯誤信息:
[W/DBG] wdg set timeout parameter too large, please less than 3276 ms
set wdt timeout failed!
具體的工作原理可以參考下面這段drv_wdt.c的代碼:
case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
{
RT_ASSERT(*(uint16_t *)args != 0);
reload_value = *(uint16_t *)args;
if(reload_value > 0xFFF * 32 *1000 / LsiFreq)
{
LOG_W("wdg set timeout parameter too large, please less than %d msn", 0xFFF * 32 *1000 / LsiFreq);
return -RT_EINVAL;
}
/* Enable write access to IWDG_PR and IWDG_RLR registers */
IWDG_WriteConfig(IWDG_WRITE_ENABLE);
/* IWDG counter clock: LSI/32 */
IWDG_SetPrescalerDiv(IWDG_PRESCALER_DIV32);
reload_value = ((uint32_t)reload_value * LsiFreq / 1000) / 32;
IWDG_CntReload(reload_value);
IWDG_WriteConfig(IWDG_WRITE_DISABLE);
}
如果注釋掉上面idle_hook中的喂狗語句,則可以看到程序每3秒重啟一次。
章節(jié)總結
通過測試,可以驗證N32L40XCL芯片的WDT驅(qū)動程序可以正常運行。
-
寄存器
+關注
關注
31文章
5254瀏覽量
119217 -
RT-Thread
+關注
關注
31文章
1239瀏覽量
39447 -
MCU控制器
+關注
關注
0文章
27瀏覽量
6858 -
WWDG
+關注
關注
0文章
19瀏覽量
5478 -
IWDG
+關注
關注
0文章
21瀏覽量
5182
發(fā)布評論請先 登錄
相關推薦
評論