关于看门狗2和1的联系1的问题

> 《看门狗》一代评价如此惨败 为何还做第二代?
《看门狗》一代评价如此惨败 为何还做第二代?
发布时间:16-06-12 10:22
来源:多玩
作者:佚名
近日,育碧正式宣布了《看门狗2》的发售信息,同时会在E3展中进一步放出更多信息。而现在游戏的预告、实机演示都已经放出。
如果你有兴趣,你可以先准备好money。steam国区售价248元,黄金版售价408元,折后价368元。而PS4版本的《看门狗2》,分为三个版本:标准版,豪华版和黄金版,售价分别为59.99美元,69.99美元和99.99美元。
然而一副香港狗仔队的样子,这真的能够吸引被初代喷出翔的玩家么?
当2013年育碧放出《看门狗1》的时候,上千万新主机玩家正遇上3A大作荒(机智的育碧利用跳票大法,成功避开了GTA5与AC4)。然后再加上沙盘游戏+骇客的新鲜概念+画质牛逼的CG广告,很难让人不掏钱出来。
所以《看门狗》破了UBI的首发纪录。但是,育碧在明知道老主机性能不足,于是就不用心做,然而主机销量又是主要的利润,就故意锁死PC画质。《缩水狗》的大名,并不是浪得虚名。
这么不厚道的做法,能不喷么?
所以前一段时间,育碧CEO时不时的露脸攒人品就变得耐人寻味了,育碧总裁Yves Guillemo在曾在去年接受英国《卫报》的专访时,Guillemot指出育碧现在展示游戏的方式已经改变,他们将确保游戏在E3之类的大展上展示之前能够在目标硬件上游玩。
当我们展示一个游戏时,我们会要求团队确保它能玩,而且还要保证玩家看到的就是实际发售时的画面。这是我们从《看门狗》中获得的教训。假如目标机器带不动它,那么就会有危险。
机智的育碧!成功的甩锅给主机性能,再加上《看门狗2》自带简体中文,再加上沙盒游戏的性价比光环。
看来又能再续一作了。
关注52PK微信公众号
扫描二维码或添加微信号:love52pk 关注“52PK游戏网”
第一时间获取最火游戏激活码
最有趣游戏资讯
*网友评论仅代表其个人看法,并不表明本站同意其观点及描述。在做项目时添加看门狗一个好的办法
由于项目到后来抗干扰实验没有通过,需要加入看门狗,喂狗指令怎么加?加到什么地方比较合适?这是一个很有意思的问题,自己总结下,够后人参考。
目前有两个理论:主程序喂狗论和中断喂狗论;主程序喂狗论最大的依据就是:程序跑飞了但中断不一定会死,因为中断一般都有自己固定的中断向量地址,这个时候中断喂狗就失去了看门狗的意思。而中断喂狗论则认为:(1)只在主程序喂狗,由于中断被无意关断,那么主程序实际就只干傻喂狗功能,这种不工作也不死的 ,比死了更难受;(2)如果主程序陷入死循环,而死循环刚好又有喂狗程序,则起不到让复位的作用。
实际上无论哪种方法都不可能把所有的意外情况处理掉,我们能做的只是尽可能的处理意外事件。最好的办法就是主程序和中断相结合的方法喂狗,这个需要根据实际程序中断的特点编写相应的喂狗功能。我有两种想法实现主程序和中断相结合的办法。
(1)interrupt void ISR(void)//中断服务程序,定时周期为T
if(Dog_Save != Dog_Flag)//看门狗标志位不同表示程序在正常运行
WDT=0;//喂狗
Dog_Count=0;//用于计数
WDT=0;//喂狗
Dog_Count++;
if(Dog_Count&50)//死机50个周期后开始不喂狗
while(1);//等待看门狗使系统复位,此处也可软件复位。
Dog_Flag = 1;//看门狗标志位
...............
Dog_Flag = 2;
..............
Dog_Flag = 3;
..............
在主程序中设置许多软狗标志位,定时器中不断检测软狗标志位是否变化,以此来检测主程序是否在正常运行。从而使看门狗系统能够可靠的保证程序在异常情况下实现系统复位!
interrupt void ISR(void)//中断服务程序,定时周期为T
Dog_Count++;l
if(Dog_Count&50)//如果程序正常运行,主程序中有清0,一定会喂狗。
WDT = 0;//喂狗
while(1);//如果程序死机50个周期,开始不喂狗,等待硬件复位。
Dog_Count = 0;//在主程序中清除计数位
...............
Dog_Count = 0;
..............
Dog_Count = 0;
..............
主程序中清0相当于看门狗喂狗的条件,这样就可以实现主程序和中断相结合,最终抗干扰效果要比单一的方法好很多。2286人阅读
Android(26)
linux驱动(7)
深入分析看门狗框架
&&& 在手机Soc Chip中,里面的AP跑着linux操作系统软件,而任何软件都可能存在各种问题,如果遇到了这些异常,软件可能陷入死循环,导致手机变成“砖头”,如果没有其他硬件辅助,那么只能断电(拔电池)然后重新开机才行。为了避免出现这种情况,芯片内部增加了一个看门狗模块,这个模块专门检测CPU运行状态,只要出现卡死就复位系统。
&&& WDT全称是watchdog timer,就是看门狗模块,看门狗其实就是一个可以在一定时间内被复位的计数器。当看门狗启动后,计数器开始自动计数,经过一定时间,如果计数没有被复位,计数器达到指定数值就会发出复位信号,很多设备包括CPU接到这个信号而复位重启(俗称“被狗咬”)。为了保证看门狗不发出复位信号,就需要在看门狗允许的时间间隔内对看门狗计数器清零(俗称“喂狗”),计数器重新计数。如果系统正常并保证按时“喂狗”,那么就相安无事。一旦程序故障卡死,没有“喂狗”,系统“被咬”复位。
<span style="font-family:微软雅黑; font-size:24 color:#. 种类
&&& 嵌入式系统中主要可以分为两种类型的看门狗:
Soc芯片内部集成WDT,这是Soc常用的设计。当然PC上可能用独立的看门狗芯片。
软件模拟看门狗,只要有个timer就可以模拟。
<span style="font-family:微软雅黑; font-size:24 color:#. 结构
& & 在现有Soc芯片中,只有1个看门狗硬件模块,这个模块被包含在一个叫RGU的模块里。在早期平台中,比如MT6577,MT6575除了RGU里的WDT外,每个CPU都有一个local WDT,可以保证每个CPU不卡死。而MT6577之后就只有RGU里的WDT了,如图:
&&&& 在只有一个WDT的情况下如何保证每个CPU不卡死呢?这里需要软件设计使它都可以喂狗才行。软件设计部分将在下一章节介绍。
&&&& RGU全称是reset generation unit,在datasheet有如下框图:
&&& 可以看到WDT在RGU里只是其中一个模块,还有其他模块可以产生复位信号,比如thermal,当温度过高会触发IRQ或直接复位,这也是一种硬件保护措施。复位信号经过Mixer后会分出2个信号,grst_b会复位芯片内部模块,还有1个信号通过芯片管脚WATCHDOG复位外部芯片。有时为了debug,也可以测量WATCHDOG pin脚(正常是高电平,有复位信号时低电平),看这次重启是否是WDT等触发的。
<span style="font-family:微软雅黑; font-size:24 color:#. dual mode
&&& WDT功能,大家可以看datasheet里的寄存器介绍,比如包含了
WDT_MODE:功能开关
WDT_LENGTH:超时计数
WDT_RESTART:写该寄存器触发计数清0
WDT_STA:状态
WDT_INTAVEL:reset信号长度
WDT_SWRST:写该寄存器直接触发复位
&&& 这里介绍一个dual mode功能,通常CPU发生卡死,我们需要知道卡死位置,分析原因,然后改进,而不希望直接复位。设计的方法是:WDT超时后先不发复位信号,而是先送出IRQ(如上面的框图),WDT IRQ通常配置成CPU的FIQ,如果CPU只是软件卡死(内核死锁,中断过多等),会响应该FIQ,然后我们在FIQ里收集异常信息和CPU寄存器信息,然后再走正常的panic流程。重启后我们就有信息分析此次WDT
timeout的原因了。为了保证IRQ发出后,CPU不卡死,WDT再次计时,如果在panic流程又卡死了,就会由WDT发出复位信号复位。
&&& 简单讲:WDT超时先发出IRQ,WDT重新计时,如果再次超时WDT直接发出复位信号。可以看到WDT超时后分2个阶段,第1阶段发出IRQ用于收集异常信息,第2阶段直接复位。通常我们在第1阶段就完成异常信息收集并通过WDT_SWRST寄存器完成复位,而不用等到第2阶段的。这种情况我们称为HWT(Hardware
Watchdog Timeout)
&&& 事实上任何事情总有意外,比如CPU因为PMIC提供的电压低,或硬件故障等原因导致WDT超时发出的IRQ在CPU端得不到响应,WDT只能通过第2阶段复位芯片。这种情况我们称为HW reboot。HW reboot通常和硬件有较大关系。比如:
硬件故障,电压或频率异常
上一章节有讲Soc芯片内部只有1个WDT模块,但CPU有多颗,为了保证每个CPU卡死都可以顺利复位,就必须借助软件。WDT本质是个计数器并且支持dual mode,目前我们将超时时间(第1阶段超时)设定为30s,在发出IRQ之后超时时间(第2阶段超时)不可设定,各个平台可能不一样,一般在30s~60s之间。
&&& 配置好后,还需要设计喂狗模块,这是重中之重。流程如下:
bit位代表CPU的喂狗状态:CPU核数每个平台都不太一样,我们用bit位代表1个CPU,比如4个CPU就用4个bit,我们用kick_bit变量表示。
喂狗进程负责喂狗:在喂狗模块初始化时针对每个CPU创建的对应的内核实时进程(优先级最高)并绑定到对应的CPU上(也就是说这个进程只运行在指定CPU上,不会发生迁移),这些进程喂狗(其实就是将kick_bit对应的bit位置1而已,并没有真正喂狗)后进入睡眠,喂狗间隔是20s,如此循环反复。
真正喂外部WDT狗:任何一个喂狗进程在喂狗之后,会检查kick_bit变量,如果该&#20540;等于cpus_kick_bit变量(这个变量的每个bit代表对应CPU online情况,如果CPU online,对应bit置1),表示所有CPU都已喂狗,这时才真正喂外部WDT狗,同时将kick_bit清0,进入下一轮喂狗流程,如此循环反复。
&&& 用一张框图总结上面的流程(以4核CPU为例):
&&& 这里的wdtk-x就是对应CPU的喂狗进程。以上的一套设计可以保证各个CPU卡死都可以通过看门狗复位。
&&& 喂狗间隔是20s,而超时时间是30s,也就是说最长能容忍卡住的时间是10s(卡一小会还是可以的),超过这个时间,系统就会复位了。这里还有问题,由于喂狗进程之间没有同步,是否有可能存在刚开始一起喂狗,之后渐渐出现先后呢?误差肯定有的,但在任何30s时间里,喂狗进程都会喂1次狗的(因为喂狗间隔20s,每个CPU肯至少会喂1次狗)。而只要CPU卡死超过10s就复位了。
&&& 多核CPU不可能一直都是online,系统会根据负载做hotplug,在某颗CPU power down/power up时,会更新cpus_kick_bit变量并将kick_bit变量清0,同时喂外部WDT狗。
&&& 当只剩1个CPU时,并且该CPU要进入睡眠,此时kernel进入suspend状态,WDT模块当然也要关闭的,唤醒时再重启开启。那睡眠后的流程卡死怎么办?那已超出WDT管辖的范围了,需要用其他硬件保证,不在该文章讨论范围。
WDT驱动分布
&&&&android系统中,启动分好几个阶段:preloader、lk、kernel、android。因此每个阶段都要配置WDT,才能保证不卡死。这里我们介绍kernel阶段的WDT驱动,其他阶段是类&#20284;的。
kernel WDT驱动
&&&&这里我们没有用到kernel原生的WDT驱动,而是前面章节讲的那套机制。具体代码位置:
&&& alps/kernel-3.10/drivers/misc/mediatek/wdt/$platform/mtk_wdt.c。下面我们以L1.MP6的MT6752的wdt驱动做讲解。
&&& 流程是:()
&&& 在()函数里,做了如下几件事:
注册WDT IRQ处理函数(),kernel本身是没有使用FIQ的,因此WDT
FIQ发生时一定会被处理,除非FIQ被关闭或硬件故障了。由于64bit kernel默认支持ATF(ARM Trusted Firmware),FIQ为security interrupt,kernel是无法处理security interrupt的,因此FIQ会路由到ATF里处理。在后面的流程中会详细介绍。
设定WDT超时时间30s。
调用()初始化WDT,这里打开的dual
&&& 这样就完成WDT的初始化了,WDT初始化是比较早的,基本上3s内就完成了(kernel时间)。以下是72KK版本的uart log中搜索wdt结果:
&&& 在系统进入睡眠时,WDT要被关闭,不过不是在WDT suspend里关闭WDT,因为suspend不是睡眠最后的步骤。这里会在sleep模块通过调用WDK的wd_suspend_notify()来间接调用mtk_wd_suspend()来关闭WDT的。同理唤醒时也是早于resume流程就被sleep模块通过WDK的resume_notify()调用mtk_wd_resume()重新启动WDT。
&&& 系统重启(比如adb reboot)是通过WDT来完成复位的,在驱动里提供了()函数,这个函数通过写WDT_SWRST寄存器完成软件复位。基本上重启的log都长这样:
&&& 红线以上是正常的log,写完WDT_SWRST寄存器基本就复位了,但有些平台并不是立即生效,需要过几百毫秒才完成复位,因此有可能看到红线以下的log,这是正常的。&
&&& WDT启动后就开始计时了,如果没人喂狗就会触发FIQ,然后在硬复位。因此需要提供了()函数,调用一次就将计数清0。
&&& 如果有驱动需要长时间关中断运行,比如开机时的TP固件升级,就需要在里面添加喂狗动作,防止HWT。
&&& 有时为了调试,我们需要关闭看门狗,驱动里也提供了开启/关闭函数:()。如果你要关闭WDT,可以直接在代码里调用这个函数,那么WDT就永久关闭了。
&&& 在WDK驱动里还提供了用户接口,可以很方便在adb shell里关闭/打开WDT。
&&& WDT驱动比较简单,基本都是控制WDT硬件寄存器达到所需效果。重点还在于WDK驱动(喂狗模块)。
&&& wdk是喂狗模块,由于只有一个WDT,而需要保护多个CPU不卡死,根据前面设计的原理来设计wdk驱动,驱动具体位置:
&&& kernel-3.10/drivers/misc/mediatek/wdk,里面主要有wd_common_drv.c/wd_api.c
&&& wd_api.c负责对外接口,wd_common_drv.c负责喂狗工作。
&&&()可以获取到通用的wdk
api结构体,里面提供了WDT和WDK所需的操作。使用方法如下(手动喂狗):
&&& 下面介绍常用的几个api函数:
&&& 流程1:()
=& ()。完成cpus_kick_bit、kick_bit这2个重要变量初始化。cpus_kick_bit表示需喂狗CPU位图,kick_bit表示已喂狗CPU位图,每个bit对应CPU。
&&& 流程2:()
=& ()、()、()、(&)。
通过()创建了sysfs文件系统节点。
通过()创建per
CPU的喂狗进程wdtk-x,这些进程都是系统中优先级最高的进程,执行的核心函数是(),里面实现了前面提到的喂狗框架。
通过()创建了proc文件系统节点/proc/wdk。我们可以通过它来设定超时时间、喂狗时间、打开/关闭WDT。&#26684;式如下(如关闭WDT):echo
0 20 30 0&0 & /proc/wdk
参数1:目前没用到,可以忽略,直接写0。
参数2:喂狗间隔,默认20,单位秒。
参数3:超时时间,默认30,单位秒。
参数4:目前没用到,可以忽略。
参数5:打开/关闭WDT。
根据当前online CPU状况更新cpus_kick_bit并注册CPU hotplug回调函数,因为CPU会根据负载上电/下电,因此需要及时更新cpus_kick_bit、kick_bit。
&&& 需要注意的是:
WDT初始化和WDK初始化是处于kernel初始化的不同阶段,WDT通过module_init()完成,而WDK通过late_initcall(),中间隔着各种驱动,因此如果有些驱动执行时间太长,会导致开机30s HWT的问题,这个在后面章节提到。
在KK1.MP11以前的版本启动喂狗进程时,会直接调用到kwdt_thread(),里面会设置一遍kick_bit,最后等于cpus_kick_bit然后喂WDT,但实际上第1次kick并没有累加起来,查看log:
看到所有wdk进程起来后,都会设置kick_bit(就是local_bit),但是没有累加起来,无法等于0xf,也就无法喂WDT,真正喂狗是在20s之后,从时间轴来看:
这是为什么呢?原因是()里没创建完进程,就会调用()将kick_bit清0,因此无法累加。KK1.MP11及之后的版本就没有再调用(),因此wdk初始化完就会完成第1次喂狗。
&&& ()完成喂狗动作,里面就是一个循环:
如果需要更新超时时间,则在这里调用wdt函数更新。
更新对应CPU的kick_bit,如果等于cpus_kick_bit则清除kick_bit并喂WDT。
显示UTC时间,主要用于kernel和android时间同步,这条log非常重要,如果要看android log当时对应的kernel log,就可以通过这条log找到大致的位置。由于WDK是每20s跑一次,因此这条log也是每20s输出一次,如下:[&& 25.&[thread:187][RT:]
00:10:38.35106 UTC; android time
00:10:38.35106
&&& 各个CPU的()没有同步,因此各自喂狗的时间不定,但只要喂狗间隔不超过30s就没有事。
CPU hotplug
&&& 由于有注册CPU hotplug回调函数,因此在某颗CPU上电时,会将cpus_kick_bit对应的bit置位并同时喂狗。下电时,会清除cpus_kick_bit对应bit位并同时喂狗。
如果喂狗进程没有及时喂狗,WDT就会超时触发FIQ,而分析解决HWT的问题很依赖WDT FIQ能输出什么信息。因此必须要熟悉WDT FIQ流程。32bit/64bit kernel处理FIQ方式不一样,因此要分开讲解。
<span style="font-family:微软雅黑; font-size:24 color:#bit kernel FIQ触发流程
&&& 在WDT驱动里有注册了WDT FIQ中断处理函数(),当WDT发出中断后,kernel流程如下:
__vectors_start &#43; 0x1C:这是异常向量表FIQ入口,所有FIQ中断都会导向这里。
():FIQ入口直接调用了这个函数,此时处于FIQ
mode,用独立的栈,只要还在这个独立的栈里就无法调用printk输出log,原因是printk使用了current(),会从栈底取出thread_info结构体,而该独立的栈咩有thread_info结构体。
():这个函数更新了fiq_step。后面会继续讲fiq_step内容。
():到了WDT注册的中断函数了,这里还是无法使用printk,因此只能调用()打印到buffer里。这里印出了最重要的信息kick和check(对应的kick_bit和cpus_kick_bit),比如:kick=0x,check=0x0000000f。得到kick和check就知道是哪些CPU没有喂狗了,接下来重点关注没喂狗的CPU调用栈等信息。
():这个函数首先将栈切换为当前进程栈,就可以用printk了。另外当前CPU的寄存器打印到per
CPU buffer里。最后只允许一个CPU继续往下走,其他CPU直接死循环等待重启了。
():这个函数将输出重要log
喂狗,防止超时。
停止其他CPU。
将per CPU buffer输出到last_kmsg。注意:只输出到last_kmsg,kernel log是看不到的。last_kmsg里的log如下:
cpu 0 preempt=1, softirq=0, hardirq=0
cpu 0 r0-&r10 fp ip sp lr pc cpsr orig_r0
30 40af8 40af8 c0c46a60
c08ce0fc c0c00 c0c27f3c c0c27f40 c0c27f30 c0344a1c c03444fc
cpu 0 stack [c0c27f30 c0c27fb0]
c27f40 c0344a1c cc27f6c c0c27f50 c0344a4c c03449fc
cc200 c0cd6ea8 c0c27f7c c0c27f70 c000ffdc c0344a30
c0c27fa4 c0c27f80 c0ffc4 c0c2c6 c0c200
c08c9ba8 c16ed680 c0c27fbc c0c27fa8 c08b20f8 c00917ec c46d54
cpu 0 backtrace : c0344a1c, c0344a1c,
cpu 1 preempt=0, softirq=0, hardirq=0
cpu 1 r0-&r10 fp ip sp lr pc cpsr orig_r0
如果后面流程卡住了,那么能参考的信息只有last_kmsg了,因此这个信息尤为重要。
调用mt_aee_dump_sched_traces()输出中断信息。这个信息只有eng版本才有。这个有什么用呢?HWT有一个原因是IRQ太过频繁导致,因此IRQ信息能直接看出原因
当前CPU中断信息,可以看到上次IRQ/SoftIRQ/tasklet/hrtimer/SoftTimer信息,如果HWT时调用栈在IRQ里,还可以看到该IRQ的信息,可以判断执行是否太久。
IRQ Status会印出所有中断在Dur时间段里触发次数,如果太多就有问题了(比如&1000次每秒)。
将aee wdt buffer打印到last_kmsg,之前是per CPU buffer,这次是aee wdt buffer:
kick=0x,check=0x0000000f
Qwdt at [701]
,这里才能从last_kmsg看到kick/check信息。
(),之后就是正常的die/panic流程了,所以kernel
log总能看到PC is at aee_wdt_irq_info。看到这个信息就可以判断是HWT了。
<span style="font-family:微软雅黑; font-size:24 color:#bit kernel FIQ触发流程
&&& 64bit kernel有ATF(ARM Trusted Firmware),FIQ是security interrupt,必须路由到secure world处理,之后才会返回kernel完成剩下的工作。
&&& 建议了解下ATF相关内容再来看下面的知识点。
&&& ATF初始化时就会注册WDT FIQ处理函数,该函数保存per-CPU寄存器信息并返回kernel处理。
&&& 仅有ATF的流程比较简单,由于在ATF时,屏蔽所有中断,因此WDT FIQ只能在EL1 kernel时发生,如下:
&&& 如果存在TEE OS则更复杂些,WDT FIQ可能在EL1 kernel或S-EL1 TEE OS触发,最后都会路由到S-EL1 OS处理,然后再返回ATF,最后到EL1 kernel,如下:
&&& 除了底层流程不一样外,kernel流程是差不多的,aee_wdt_atf_info()等效于aee_wdt_irq_info()。因此可以参考上面的内容。
&&&kernel发生异常或HWT,当时的系统是不稳定的,无法保证panic或上面的WDT FIQ流程能顺利走完。因此我们使用fiq step标记走到了哪里,如上面的WDT fiq流程里,基本上每走几步就通过aee_rr_rec_fiq_step()记录特定的数字。在db解开后的SYS_REBOOT_REASON、SYS_LAST_KMSG和__exp_main.txt都会有fiq
step以供查看,如下:
WDT status: 2 fiq step: 41& exception type: 1
&&& 详情可参考:[FAQ14332]SYS_LAST_KMSG里的hw_status和fiq step的含义。
&&& 一般kernel异常,fiq step都不为0,为0表示CPU没有走到这些步骤当中,可能是没异常或CPU卡死跑不了代码。
&&& 请结合代码理清一遍流程,知道哪条log从哪个函数打印出来。如果需要加log调试,也知道该加在哪个位置。
&&& 学完WDT/WDK相关内容并不代表就可以独立解决HWT/HW REBOOT的问题了,还需要很多kernel基础知识支撑才行,因为任何模块都不是独立存在,在后面的案例分析就会有更深刻的体会了。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:44235次
排名:千里之外
原创:10篇
转载:45篇
(1)(2)(1)(1)(1)(2)(1)(3)(1)(3)(1)(2)(2)(3)(10)(5)(3)(1)(1)(1)(1)(1)(1)(5)(1)(1)}

我要回帖

更多关于 看门狗出现了一个问题 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信