【嵌入式开发】ARM 看门狗 Watchdog ( 看门狗概念

您所在的位置:网站首页 看门狗模式举例 【嵌入式开发】ARM 看门狗 Watchdog ( 看门狗概念

【嵌入式开发】ARM 看门狗 Watchdog ( 看门狗概念

2024-07-16 13:09| 来源: 网络整理| 查看: 265

一. 看门狗 简介 1. 看门狗 简介 (1) 看门狗作用(2) 看门狗 工作方式(3) 看门狗 在启动时 的 关闭策略2. 看门狗 原理 (1) 看门狗 硬件模块 原理(2) 看门狗 硬件模块 工作流程二. 看门狗 寄存器介绍 1. 看门狗 时钟 控制 寄存器 ( WTCON ) (1) 看门狗 时钟控制 寄存器 介绍(2) 看门狗 时钟控制 寄存器 详细参数解析2. 看门狗 定时器 数据 寄存器 ( WTDAT)3. 看门狗 定时器 计数 寄存器 ( WTCNT )4. 看门狗 定时器 中断清理寄存器 ( WTCLRINT )三. 关闭看门狗 汇编代码示例 1. 汇编代码编写 (1) 代码 逻辑 分析(2) 汇编代码示例2. 链接器脚本3. Makefile 编译脚本4. 编译输出可执行文件

本博客的参考文章及相关资料下载 :

1.本博客代码及参考手册下载 : https://download.csdn.net/download/han1202012/10409013一. 看门狗 简介

参考手册 : S3C6410X.pdf ( 本博客基于 6410 开发板 )

1.手册对应章节 : 34 章 WATCHDOG TIMER;2.6410芯片手册下载地址 :https://download.csdn.net/download/han1202012/104090131. 看门狗 简介(1) 看门狗作用

看门狗 作用 :

1.嵌入式产品 : 嵌入式产品在运行过程中, 经常出现各种故障, 死机 等情况, 当出现故障的时候 就需要一种纠错重启机制, 看门狗就是应对这些问题的 ; 2.看门狗本质 : 看门狗是一个 硬件模块 ; 3.主要作用 : 在 系统出现故障 死机后, 重启系统; (2) 看门狗 工作方式

看门狗 工作方式 :

1.实现定时器功能 : 看门狗 是在 硬件模块上 实现了一个定时器, 该定时器 启动后 必须在指定的时间重新开始计时;2.喂狗 : 喂狗 操作 就是 重新计时 的 形象的称呼; 3.重启机制 : 如果在规定的时间内, 没有重新开始计时 ( 喂狗 ), 那么 该硬件模块 就会 认为 系统死机, 重启系统; (3) 看门狗 在启动时 的 关闭策略

看门狗启动时 关闭 :

1.看门狗的作用周期 : 看门狗主要是在 Linux 内核运行起来之后, 操作系统 来负责 定时 重启看门狗定时器 ( 喂狗 ) ; 2.Bootloader 启动 : 在 BootLoader 引导 启动时, 此时 操作系统没有运行, 需要编写额外的代码来定时喂狗; 3.启动时关闭看门狗 : 在 BootLoader 引导启动时, 看门狗不是必须的, 关闭看门狗能省去很多麻烦; 2. 看门狗 原理(1) 看门狗 硬件模块 原理

看门狗 模块 原理 :

这里写图片描述这里写图片描述1.时钟产生模块 : PLCK 是看门狗的时钟源, 首先经过一个 8 位的 ① 预分频器 进行预分频处理 生成对应的 看门狗定时器时钟, 这个值 还要 经过一次 ② 频率分割 处理 ; ( 1 ) 看门狗控制寄存器 : 英文全称 Watchdog Timer Control Register ( WTCON ) , 该寄存器中设置 ① 预分频值 和 ② 频率分割参数; ( 2 ) 预分频器参数取值范围 : 0 ~ 2^8 - 1, 最小值 0, 最大值 2^8 - 1 ;( 3 ) 频率分割参数 : 16, 32, 64, 128 ; ( 4 ) 看门狗时钟计算公式 : PCLK 是原始时钟源, Prescaler value 是预分频器值, Division_factor 是频率分割参数 ; t\_watchdog = 1/( PCLK / (Prescaler value + 1) / Division\_factor ) 2.计数模块 : 启动看门狗前 ① 先给 看门狗的 计数器 设置一个初始值, ② 每次时钟信号到来后 这个计数器 就递减 1 操作; ( 1 ) 看门狗时钟数据寄存器 ( WTDAT ) : 英文全称 Watchdog Timer Data Register ( 简称 WTDAT ), 存放 需要递减的时钟数据的初始值 ; ( 2 ) 看门狗时钟计数寄存器 ( WTCNT ) : 英文全称 Watchdog Timer Count Register ( 简称 WTDAT ), 存放 定时器 递减的值; ( 3 ) WTCNT 初始值设置 : WTDAT 是时钟数据初始值, WTCNT 负责进行定时操作, WTCNT 的值是递减的, 需要在看门狗启动前将 WTDAT 中的初始值 设置 给 WTCNT 寄存器, 这个操作就是 喂狗 操作; 3.重启模块 : 如果 WTCNT 计数器 递减到 0 后, 没有喂狗操作, 那么就会 产生一个重启信号 传递给 处理器 通知需要进行重启操作 ; (2) 看门狗 硬件模块 工作流程

看门狗 硬件模块 工作流程 :

这里写图片描述这里写图片描述1.时钟源 PLCK : 是 芯片 通过 晶振 产生 的 ; 2.预分频 : 根据 预分频值 进行 预分频 ; 3.正式分频 : 根据 频率分割参数 进行 频率分割 ; 4.计数器计数 : 看门狗计数器 计数 操作 ; 5.根据 WTCON 中的设置 进行的操作 : ( 1 ) 如果没有关闭中断功能 : 产生中断信号 ; ( 2 ) 如果关闭了中断功能 : 产生重启信号 ; 二. 看门狗 寄存器介绍

参考手册 : S3C6410X.pdf ( 本博客基于 6410 开发板 )

1.手册对应章节 : 34 章 WATCHDOG TIMER;2.6410芯片手册下载地址 :https://download.csdn.net/download/han1202012/104090131. 看门狗 时钟 控制 寄存器 ( WTCON )(1) 看门狗 时钟控制 寄存器 介绍

看门狗 时钟 控制 寄存器 简介 :

1.英文全称 : WATCHDOG TIMER CONTROL (WTCON) REGISTER; 2.WTCON 主要功能 : ① 打开 / 关闭 看门狗 定时器, ② 从 4 个不同的时钟源中选择 时钟信号 , * ③ 打开 / 关闭 中断功能 , ④ 打开 / 关闭 看门狗 计时器输出* ; 3.看门狗重启操作 : 在系统上电后发生故障, 看门狗可以重启系统, 同时 ① 关闭 中断生成器, ② 激活 看门狗 生成重启信号的时钟输出;4.看门狗计数操作 ( 不重启 ) : 如果用户想要使用 看门狗 的普通计数功能, ① 激活 中断生成器, ② 关闭 看门狗 生成重启信号的时钟输出; (2) 看门狗 时钟控制 寄存器 详细参数解析

本博客针对 6410 开发板编写, 下面的寄存器的地址, 不同类型的开发板都有不同的地址值 寄存器地址不同的开发板是不同的 寄存器内容所有 arm 开发板 都一致

看门狗时钟控制寄存器 ( WATCHDOG TIMER CONTROL (WTCON) REGISTER ) 详细参数 :

1.看门狗时钟控制寄存器访问地址 : 在 6410 开发板中 看门狗时钟控制寄存器 的地址是 0x7E004000 ; 这里写图片描述这里写图片描述2.寄存器每个 位 的设置 : 看门狗时钟控制寄存器 有 2 字节 16位, 下面详细介绍 0 ~ 15 位 每一位的功能 ; 3.[ 0 ] 位 ( 打开 / 关闭 Reset 功能 ) : 打开 / 关闭 看门狗 用于 输出 重启信号的 看门狗定时器 ; ( 1 ) 设置 1 值 : 打开 定时器 输出功能 ; ( 2 ) 设置 0 值 : 关闭 定时器 输出功能 ; 4.[ 1 ] 位 ( 保留位 ) : 该位在常规操作中必须设置成 0 ;5.[ 2 ] 位 ( 中断开关位 ) : 打开 / 关闭 中断 功能 ; ( 1 ) 设置 1 值 : 打开中断 ; ( 2 ) 设置 0 值 : 关闭中断 ;6.[ 4 : 3 ] 位 ( 频率分割参数位 ) : 设置时钟的 预分频 后的 频率分割参数 ; ( 1 ) 设置 00 值 : 参数 为 16; ( 1 ) 设置 01 值 : 参数 为 32; ( 1 ) 设置 10 值 : 参数 为 64; ( 1 ) 设置 11 值 : 参数 为 128; 7.[ 5 ] 位 ( 打开 / 关闭 看门狗定时器 ) : 设置 打开 / 关闭 看门狗定时器 ; ( 1 ) 设置 0 值 : 关闭 看门狗 定时器 ; ( 2 ) 设置 1 值 : 打开 看门狗 定时器 ; 8.[ 7 : 6 ] 位 ( 保留位 ) : 这是保留位, 常规操作必须设置为 00 值; 9.[15 : 8] 位 ( 预分频器值 ) : 设置预分频器 值; ( 1 ) 预分频器参数取值范围 : 0 ~ 2^8 - 1, 最小值 0, 最大值 2^8 - 1 ;这里写图片描述这里写图片描述2. 看门狗 定时器 数据 寄存器 ( WTDAT)

看门狗定时器数据寄存器 : 英文全称 WATCHDOG TIMER DATA (WTDAT) REGISTER ;

1.作用 : 该寄存器用于 指定看门狗的 计数 超时时间 ; 2.WTCNT 超时时间设置 : WTDAT 寄存器的值 不会自动被加载到 看门狗 定时器 计数器中 ; 3.默认初始值 : 使用 0x8000 作为计时器 默认的 超时时间, 该值 是 WTCNT 寄存器初始值 ; 这里写图片描述这里写图片描述3. 看门狗 定时器 计数 寄存器 ( WTCNT )

看门狗定时器计数寄存器 : 英文全称 WATCHDOG TIMER COUNT (WTCNT) REGISTER ;

1.作用 : 该寄存器用于 存储 定时器 的当前的计数值; 2.初始值设置 : 当看门狗 计时器 最初工作时, WTDAT 寄存器中的值 不会自动装载入 WTCNT 寄存器中, WTCNT 寄存器 在开始工作前必须设置一个初始值; 这里写图片描述这里写图片描述4. 看门狗 定时器 中断清理寄存器 ( WTCLRINT )

看门狗定时器中断清理寄存器 : 英文全称 WATCHDOG TIMER INTERRUPT CLEAR (WTCLRINT) REGISTER ;

1.作用 : 该寄存器用于清除中断; 2.中断服务例行程序 : 该程序 负责 在 中断服务完成后 清理 相关的 中断; 3.寄存器使用方法 : 向寄存器中写入任意值, 都会清空中断 ; 4.寄存器不可读 : WTCLRINT 的值是不可读取的 ; 这里写图片描述这里写图片描述三. 关闭看门狗 汇编代码示例 1. 汇编代码编写(1) 代码 逻辑 分析

关闭看门狗 代码 逻辑 分析 :

1.定义宏保存看门狗控制寄存器地址 : 定义 看门狗 控制寄存器所在的地址, 以便访问, #define pWTCON 0x7E004000 ;2.定义调用标号 : 在 汇编 代码中定义 一个标号, 用于 标记关闭看门狗的指令 地址 , 使用 bl 指令 跳转到该标号处, 即可执行 关闭看门狗的操作, 代码 disable_watchdog : ;3.将 看门狗 控制寄存器 地址 装载 到 通用寄存器中 : 将 0x7E004000 地址 装载到通用寄存器中, 以便后面进行寻址访问 , 代码 ldr r0, =pWTCON ;4.将 立即数 0 设置到通用寄存器中 : 将 立即数 0 设置到 通用寄存器 r1 中, 该寄存器中的值是要用于赋值操作的原始值, 代码 mov r1, #0x0 ; 5.设置看门狗控制寄存器 : 寄存器 r1 中的值 存到 r0 寄存器存储的地址 对应 的内存中, 注意 要先 针对 R0 中的地址进行寻址, 然后在设置该寻址后的值, 代码 str r1, [r0] ; (2) 汇编代码示例

汇编代码示例 :

代码语言:javascript复制@**************************** @File:start.S @ @BootLoader 初始化代码 @**************************** .text @ 宏 指明代码段 .global _start @ 伪指令声明全局开始符号 _start: @ 程序入口标志 b reset @ reset 复位异常 ldr pc, _undefined_instruction @ 未定义异常, 将 _undefined_instruction 值装载到 pc 指针中 ldr pc, _software_interrupt @ 软中断异常 ldr pc, _prefetch_abort @ 预取指令异常 ldr pc, _data_abort @ 数据读取异常 ldr pc, _not_used @ 占用 0x00000014 地址 ldr pc, _irq @ 普通中断异常 ldr pc, _fiq @ 软中断异常 _undefined_instruction: .word undefined_instruction @ _undefined_instruction 标号存放了一个值, 该值是 32 位地址 undefined_instruction, undefined_instruction 是一个地址 _software_interrupt: .word software_interrupt @ 软中断异常 _prefetch_abort: .word prefetch_abort @ 预取指令异常 处理 _data_abort: .word data_abort @ 数据读取异常 _not_used: .word not_used @ 空位处理 _irq: .word irq @ 普通中断处理 _fiq: .word fiq @ 快速中断处理 undefined_instruction: @ undefined_instruction 地址存放要执行的内容 nop software_interrupt: @ software_interrupt 地址存放要执行的内容 nop prefetch_abort: @ prefetch_abort 地址存放要执行的内容 nop data_abort: @ data_abort 地址存放要执行的内容 nop not_used: @ not_used 地址存放要执行的内容 nop irq: @ irq 地址存放要执行的内容 nop fiq: @ fiq 地址存放要执行的内容 nop reset: @ reset 地址存放要执行的内容 bl set_svc @ 跳转到 set_svc 标号处执行, 设置 svc 工作模式 bl disable_watchdog @ 跳转到 disable_watchdog 标号执行, 关闭看门狗 set_svc: mrs r0, cpsr @ 将 CPSR 寄存器中的值 导出到 R0 寄存器中 bic r0, r0, #0x1f @ 将 R0 寄存器中的值 与 #0x1f 立即数 进行与操作, 并将结果保存到 R0 寄存器中, 实际是将寄存器的 0 ~ 4 位 置 0 orr r0, r0, #0xd3 @ 将 R0 寄存器中的值 与 #0xd3 立即数 进行或操作, 并将结果保存到 R0 寄存器中, 实际是设置 0 ~ 4 位 寄存器值 的处理器工作模式代码 msr cpsr, r0 @ 将 R0 寄存器中的值 保存到 CPSR 寄存器中 #define pWTCON 0x7e004000 @ 定义看门狗控制寄存器 地址 ( 6410开发板 ) disable_watchdog: ldr r0, =pWTCON @ 先将控制寄存器地址保存到通用寄存器中 mov r1, #0x0 @ 准备一个 0 值, 看门狗控制寄存器都设置为0 , 即看门狗也关闭了 str r1, [r0] @ 将 0 值 设置到 看门狗控制寄存器中 2. 链接器脚本

gboot.lds 链接器脚本 代码解析 :

1.指明输出格式 ( 处理器架构 ) : 使用 OUTPUT_ARCH(架构名称) 指明输出格式, 即处理器的架构, 这里是 arm 架构的, OUTPUT_ARCH(arm) ;2.指明输出程序的入口 : 设置编译输出的程序入口位置, 语法为 ENTRY(入口位置), 在上面的 Start.S 中设置的程序入口是 _start, 代码为 ENTRY(_start) ;3.设置代码段 : 使用 .text : 设置代码段; 4.设置数据段 : 使用 .data : 设置数据段;5.设置 BSS 段 : 使用 .bss : 设置 BSS 段; ( 1 ) 记录 BSS 段的起始地址 : bss_start = .; ;( 2 ) 记录 BSS 段的结束地址 : bss_end = .; ;6.对齐 : 每个段都需要设置内存的对齐格式, 使用 . = ALIGN(4); 设置四字节对齐即可;7.代码示例 : 代码语言:javascript复制OUTPUT_ARCH(arm) /*指明处理器结构*/ ENTRY(_start) /*指明程序入口 在 _start 标号处*/ SECTIONS { . = 0x50008000; /*整个程序链接的起始位置, 根据开发板确定, 不同开发板地址不一致*/ . = ALIGN(4); /*对齐处理, 每段开始之前进行 4 字节对齐*/ .text : /*代码段*/ { start.o (.text) /*start.S 转化来的代码段*/ *(.text) /*其它代码段*/ } . = ALIGN(4); /*对齐处理, 每段开始之前进行 4 字节对齐*/ .data : /*数据段*/ { *(.data) } . = ALIGN(4); /*对齐处理, 每段开始之前进行 4 字节对齐*/ bss_start = .; /*记录 bss 段起始位置*/ .bss : /*bss 段*/ { *(.bss) } bss_end = .; /*记录 bss 段结束位置*/ } 3. Makefile 编译脚本

makefile 文件编写 :

1.通用规则 ( 汇编文件编译规则 ) : 汇编文件 编译 成同名的 .o 文件, 文件名称相同, 后缀不同, %.o : %.S, 产生过程是 arm-linux-gcc -g -c $^ , 其中 ^ 标识是所有的依赖文件, 在该规则下 start.S 会被变异成 start.o ; 2.通用规则 ( C 文件编译规则 ) : C 代码编译成同名的 .o 文件, %.o : %.c , 产生过程是 arm-linux-gcc -g -c $^ ; 3.设置最终目标 : 使用 all: 设置最终编译目标; ( 1 ) 依赖文件 : 产生最终目标需要依赖 start.o 文件, 使用 all: start.o 表示最终目标需要依赖该文件; ( 2 ) 链接过程 : arm-linux-ld -Tgboot.lds -o gboot.elf ^, 需要使用链接器脚本进行连接, ①链接工具是 arm-linux-ld 工具, ②使用 -Tgboot.lds 设置链接器脚本 是刚写的 gboot.lds 链接器脚本, ③输出文件是 gboot.elf 这是个中间文件, ④ 依赖文件是 ^ 代表所有的依赖; ( 3 ) 转换成可执行二进制文件 : arm-linux-objcopy -O binary gboot.elf gboot.bin, 使用 -O binary 设置输出二进制文件, 依赖文件是 gboot.elf, 输出的可执行二进制文件 即 结果是 gboot.bin ;4.makefile 文件内容 : 代码语言:javascript复制all: start.o #依赖于 start.o arm-linux-ld -Tgboot.lds -o gboot.elf $^ #使用链接器脚本, 将 start.o 转为 gboot.elf arm-linux-objcopy -O binary gboot.elf gboot.bin #将 gboot.elf 转化为可以直接在板子上执行的 gboot.bin 文件 %.o : %.S #通用规则, 如 start.o 是由 start.S 编译来的, -c 是只编译不链接 arm-linux-gcc -g -c $^ %.o : %.c #通用规则, 如 start.o 是由 start.c 编译来的, -c 是只编译不链接 arm-linux-gcc -g -c $^ .PHONY: clean clean: #清除编译信息 rm *.o *.elf *.bin 4. 编译输出可执行文件

编译过程 :

1.文件准备 : 将 汇编代码 ( start.S ) 链接器脚本 ( gboot.lds ) makefile 文件 拷贝到编译目录 ;2.执行编译命令 : make ; 3.编译结果 : 可以看到 生成了 编译目标文件 start.o, 链接文件 gboot.elf, 可执行的二进制文件 gboot.bin ; 这里写图片描述这里写图片描述

本博客的参考文章及相关资料下载 :

1.本博客代码及参考手册下载 : https://download.csdn.net/download/han1202012/10409013


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3