本帖最后由 LINUX课程 于 2024-9-11 10:21 编辑
软件版本:vitis2021.1(vivado2021.1) 操作系统:WIN10 64bit 硬件平台:适用XILINX Z7/ZU系列FPGA
1 概述 在学习了TTC定时器的基础上,本章将会学习关于看门狗相关的内容,主要进行的操作的将是系统看门狗(SWDT)。 实验目的: - 了解看门狗的概念。
- 理解看门狗在系统中的作用。
- 掌握使用系统看门狗的方法。
2 系统框图 在上一章TTC定时器的系统框图部分,我们已经对系统内的定时器分布有了一定的了解,在此基础上,我们对SWDT部分进行深入的分析。 PS中有三个系统看门狗定时器(SWDT)单元。它们全都是基于ARM体系结构的系统看门狗定时器。这些看门狗之间的一个主要区别是系统接口信号不同。LPD和FPD看门狗定时器的时钟源可以来自内部参考时钟、EMIO时钟或MIO时钟,CSU_SWDT可以从本地总线或直接从PS_REF_CLK引脚获取时钟。 3 介绍 3.1 SWDT定时器 Zynq的PS的CPU0和CPU1各包含1个私有定时器以及一个私有看门狗定时器并且共享一个全局定时器。另外Zynq的PS还有TTC0以及TTC1定制控制器。每个TTC定时器里面包含三个定时器/计数器。本文所讲解的是CPU0的私有看门狗定时器中断的使用。 看门狗需要不停的“喂狗”,在这里就是不停的读预加载寄存器再写入预加载寄存器。如果不能及时喂狗,那么看门狗就会超时,并且产生一个复位输出。 本方案中只对CPU0的私有看门狗定时器进行说明。 Zynq的私有定时器和看门狗定时器具有以下共同的特性: 1-定时计数器位宽为32位,当达到0时产生中断 2-参考时钟为CPU时钟的1/2,比如CPU是666.6666M 那么定时器的参考时钟为333.3333M 3-有一个8bit预分频器,可以对参考时钟进一步分频 4-有一个可配置的预加载寄存器 5-可配置为单次模式或者自动重载模式 看门狗定时器多了以下功能: 1-当看门狗没有及时“喂狗”导致的系统复位输出 2-看门狗定时器可以设置为定时器模式或者看门狗模式 3.2 私有定看门狗时器的寄存器 在UG585中没有关于私有看门狗定时器的详细说明,我们通过SDK代码的理解补充了这部分说明。私有看门狗定时器的基地址为0xF8F00620。CPU的私有看门狗定时器一共有6个寄存器: XSCUWDT_LOAD寄存器XSCUWDT_LOAD_OFFSET(0x00U) Field Name | Bits | Type | Reset Value | Description | | | | | |
XSCUWDT_COUNTER寄存器XSCUWDT_COUNTER_OFFSET (0x04U) Field Name | Bits | Type | Reset Value | Description | | | | | |
XSCUWDT_CONTROL寄存器XSCUWDT_CONTROL_OFFSET (0x08U) Field Name | Bits | Type | Reset Value | Description | | | | | 私有看门狗定时器的控制寄存器 15~8bit:预分频设置 3bit:当为看门狗模式,设置1为看门狗 2bit:当为定时器模式,设置1为中断使能 1bit:当为1自动重载使能 0bit:当为1表示看门狗使能 |
XSCUWDT _ISR寄存器XSCUWDT _ISR_OFFSET (0x0CU) Field Name | Bits | Type | Reset Value | Description | | | | | 私有看门狗定时器的中断寄存器 0bit:当为1的时候表示发生中断 |
XSCUWDT_RST_STS寄存器XSCUWDT_RST_STS_OFFSET (0x10U) Field Name | Bits | Type | Reset Value | Description | | | | | 私有看门狗定时器的复位状态寄存器 0bit:当为1代表定时器超时并且发送一个复位 |
XSCUWDT_DISABLE寄存器XSCUWDT_DISABLE_OFFSET (0x14U) Field Name | Bits | Type | Reset Value | Description | | | | | 第一次写入0x12345678U 第二次写入0x87654321U 会设置控制寄存器的bit-3为0,这样设置为定时器模式 |
4 搭建工程 4.1 vivado工程的搭建 详细的vivado搭建参考第一章vivado和vitis工程搭建。如果使用的是附件中的工程生成的系统文件,或者使用的是附件中提供的相关的boot文件夹中的文件。那么,就无需改动vivado工程的设置。 4.2 上传文件至虚拟机 将文件“watchdog”上传至虚拟机,可以使用U盘,scp,vm-tools等一系列方式实现。 5 程序分析 驱动程序已经在内核编译的时候就已经编译在linux系统中了。因此,仅在这里生成应用程序对SWDT进行验证。 5.1 应用程序分析 - #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys/ioctl.h>
- #include <unistd.h>
- #include <linux/watchdog.h>
- int main(int argc, char *argv[])
- {
- int fd = -1, cmd = -1, timeout = 0;
- //打开看门狗
- fd = open("/dev/watchdog1", O_RDWR);
- if (fd < 0)
- {
- printf("Error: Failed to open /dev/watchdog1\n");
- return -1;
- }
- //使能看门狗
- ioctl(fd, WDIOC_SETOPTIONS, WDIOS_ENABLECARD);
- switch (atoi(argv[1]))
- {
- case 0:
- //获取超时时间
- timeout = atoi(argv[2]);
- printf("Timeout = %ds\n", timeout);
- //设置超时
- ioctl(fd, WDIOC_SETTIMEOUT, &timeout);
- break;
- case 1:
- //喂狗
- ioctl(fd, WDIOC_KEEPALIVE, NULL);
- break;
- default:
- break;
- }
- close(fd);
- return 0;
- }
复制代码第16行打开设备。第23行使能看门狗。 第31、35行对设备进行设置。 1:看门狗相关参数 - #define WDIOC_GETSUPPORT _IOR(WATCHDOG_IOCTL_BASE, 0, struct watchdog_info)
- #define WDIOC_GETSTATUS _IOR(WATCHDOG_IOCTL_BASE, 1, int)
- #define WDIOC_GETBOOTSTATUS _IOR(WATCHDOG_IOCTL_BASE, 2, int)
- #define WDIOC_GETTEMP _IOR(WATCHDOG_IOCTL_BASE, 3, int)
- #define WDIOC_SETOPTIONS _IOR(WATCHDOG_IOCTL_BASE, 4, int)
- #define WDIOC_KEEPALIVE _IOR(WATCHDOG_IOCTL_BASE, 5, int)
- #define WDIOC_SETTIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 6, int)
- #define WDIOC_GETTIMEOUT _IOR(WATCHDOG_IOCTL_BASE, 7, int)
- #define WDIOC_SETPRETIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 8, int)
- #define WDIOC_GETPRETIMEOUT _IOR(WATCHDOG_IOCTL_BASE, 9, int)
- #define WDIOC_GETTIMELEFT _IOR(WATCHDOG_IOCTL_BASE, 10, int)
复制代码含义:设置看门狗的相关参数。 具体分析: - WDIOC_GETSUPPORT:获取看门狗信息
- WDIOC_GETSTATUS:获取看门狗状态
- WDIOC_SETOPTIONS:看门狗选项,可以用来使能看门狗
- WDIOC_KEEPALIVE:喂狗
- WDIOC_SETTIMEOUT:设置超时值
- WDIOC_GETTIMEOUT:获取超时值
- WDIOC_SETPRETIMEOUT:设置预超时值
- WDIOC_GETPRETIMEOUT:获取预超时值
- WDIOC_GETTIMELEFT:获取剩余时间
2:ioctl函数 - int ioctl(int d,int request, ...)
复制代码含义:配合驱动层的IOCTL函数实现指令的传递。 具体分析: - d:设备描述符
- request:指令,如某一个命令对应驱动层的某一个功能
- …:可变参数,跟命令有关,传递进入驱动层的参数或者是接收数据的缓存
- 返回值:0:成功;非0:失败
6 程序编译 6.1 Makefile文件分析 - #已经编译过的内核源码路径
- KERNEL_DIR = /home/uisrc/uisrc-lab-xlnx/sources/kernel
- export ARCH=arm
- export CROSS_COMPILE=arm-linux-gnueabihf-
- #当前路径
- CURRENT_DIR = $(shell pwd)
- APP = watchdog_test
- #APP = watchdog
- all :
- #进入并调用内核源码目录中Makefile的规则, 将当前的目录中的源码编译成模块
- ifneq ($(APP), )
- $(CROSS_COMPILE)gcc $(APP).c -o $(APP)
- endif
- clean :
- rm $(APP)
- #指定编译哪个文件
- obj-m += $(MODULE).o
复制代码详细内容参考第一章“在虚拟机上进行交叉编译”的相关内容。如果是自定义的文件名,在第10行和第11行,可以进行修改。 7 演示 7.1 硬件准备 SD2.0 启动 01 而模式开关为 ON OFF(7100 需要先将系统烧录进qspi,然后才能从qspi启动sd卡,“[米联客-XILINX-H3_CZ08_7100] LINUX基础篇连载-04 从vitis移植Ubuntu实现二次开发”) 将 PS 端串口线连接电脑,如果要使用 ssh 登录,将网口线同样连接至电脑,最后给开发板通电。每次重新上电,需要重新插拔 PS 串口,否则会登录失败。 7.2 程序准备 将驱动与程序上传至开发板,查看文件是否传输成功。 在终端输入“ls”命令。确认当前所需文件,已经被上传到当前的文件夹内了。 在管理员权限下,终端输入“chmod 777 watchdog_test”,改变应用程序的权限。 通过以上操作可以确定应用程序已经安装。 7.3 实验结果 在终端输入“./watchdog_test 0 3”,输出如下。可以看到,在启动看门狗的时候,设置的时间是3秒。3秒到了之后,watchdog就会报超时的警告。 再在终端输入“./watchdog_test 0 5”,在未超时的时间内不断的输入“./watchdog_test 0 1”来重置看门狗。时间可以看到非常明显的延长至427秒处,而watchdog开始于410秒处,显然是已经超过了设置的5秒了。之所有没有报超时,是因为我们不断的给它重置。 测试成功。 |