正点原子第52章。
基础知识
正点原子教程
fmql-dts
代码
APP代码(不需要编写驱动代码)
static int dw_wdt_drv_probe(struct platform_device *pdev)
{struct device *dev = &pdev->dev;struct watchdog_device *wdd;struct dw_wdt *dw_wdt; /* 描述SDWT设备 */struct resource *mem;struct dw_wdt_of_data *of_data = NULL;int ret;/* 实例化wdt对象 */ dw_wdt = devm_kzalloc(dev, sizeof(*dw_wdt), GFP_KERNEL);if (!dw_wdt)return -ENOMEM;/* 获取SWDT的寄存器基地址(物理地址)* 并将其转换为内核当中操作使用的虚拟地址* 将其存放在dw_wdt->regs中*/mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);dw_wdt->regs = devm_ioremap_resource(dev, mem);if (IS_ERR(dw_wdt->regs))return PTR_ERR(dw_wdt->regs);/* 获取输入时钟 */dw_wdt->clk = devm_clk_get(dev, NULL);if (IS_ERR(dw_wdt->clk))return PTR_ERR(dw_wdt->clk);/* 使能时钟 */ret = clk_prepare_enable(dw_wdt->clk);if (ret)return ret;/* 获取时钟频率 */dw_wdt->rate = clk_get_rate(dw_wdt->clk);if (dw_wdt->rate == 0) {ret = -EINVAL;goto out_disable_clk;}dw_wdt->rst = devm_reset_control_get_optional_shared(&pdev->dev, NULL);if (IS_ERR(dw_wdt->rst)) {ret = PTR_ERR(dw_wdt->rst);goto out_disable_clk;}reset_control_deassert(dw_wdt->rst);/* 对 struct watchdog_device 对象成员变量进行了初始化 */wdd = &dw_wdt->wdd;wdd->info = &dw_wdt_ident;wdd->ops = &dw_wdt_ops;wdd->min_timeout = 1;wdd->max_hw_heartbeat_ms =dw_wdt_top_in_seconds(dw_wdt, DW_WDT_MAX_TOP) * 1000;wdd->parent = dev;/* 调用函数:* 初始化WDT*/watchdog_set_drvdata(wdd, dw_wdt); watchdog_set_nowayout(wdd, nowayout); // 设置WDT status为WDOG_NO_WAY_OUTwatchdog_init_timeout(wdd, 0, dev); // 超时时间值/** If the watchdog is already running, use its already configured* timeout. Otherwise use the default or the value provided through* devicetree.*/if (dw_wdt_is_enabled(dw_wdt)) {wdd->timeout = dw_wdt_get_top(dw_wdt);set_bit(WDOG_HW_RUNNING, &wdd->status);} else {wdd->timeout = DW_WDT_DEFAULT_SECONDS;watchdog_init_timeout(wdd, 0, dev);}platform_set_drvdata(pdev, dw_wdt);watchdog_set_restart_priority(wdd, 128);/* 向看门狗核心层注册一个WDT设备 */ret = watchdog_register_device(wdd);if (ret)goto out_disable_clk;of_data = dev_to_ofdata(&pdev->dev);if (of_data && of_data->init) {ret = of_data->init(&pdev->dev);if (ret)goto out_disable_clk;}return 0;out_disable_clk:clk_disable_unprepare(dw_wdt->clk);return ret;
}
static const struct watchdog_info dw_wdt_ident = {.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |WDIOF_MAGICCLOSE,.identity = "Synopsys DesignWare Watchdog",
};
/* options:* WDIOF_KEEPALIVEPING 支持喂狗* WDIOF_SETTIMEOUT 设置超时时间* WDIOF_MAGICCLOSE 当应用层关闭设备时,WDT不会停止运行*/static const struct watchdog_ops dw_wdt_ops = {.owner = THIS_MODULE,.start = dw_wdt_start,.stop = dw_wdt_stop,.ping = dw_wdt_ping,.set_timeout = dw_wdt_set_timeout,.get_timeleft = dw_wdt_get_timeleft,.restart = dw_wdt_restart,
};
运行测试
过一会就重启了(应该是WDT没喂狗)
- fmql的WDT时间要比设置的长一些,比如这里我设置的"set 10",理论上是10s,但是我大概计算了一下,需要30s+才会复位。
- 需要查看wdt使用的clk。
开启&定时:
重启:
重启时卡在这里。
发现sd卡的第二个分区未能成功搭载。(当时不知道为什么创建了三个分区:sdb1放启动文件,sdb3放ubuntu系统,sdb2空的)(所以只需要创建2个分区即可★★★)
WDT重启系统后
linux内核启动报错Kernel panic - not syncing: No working init found. 问题分析-CSDN博客
petalinux启动报错:Kernel panic - not syncing: No working init found. Try passing init= option to kernel.-CSDN博客
显示SD卡的某个分区未成功加载。
不可行:
之前设置好了:
尝试其他解决办法
法一:
不使用wdt,使用shell命令(如reboot)让ubuntu重启。
理论可行。
法二:
修改SD卡分区,只创建2个分区。
并且修改u-boot环境变量,设置为从mmcplk0p2启动
wdt没有喂狗后成功重启ubuntu。
- 备份ubuntu系统:(要先取消sdb3的挂载)
sudo dd if=/dev/sdb3 of=/home/sdcard_backup.img bs=4M status=progress
- 拷贝到SD卡新的分区:
sudo dd if=/home/sdcard_backup.img of=/dev/sdb2 bs=4M status=progress
setenv bootargs 'console=ttyPS0,115200 noinitrd root=/dev/mmcblk0p2 rootfstype=ext4 rootwait rw'
重启后
MobaXterm(windows)无法通过SSH连接ubuntu:
尝试中。。。
其他学习内容
kill杀掉进程
https://download.csdn.net/blog/column/11438800/137284052
buildroot配置目录
【Buildroot】学习记录(2)配置注释_buildroot配置-CSDN博客
17. Buildroot根文件系统的构建 — [野火]嵌入式Linux镜像构建与部署——基于LubanCat-i.MX6ULL开发板 文档