0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

【瑞萨RA × Zephyr评测】多线程和看门狗

枫雪天 来源:枫雪天 作者:枫雪天 2026-01-10 10:23 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

Zephyr 应用在 FPB-RA6E2 开发板上的评测:多线程与看门狗

本文章旨在评估使用 Zephyr RTOS 在 Renesas FPB-RA6E2 开发板上实现多线程调度与硬件看门狗功能的应用。评估内容包括任务调度、看门狗初始化流程、主程序逻辑的详细解析,以及实验现象与数据分析。


1. 硬件连接与引脚定义

本实验涉及的任务调度和看门狗功能不依赖特定的物理引脚,但需要确保开发板支持硬件看门狗外设。

功能物理引脚 (Pin)信号定义接线说明
看门狗内部外设WDT Timer无需外部连接

2. 软件环境配置

2.1 Device Tree Overlay

设备树用于定义硬件看门狗的初始状态。以下是关键配置:

看门狗配置

wdt: wdt@40083400 {
	compatible = "renesas,ra-wdt"; /* in externalzephyrdtsarmrenesasrara6ra6-cm33-common.dtsi:542 */
	reg = < 0x40083400 0x200 >;    /* in externalzephyrdtsarmrenesasrara6ra6-cm33-common.dtsi:543 */
	clocks = < &pclkb 0x0 0x0 >;   /* in externalzephyrdtsarmrenesasrara6ra6-cm33-common.dtsi:544 */
	status = "okay";               /* in externalzephyrboardsrenesasfpb_ra6e2fpb_ra6e2.dts:135 */
	};
	};
};

2.2 Kconfig 配置 (prj.conf)

确保启用了多线程和看门狗驱动支持:

CONFIG_MULTITHREADING=y
CONFIG_WATCHDOG=y
CONFIG_TASK_WDT=y
CONFIG_LOG=y

3. 代码逻辑分析

3.1 主程序代码(main.c)

#include < zephyr/kernel.h >
#include < zephyr/device.h >
#include < zephyr/drivers/watchdog.h >
#include < zephyr/sys/reboot.h >
#include < zephyr/task_wdt/task_wdt.h >
#include < zephyr/sys/printk.h >
#include < stdbool.h >

/*
 * To use this sample, either the devicetree's /aliases must have a
 * 'watchdog0' property, or one of the following watchdog compatibles
 * must have an enabled node.
 *
 * If the devicetree has a watchdog node, we get the watchdog device
 * from there. Otherwise, the task watchdog will be used without a
 * hardware watchdog fallback.
 */
#if DT_NODE_HAS_STATUS_OKAY(DT_ALIAS(watchdog0))
#define WDT_NODE DT_ALIAS(watchdog0)
#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_window_watchdog)
#define WDT_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(st_stm32_window_watchdog)
#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_watchdog)
#define WDT_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(st_stm32_watchdog)
#elif DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_wdt)
#define WDT_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(nordic_nrf_wdt)
#elif DT_HAS_COMPAT_STATUS_OKAY(espressif_esp32_watchdog)
#define WDT_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(espressif_esp32_watchdog)
#elif DT_HAS_COMPAT_STATUS_OKAY(silabs_gecko_wdog)
#define WDT_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(silabs_gecko_wdog)
#elif DT_HAS_COMPAT_STATUS_OKAY(nxp_wdog32)
#define WDT_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(nxp_wdog32)
#elif DT_HAS_COMPAT_STATUS_OKAY(microchip_xec_watchdog)
#define WDT_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(microchip_xec_watchdog)
#else
#define WDT_NODE DT_INVALID_NODE
#endif

static void task_wdt_callback(int channel_id, void *user_data)
{
	printk("Task watchdog channel %d callback, thread: %sn",
		channel_id, k_thread_name_get((k_tid_t)user_data));

	/*
	 * If the issue could be resolved, call task_wdt_feed(channel_id) here
	 * to continue operation.
	 *
	 * Otherwise we can perform some cleanup and reset the device.
	 */

	printk("Resetting device...n");

	sys_reboot(SYS_REBOOT_COLD);
}

int main(void)
{
	int ret;
	const struct device *const hw_wdt_dev = DEVICE_DT_GET_OR_NULL(WDT_NODE);

	printk("Task watchdog sample application.n");

	if (!device_is_ready(hw_wdt_dev)) {
		printk("Hardware watchdog not ready; ignoring it.n");
		ret = task_wdt_init(NULL);
	} else {
		ret = task_wdt_init(hw_wdt_dev);
	}

	if (ret != 0) {
		printk("task wdt init failure: %dn", ret);
		return 0;
	}


	/* passing NULL instead of callback to trigger system reset */
	int task_wdt_id = task_wdt_add(1100U, NULL, NULL);

	while (true) {
		printk("Main thread still alive...n");
		task_wdt_feed(task_wdt_id);
		k_sleep(K_MSEC(1000));
	}
	return 0;
}

/*
 * This high-priority thread needs a tight timing
 */
void control_thread(void)
{
	int task_wdt_id;
	int count = 0;

	printk("Control thread started.n");

	/*
	 * Add a new task watchdog channel with custom callback function and
	 * the current thread ID as user data.
	 */
	task_wdt_id = task_wdt_add(100U, task_wdt_callback,
		(void *)k_current_get());

	while (true) {
		if (count == 50) {
			printk("Control thread getting stuck...n");
			k_sleep(K_FOREVER);
		}

		task_wdt_feed(task_wdt_id);
		k_sleep(K_MSEC(50));
		count++;
	}
}

K_THREAD_DEFINE(control, 1024, control_thread, NULL, NULL, NULL, -1, 0, 1000);

3.2 核心流程

多线程调度

  1. 创建高优先级线程 control_thread,用于模拟实时任务。
  2. 主线程运行低优先级任务,定期喂养看门狗。
  3. 当高优先级线程卡住时,触发看门狗回调或系统复位。

看门狗流程

  1. 初始化硬件看门狗或任务看门狗。
  2. 为每个线程注册独立的看门狗通道,并设置超时时间。
  3. 定期调用 task_wdt_feed 函数喂养看门狗。
  4. 如果某个线程未能及时喂养,触发回调函数或系统复位。

3.3 关键 API 使用

以下是代码中使用的关键 API:

多线程管理

K_THREAD_DEFINE(thread_name, stack_size, entry_point, arg1, arg2, arg3, prio, options, delay);
  • thread_name: 线程名称。
  • stack_size: 线程栈大小。
  • entry_point: 线程入口函数。
  • prio: 线程优先级。

看门狗初始化

int task_wdt_init(const struct device *hw_wdt_dev);
  • hw_wdt_dev: 硬件看门狗设备句柄(可为空)。

看门狗通道管理

int task_wdt_add(uint32_t timeout_ms, task_wdt_callback_t callback, void *user_data);
void task_wdt_feed(int channel_id);
  • timeout_ms: 超时时间(毫秒)。
  • callback: 超时回调函数。
  • channel_id: 看门狗通道 ID。

4. 实验现象与数据分析

4.1 多线程调度行为

  • 主线程 : 每秒打印一次日志,表明其仍在运行。
  • 高优先级线程 : 模拟实时任务,每 50 毫秒喂养看门狗,运行 50 次后故意卡住。

终端应显示如下数据流:

*** Booting Zephyr OS build v4.2.0 ***
Task watchdog sample application.
[00:00:00.005,000] [0m< inf > wdt_renesas_ra: actual window min = 0.00 ms[0m
[00:00:00.012,000] [0m< inf > wdt_renesas_ra: actual window max = 671.00 ms[0m
[00:00:00.019,000] [0m< inf > wdt_renesas_ra: wdt timeout was set successfully[0m
Main thread still alive...
Control thread started.
Main thread still alive...
Main thread still alive...
Main thread still alive...
Control thread getting stuck...
Task watchdog channel 1 callback, thread: control
Resetting d?*** Booting Zephyr OS build v4.2.0 ***
Task watchdog sample application.
[00:00:00.005,000] [0m< inf > wdt_renesas_ra: actual window min = 0.00 ms[0m
[00:00:00.012,000] [0m< inf > wdt_renesas_ra: actual window max = 671.00 ms[0m
[00:00:00.019,000] [0m< inf > wdt_renesas_ra: wdt timeout was set successfully[0m
Main thread still alive...
Control thread started.

4.2 看门狗复位行为

  • 正常运行 : 看门狗被定期喂养,系统保持稳定。
  • 异常情况 : 高优先级线程卡住后,看门狗超时触发回调或系统复位。
  • 视觉效果 : 使用调试器观察复位信号,确认系统重启。

5. 测评总结

本程序成功演示了 Renesas RA6E2 在 Zephyr RTOS 下的多线程调度与看门狗功能。通过模拟高优先级任务卡住的场景,验证了任务看门狗对系统稳定性的保护作用。代码结构清晰,适配了最新的驱动 API,适用于初学者学习和开发者快速验证硬件功能。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6078

    文章

    45618

    浏览量

    674985
  • 看门狗
    +关注

    关注

    10

    文章

    612

    浏览量

    73302
  • 开发板
    +关注

    关注

    26

    文章

    6483

    浏览量

    121320
  • Zephyr
    +关注

    关注

    1

    文章

    62

    浏览量

    6641
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    STM32中的独立看门狗和窗口看门狗是什么

    在早期的MCU中是没有看门狗这种东西的,所以产品就很容易出现死机,跑飞的情况。为了避免这种情况的出现,后期的MCU都集成了看门狗的功能。但是目前看门狗发展到今天基本上分为两大类:独立看门狗
    的头像 发表于 02-20 17:47 4929次阅读
    STM32中的独立<b class='flag-5'>看门狗</b>和窗口<b class='flag-5'>看门狗</b>是什么

    FPB-RA6E2试用】【RA × Zephyr开发板评测】Linux环境配置和初步试用

    1. 前言 很荣幸获得了RA × ZephyrFPB-
    发表于 12-29 12:55

    FPB-RA6E2试用】【FPB-RA6E2】看门狗(Watchdog Timer, WDT)个人理解及资料整理

    FPB-RA6E2】看门狗(Watchdog Timer, WDT)个人理解及资料整理
    发表于 01-14 11:09

    FPB-RA6E2试用】Zephyr看门狗(WDT)机制

    程序卡死未按时喂狗,看门狗就会直接切断并复位MCU的电源轨,让系统重启。 在传统的裸机开发中,配置看门狗需要翻阅芯片手册,操作复杂的控制寄存器和分频器。而在Zephyr中,无论底层是
    发表于 02-20 10:35

    什么是看门狗电路

    看门狗电路 看门狗电路一般有软件看门狗和硬件看门狗两种。软件看门狗不需外接硬件电路,但系统需要出让一个定时器资源,这在许多系统中很
    发表于 10-21 01:40 8834次阅读

    stm32看门狗时间计算 独立看门狗和窗口看门狗的特性是什么

    本文为您讲解STM看门狗时间计算(时限)与频率计算,独立看门狗和窗口看门狗的特性、区别与联系。
    发表于 10-10 10:41 9457次阅读

    什么是stm32看门狗?独立看门狗和窗口看门狗工作原理解析

    stm32有两个看门狗,独立看门狗和窗口看门狗,其实两者的功能是类似的,只是喂狗的限制时间不同。 独立看门狗
    的头像 发表于 11-06 11:48 2.9w次阅读
    什么是stm32<b class='flag-5'>看门狗</b>?独立<b class='flag-5'>看门狗</b>和窗口<b class='flag-5'>看门狗</b>工作原理解析

    STM32看门狗配置(独立看门狗IWDG和窗口看门狗WWDG)

    stm32自带两个看门狗模块,独立看门狗IWDG和窗口看门狗WWDG。看门狗主要作用是可用来检测和解决由软件错误引起的故障;当计数器达到给定的超时值时,触发一个中断(仅适用于窗口型
    发表于 11-09 17:17 8946次阅读
    STM32<b class='flag-5'>看门狗</b>配置(独立<b class='flag-5'>看门狗</b>IWDG和窗口<b class='flag-5'>看门狗</b>WWDG)

    MCU独立看门狗与窗口看门狗的区别

    早期的MCU没有看门狗,就容易引起有些产品死机了不能重启工作。为了避免这个问题,后期的MCU在内部集成了看门狗的功能。为了满足更多使用场景,现在很多MCU都集成了两个看门狗:独立看门狗
    发表于 10-28 20:06 8次下载
    MCU独立<b class='flag-5'>看门狗</b>与窗口<b class='flag-5'>看门狗</b>的区别

    【奇葩-002】调教Renesas RX130独立看门狗

    RX130的看门狗,配置后必须要喂狗一次,才能激活;否则就不工作。
    发表于 12-20 19:01 7次下载
    【奇葩<b class='flag-5'>瑞</b><b class='flag-5'>萨</b>-002】调教Renesas RX130独立<b class='flag-5'>看门狗</b>

    STM32:独立看门狗、窗口看门狗的配置

    STM32单片机的看门狗有独立看门狗和窗口看门狗之分,这两者的工作原理却完全不同。
    发表于 02-08 16:15 18次下载
    STM32:独立<b class='flag-5'>看门狗</b>、窗口<b class='flag-5'>看门狗</b>的配置

    STM32中的独立看门狗和窗口看门狗

    一、前言 在早期的MCU中是没有看门狗这种东西的,所以产品就很容易出现死机,跑飞的情况。为了避免这种情况的出现,后期的MCU都集成了看门狗的功能。但是目前看门狗发展到今天基本上分为两大类:独立
    的头像 发表于 12-22 16:58 3449次阅读

    STM32中的独立看门狗和窗口看门狗

    在早期的MCU中是没有看门狗这种东西的,所以产品就很容易出现死机,跑飞的情况。为了避免这种情况的出现,后期的MCU都集成了看门狗的功能。但是目前看门狗发展到今天基本上分为两大类:独立看门狗
    的头像 发表于 01-30 14:38 2799次阅读
    STM32中的独立<b class='flag-5'>看门狗</b>和窗口<b class='flag-5'>看门狗</b>

    e2studio----独立看门狗IWDT

    概述本篇文章主要介绍如何使用e2studio对进行独立看门狗IWDT配置,并且配置RTC时钟产生1s的周期中断,通过串口打印查看独立看门狗IWDT的计数值。
    的头像 发表于 11-26 17:18 2736次阅读
    <b class='flag-5'>瑞</b><b class='flag-5'>萨</b>e2studio----独立<b class='flag-5'>看门狗</b>IWDT

    e2studio----看门狗WDT

    本篇文章主要介绍如何使用e2studio对进行看门狗WDT配置,并且配置RTC时钟产生1s的周期中断,通过串口打印查看看门狗WDT的计数值。
    的头像 发表于 12-02 17:54 3133次阅读
    <b class='flag-5'>瑞</b><b class='flag-5'>萨</b>e2studio----<b class='flag-5'>看门狗</b>WDT