【中科蓝讯AB32VG1 RISC-V板“碰上”RTT测评】看门狗
本帖最后由 xiyue521 于 2021-5-16 01:48 编辑<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle"><span style="font-size:20px;"> 看门狗的目的是为了保护芯片避免其进入死循环(或者说程序跑飞)。看门狗有一个输入端和一个输出端。看门狗和单片机程序的主体部分连接,如果主体部分运行正常,那么每一段时间就会给看门狗的输入端一个信号,这时候看门狗就会知道程序运行正常,就不会做出反应。如果看门狗较长一段时间内没有收到信号,说明程序运行不正常,此时由看门狗输出一个信号,该信号会让单片机的主体程序复位进而起到保护的作用。</span></p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle"><span style="font-size:20px;">首先使能看门狗,然后照旧用rt_device_find查找设备,成功了进入下一步:</span></p>
<p class="imagemiddle"><span style="font-size:20px;">开发板的看门狗主要有3个函数:(其实只有一个,就是第二,三个参数不一样)</span></p>
<p><span style="font-size:20px;">设置看门狗溢出时间 :rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);<br />
<br />
启动看门狗 :rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_START, RT_NULL);<br />
</span></p>
<p><span style="font-size:20px;">喂狗rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, NULL);</span></p>
<p class="imagemiddle" style="text-align: center;"><span style="font-size:20px;"></span></p>
<p> </p>
<p> </p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle" style="margin-left: 40px;"><span style="font-size:20px;">timeout溢出时间选择1024ms,也可以有其他的:</span></p>
<p class="imagemiddle" style="text-align: center; margin-left: 40px;"> </p>
<p class="imagemiddle" style="text-align: center;"><span style="font-size:20px;"></span></p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle"><span style="font-size:20px;">代码设计思路,创建一个看门狗线程,先初始化看门狗,然后在循环里面喂狗,如果 rt_thread_mdelay<1024ms喂狗则不会复位:</span></p>
<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs">
#define WDT_DEVICE_NAME "wdt" /* 看门狗设备名称 */
static rt_device_t wdg_dev; /* 看门狗设备句柄 */
static void wdt(void* pdata)
{
rt_err_t ret = RT_EOK;
rt_uint32_t timeout = 3; /* 溢出时间,单位:秒 */
char device_name;
rt_strncpy(device_name, WDT_DEVICE_NAME, RT_NAME_MAX);
/* 根据设备名称查找看门狗设备,获取设备句柄 */
wdg_dev = rt_device_find(device_name);
if (!wdg_dev)
{
rt_kprintf("find %s failed!\n", device_name);
while(1);
}
/* 设置看门狗溢出时间 */
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);
}
/* 启动看门狗 */
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);
}
while(1)
{
rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, NULL);
rt_kprintf("feed dog success!!\r\n");
rt_thread_mdelay(1000);
}
}
static int wdt_Thread_Init(void)
{
rt_thread_t thread = RT_NULL;
thread = rt_thread_create("wdt_thread", wdt, RT_NULL, 512, 10, 10);
if(thread == RT_NULL)
{
rt_kprintf("Thread_GRB Init ERROR");
return RT_ERROR;
}
rt_thread_startup(thread);
}
INIT_APP_EXPORT(wdt_Thread_Init);// 初始化线程</code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url("https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png") rgba(220, 220, 220, 0.5); top: -15px; left: 0px; display: block;"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>
<p> </p>
<p> </p>
<p><span style="font-size:20px;">但是经过测试1s喂狗也会发生复位,溢出时间1024ms按理来说不会的:</span></p>
<p class="imagemiddle" style="text-align: center;"><span style="font-size:20px;"></span></p>
<p class="imagemiddle"><span style="font-size:20px;">最后改成900ms喂就可以:误差有点大。。</span></p>
<p class="imagemiddle" style="text-align: center;"><span style="font-size:20px;"></span></p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle"><span style="font-size:20px;"> 其实在应用中我们不必创建线程喂狗,也不必这么精确控制喂狗时间,可以频繁喂狗,如果系统死机就不会喂狗就会复位达成目的了,所以可以在空闲线程喂狗,如果空闲线程没有喂狗,那么就可以判断系统死机了:</span></p>
<p class="imagemiddle"><span style="font-size:20px;">用一个钩子函数添加喂狗函数到空闲线程:</span></p>
<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs">
static void idle_hook(void)
{
rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, NULL);
rt_kprintf("feed the dog!\n ");
}
rt_thread_idle_sethook(idle_hook);</code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background:rgba(220,220,220,0.5);background-image:url(https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png)"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle"><span style="font-size:20px;">可以看到空闲线程疯狂喂狗:</span></p>
<p class="imagemiddle" style="text-align: center;"><span style="font-size:20px;"></span></p>
<p class="imagemiddle"><span style="font-size:20px;">这就可以保护系统运行了。</span></p>
<p class="imagemiddle"> </p>
<p class="imagemiddle"><span style="font-size:20px;"> </span></p>
<p class="imagemiddle"> </p>
<p class="imagemiddle"><span style="font-size:20px;">最后还要感谢中科蓝讯活动负责人的一个视频转gif的软件,真的挺好,可以直接录屏,摄像然后转gif:<a href="https://www.screentogif.com/" target="_blank">视频转gif工具</a></span></p>
<p class="imagemiddle"><span style="font-size:20px;"></span></p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p> </p>
<p>点赞,分享了这么多</p>
<p>所谓看门狗电路本质是一个定时计数器,一旦到达最大计数值就会把机器复位,比如楼主的测试1s喂狗也会发生复位</p>
<p>顺便说分享的视频转gif的软件,真的挺好</p>
Jacktang 发表于 2021-5-16 15:38
点赞,分享了这么多
所谓看门狗电路本质是一个定时计数器,一旦到达最大计数值就会把机器复位,比如楼主 ...
<p>但是如果我选了2048ms那个超时时间1s就不会,所以不知道1024ms为什么会复位,其实提前喂狗也挺好,不用卡的死死的</p> <p>谢谢分享,期待后续!</p>
页:
[1]