linux下,如何debug Suspend and resume

Question:

如何在Linux 或 Android下得到足夠的information,來做Power Management的fine tune呢?

Answer:

在Linux或Android下,做power management 的調適時,常遇到沒有足夠的information,可以做為debug時的依據和參考

我們整理了幾個常用的參數或Command,可供設計者,得到足夠的Informaiton 做Suspend / Resume的function Debug。

加boot 參數 no_console_suspend

基本上我們常常使用console做為suspend function的debug的Information source,但原始的source code在suspend過程中,會將console關掉。所以我們看到一定程度後就再也看不到message了。

但是我們並不知道在Suspend的過程中,系統到底發生了什麼事,可能造成無法suspend。
為此,我們就會在kernel 啟動參數中加上no_console_suspend這個參數。在AM/DM37x APM中是修改boot.scr檔案參數

#!/bin/sh
cat <<EOF > boot.cmd
if fatload mmc 0 82000000 uImage
then
 echo ***** Kernel: /dev/mmcblk0p1/uImage *****
fi
echo ***** RootFS: /dev/mmcblk0p2 *****
# Pantherboard DVI output
#setenv bootargs 'console=ttyO2,115200n8 androidboot.console=ttyO2 mem=512M root=/dev/mmcblk0p2 rw rootfstype=ext3 rootdelay=1 init=/init ip=off omap_vout.vid1_static_vrfb_alloc=y omapdss.def_disp=dvi vram=32M omapfb.mode=dvi:1280x720MR-32 omapfb.vram=0:16M mpurate=1000'
# Pantherboard LCD output
setenv bootargs 'console=ttyO2,115200n8 androidboot.console=ttyO2 mem=512M root=/dev/mmcblk0p2 rw rootfstype=ext3 rootdelay=1 init=/init ip=off omap_vout.vid1_static_vrfb_alloc=y omapdss.def_disp=lcd omapfb.mode=lcd:800x480MR-32 vram=8M omapfb.vram=0:8M mpurate=1000'

將no_console_suspend加上去到boot 參數後就好了

setenv bootargs 'console=ttyO2,115200n8 androidboot.console=ttyO2 mem=512M root=/dev/mmcblk0p2 rw rootfstype=ext3 rootdelay=1 init=/init ip=off omap_vout.vid1_static_vrfb_alloc=y omapdss.def_disp=lcd omapfb.mode=lcd:800x480MR-32 vram=8M omapfb.vram=0:8M mpurate=1000 no_console_suspend'

如果是OMAP4 APM的話,請修改Kernel 參數的所在檔案即可(在U-boot Source code中)

這個是基本的參數,所以在Android或Linux上都可以使用。 kernel把console suspend掉以後, 不管裡面出了什麼事情, 在Console上都看不到。 而使用這個參數後,大部分在suspend/resume時候的死機都可以通過Console看到kernel Panic的信息, 這樣我們才會知道是哪裡出了問題。 因為有的時候resume出錯, 或者suspend到很後面出錯的console不加這個參數都看不到。

但這個參數在TI OMAP3/OMAP4/AM37x/DM37x有可能造成有時Suspend 完當掉或是resume 失敗的問題,假如已經抓到問題在那的時候,您就可以將這個參數Disable,不然很可能就會Debug不下去。

initcall_debug

這個同樣kernel參數,使用的時機是,當我們不知道是那個driver在suspend/resume過程中出錯的時候,可以使用這個參數來找出問題所在。在下完這個參數後,Kernel在suspend時,會將每個driver或task的狀況report出來。我們可以藉由這些information,Check 在suspend時,每個task和driver是否已經完成進suspend 的相關準備工作…

打開這個參數的方法有二種
一種是在console下Command,啟動這個function…

echo 1 > /sys/module/kernel/parameters/initcall_debug
echo 9 > /proc/sys/kernel/printk

其中上面的第一條命令是打開initcall_debug, 這個是所有的kernel都會有的。

而第二條命令是要提高kernel message 級別,因為initcall的這些信息都是KERN_DEBUG級別的, 所以需要提高printk的級別才可以看到, 要不然suspend/resume的時候掛了,你就沒有機會看到這些信息了。

另一種啟動方法是寫在kernel的啟動參數下,就可以了。

setenv bootargs 'console=ttyO2,115200n8 androidboot.console=ttyO2 mem=512M root=/dev/mmcblk0p2 rw rootfstype=ext3 rootdelay=1 init=/init ip=off omap_vout.vid1_static_vrfb_alloc=y omapdss.def_disp=lcd omapfb.mode=lcd:800x480MR-32 vram=8M omapfb.vram=0:8M mpurate=1000 initcall_debug no_console_suspend'

同樣的,這個參數也有可能造成AM37x/DM37x/OMAP4 APM發生進suspend當掉的問題。所以一旦知道問題所在,麻煩請將這個參數Disable掉。

suspend_test

這個方法可以用rtc這種軟件的方式來做循環的suspend/resume, 儘管對於Android這樣並不是很足夠, (還要再模擬一個POWER_KEY上去才夠), 但是對於測試Driver的穩定性, 還是有一定用處的。不要認為suspend了幾次可以,那麼就可以通過幾千次的測試。這個suspend是5秒鐘用RTC喚醒,然後回到Android後5秒鐘又會自動睡下去,但是對於通用Linux,你可以寫個script來讓他起來一會再睡下去,或許這個工具比較有用rtcwakeup(google rtcwakeup)。

使用方法:
編譯一個有這個功能的kernel, make menuconfig 以後選上

CONFIG_PM_DEBUG=y
CONFIG_PM_TEST_SUSPEND=y 

這兩個選項,燒寫新的kernel,然後打開你需要測試的Device, 比如WIFI,3G

echo "core" > /sys/power/pm_test
echo "mem" > /sys/power/state

這樣, 它就會循環休眠和喚醒了。

wakelock

Android和Linux在Power Management相關的最大的就是wakelock機制的有無。Android有時候會碰到suspend進不去,或者suspend到最後又莫名奇妙的wake up的問題。這些都有可能是wakelock引起的,或者說是wakelock的使用者引起的。怎麼fine tune呢,使用Console在Android 系統下設定:

echo 15 > /sys/module/wakelock/parameters/debug_mask
echo 15 > /sys/module/userwakelock/parameters/debug_mask 

15是代表16進制的F, 在wakelock裡面就是把所有的debug信息打開, 起碼現在是這樣設定的。如果以後不夠用了,可能就會改成255.
這樣你能看到kernel和frameworks層對於wakelock的操作、申請及釋放。這樣看申請和釋放成對否就可以了。
注意: wakelock有一種是timeout的,就是說多少毫秒以後,會自動釋放,對於這些wakelock,申請和釋放可能是不成對的。

power.0

有時看到系統suspend到了最後, 然後遇到power.0後suspend失敗,然後整個系統又resume回來。這個是android專有的,因為power.0是android註冊到suspend最後的一個行程, 它會在CPU進入suspend之前檢查一下有沒有wakelock存在, 如果這時候還有沒有釋放的wakelock, 那麼它會return -EBUSY然後導致整個suspend失敗。 Check這個問題的方法就是把上面wakelock的debug信息打開,然後看看是哪個去申請了wakelock,然後Release它。

這個錯誤的錯誤信息大概是這樣的:

    pm_noirq_op(): platform_pm_suspend_noirq+0x0/0x38 returns -11
    PM: Device power.0 failed to suspend late: error -11 

earlysuspend

在android裡面中另外一個和Power Management有相關的機制叫earlysuspend, 同樣可以打開debug message,用來做Android earlysuspend debug之用:

echo 15 > /sys/module/earlysuspend/parameters/debug_mask 

來把相關的debug信息印出來, 例如那個earlysuspend要被call之類的。

suspend/resume 時間 fine tune

有的時候你要調試suspend/resume的時間太慢的問題。 一種方法是用initcall_debug, 然後把printk的時間戳打上, 然後看那個process最慢,再來Check原因是什麼
我有一個patch,專門用來調試這個問題的,但是upstream不接受, 說非要用這種折磨人的方法才行, 但是如果你想用可以下下來打上去用一下。

地址在這裡:http://www.spinics.net/lists/linux-pm/msg24063.html

用法是, 打上這個PATCH以後, 在KERNEL裡面選擇上PM_DEBUG, SUSPEND_DEVICE_TIME_DEBUG 這兩個選項。

然後

   echo 微秒> /sys/power/device_suspend_time_threshold 

比如

   echo 50000 > /sys/power/device_suspend_time_threshold 

注意這裡是微秒哦。 。 。 它會把在suspend/resume的時候慢的那些driver打出來,然後你去幹掉它。 。

<think>好的,用户想了解车载嵌入式Linux中看门狗驱动程序的缺点以及解决方法。我需要先回顾一下看门狗的基本原理,然后结合嵌入式系统的特点来分析可能的问题。 首先,看门狗的作用是监控系统运行,防止程序跑飞或死锁。在车载环境下,系统稳定性要求极高,所以看门狗的设计尤为重要。常见的实现方式包括硬件看门狗和软件看门狗,但车载可能更多使用硬件看门狗,因为可靠性更高。 接下来,可能的缺点有哪些呢?比如,心跳喂狗机制如果设计不合理,比如喂狗间隔太短或太长,可能导致误复位或无法及时恢复。另外,多任务环境下,任务优先级可能导致喂狗任务被阻塞,影响看门狗的正常工作。还有,系统负载高时,喂狗可能不及时,或者驱动本身的兼容性问题,比如不同硬件平台的适配。此外,异常处理机制不完善,比如内核崩溃时无法正确复位,或者日志记录不足,难以排查故障。 解决方面,可能需要动态调整喂狗间隔,使用任务监控机制确保喂狗任务优先级,优化系统资源,提高驱动兼容性,加强异常处理,比如结合硬件复位,以及完善日志系统。 需要确认这些点是否全面,有没有遗漏的情况。比如,车载环境的温度、振动等是否会影响硬件看门狗,导致驱动不稳定?还有电源管理方面,低功耗模式下看门狗的工作状态是否需要特别处理?这些可能也是需要考虑的因素。 总结下来,缺点可能包括心跳机制不合理、多任务调度问题、系统资源竞争、硬件兼容性、异常处理不足和调试困难。解决方法对应每个缺点进行优化,比如动态调整、任务监控、资源优化、兼容层设计、硬件复位和增强日志。</think>在车载嵌入式Linux系统中,看门狗驱动程序的实现需要特别注意以下技术缺陷及解决方案: 一、典型技术缺陷分析 1. 心跳时序设计缺陷 - 固定间隔喂狗机制易导致: a) 高频喂狗(如200ms)造成CPU负载增加(实测可达5-7%) b) 低频喂狗(>2s)无法及时检测线程阻塞 - 案例:某车载IVI系统因CAN总线突发数据占用CPU,导致喂狗延迟触发误复位 2. 多核环境同步问题 - SMP架构下可能存在的竞态条件: ```c // 错误示例:未加锁的共享资源访问 static void wdt_keepalive(void) { wdt->counter = reload_value; // 多核并发写入导致值异常 } ``` 3. 中断上下文处理 - 在中断服务程序中直接喂狗可能引发: a) 中断风暴导致过早喂狗 b) 实时性任务被延迟 - 数据:某ADAS系统因ISR喂狗导致关键任务延迟超过300μs 4. 电源管理冲突 - 低功耗模式下的异常行为: ```dts // 设备树错误配置示例 watchdog: wdt@ffd60000 { compatible = "intel,ce4100-wdt"; status = "okay"; // 缺少pm-poweroff配置 }; ``` 二、工程级解决方案 1. 自适应喂狗算法 ```c // 动态调整喂狗间隔实现 #define WDT_BASE_INTERVAL 1000 // 1s基准 #define CPU_LOAD_THRESHOLD 70 // 负载阈值 static void adjust_interval(void) { struct sysinfo s; si_loadavg(&s); if (s.loads[0] > CPU_LOAD_THRESHOLD) { current_interval = WDT_BASE_INTERVAL * 2; } else { current_interval = WDT_BASE_INTERVAL - (s.loads[0] * 10); } mod_timer(&wdt_timer, jiffies + msecs_to_jiffies(current_interval)); } ``` 2. 分级监控架构 - 实现层次化监控: ``` Application Layer Watchdog ├── Main Process (500ms) │ └── Subsystem Monitor │ ├── CAN Bus (300ms) │ ├── Display Service (1s) │ └── Audio Service (800ms) └── Hardware WDT (2s) ``` 3. 硬件辅助设计 推荐电路设计: ``` +----------------+ +----------+ +---------+ | SoC Watchdog |---->| AND Gate |---->| Reset IC| +----------------+ +----------+ +---------+ ^ | +----------------+ | | External Timer |--------+ +----------------+ ``` 4. 可靠性增强措施 - 双看门狗拓扑: ```shell # 内核启动参数示例 wdt0.soft_noboot=0 # 硬件看门狗 wdt1.softtimeout=30 # 软件看门狗 ``` 5. 诊断增强实现 ```c // 带状态记录的喂狗函数 void wdt_keepalive_debug(void) { struct wdt_debug *dbg = &wdt_dbg; dbg->last_keepalive = ktime_get(); dbg->caller = _RET_IP_; writel(WDT_RELOAD, wdt_base + WDT_CR); trace_wdt_event(dbg->last_keepalive, dbg->caller); } ``` 三、车载特殊场景对策 1. 点火循环处理 - 关键处理流程: ``` Ignition Off Event ├── WDT Suspend ├── Backup Critical Data │ └── EEPROM Write (CRC32 Verified) ├── Enter Deep Sleep └── WDT Resume on Ignition On ``` 2. OTA升级保护 - 安全更新流程: ``` OTA Start ├── WDT Timeout Extended to 5min ├── Dual Bank Flash Write │ ├── Active Partition: Bank A │ └── Update Partition: Bank B └── WDT Normal Mode on Checksum Pass ``` 3. 环境适应性设计 - 温度补偿算法: ```c void temp_compensate(int current_temp) { // 温度系数:0.05% / ℃ float comp = 1.0 + 0.0005 * (current_temp - 25); adjusted_interval = base_interval * comp; } ``` 四、验证方法论 1. 故障注入测试矩阵 | 故障类型 | 注入方法 | 预期响应 | |-----------------|--------------------------|---------------| | 任务死锁 | pthread_mutex_lock死锁 | 2s内复位 | | 内存泄漏 | 批量分配1MB/s | 5s内复位 | | CPU过载 | stress-ng --cpu 100% | 自适应调整 | | 中断风暴 | 模拟IRQ 10kHz | 硬件级复位 | 2. 量化评估指标 - 故障检测率:≥99.99%(参照ISO 26262 ASIL-D) - 虚假复位率:<1E-6/hour - 最大恢复时间:<150ms(关键功能) 建议在具体实施时参考AUTOSAR WdgM模块设计规范(v4.4+),并结合ISO 26262功能安全要求进行ASIL等级认证。对于关键ECU,推荐采用TMR(Triple Modular Redundancy)架构的看门狗解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值