第25章_瑞萨MCU零基础入门系列教程之看门狗定时器-WDT

news2024/11/28 18:47:11

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写,需要的同学可以在这里获取: https://item.taobao.com/item.htm?id=728461040949

配套资料获取:https://renesas-docs.100ask.net

瑞萨MCU零基础入门系列教程汇总: https://blog.csdn.net/qq_35181236/article/details/132779862


第25章 看门狗定时器-WDT

本章目标

  • 了解A6M5处理器的看门狗定时器及其工作原理;
  • 学会使用RASC配置看门狗定时器、使用其接口函数;

25.1 RA6M5的WDT外设

25.1.1 WDT的特性

一般来说,看门狗也叫看门狗定时器,从本质上面来看,其实它就是一个计数器,在使用的时候,需要给它一个数值,随后看门狗的计数器根据计数方向开始累计,在看门狗的计数器达到预设的数值之前,可以进行重置看门狗计数器的操作,也就是俗称的“喂狗”。如果没有在计数器发生溢出之前喂狗的话,看门狗就会产生复位请求或者不可屏蔽中断请求(NMI-Non Maskable Interrupt),这会导致系统重启。

瑞萨RA6M5处理器的看门狗定时器的特性见下表:

image1

看门狗时钟来自外部时钟电路PCLKB,PCLKB最大的时钟频率是50MHz,可以使用RASC配置PCLKB,也可调用CGC的接口函数设置PCLKB。

25.1.2 WDT的系统框图

WDT的系统框图如下图所示:

  1. 两套机制

RA6M5的WDT模块,有两种工作模式:“Auto start mode”(自动启动模式)、“Register start mode”(寄存器启动模式)。这两种模式有各自的寄存器,WDT工作于某种模式时,另一种模式的寄存器都无法访问。
上电后,WDT使用哪种工作模式?这由OFS0寄存器的[WDTSTRT]位决定:OFS0寄存器位于Flash上,出厂时默认为0xFFFFFFFF,也可以在生产时写入合适的数值。OFS0寄存器的值等于0xFFFFFFFF时,WDT的工作模式为“寄存器启动”,也就是上电后WDT是不工作的。

  1. 时钟源

WDT的时钟来自PCLKB,经过分频后进入WDT。
两种模式下,都有各自的寄存器用于设置时钟的分频系数:“Auto start mode”(自动启动模式)下使用OFS0寄存器的WDTCKS[3:0]位;register start mode”(寄存器启动模式)下使用WDTCR寄存器的CKS[3:0]位。不同的取值,对应不同的分频系数。有这几种分频系数:4、64、128、512、2048、8192。

  1. 14位递减计数器

看门狗的计数器是一个14位的递减计数器,它的初始值有4种选择:1024、4096、8192或16384。通过OFS0或WDTCR中的TOPS[1:0]位来选择初始值。
当看门狗被启动后,它就在分频得到的时钟下,从初始值递减。当计数值到达0时,可以发出复位信号,或者发出NMI中断请求。

  1. WDT输出及中断请求

看门狗计数溢出时,有两种处理方式:第一种是是直接复位整个系统,第二种是触发一个NMI中断,在中断函数里执行用户代码。
第一种处理方式,通常用来避免程序进入死循环,避免程序跑飞。
第二种处理方式,在中断服务函数里记录出错时的重要信息,比如记录重要的数据、记录发生错误时的环境。

  1. 输出到时钟控制电路
    当复位中断选择位(WDTRCR.RSTIRQS)在寄存器启动模式下或WDT复位时设置为1时,或当WDT复位选项功能选择寄存器0(OFS0)中的中断请求选择位(OFS0.WDTRSTIRQS)在自启动模式时设置为1时 当看门狗向下计数器下溢或者发生刷新错误时,输出1个周期计数的复位信号到时钟控制电路。

  2. 事件信号输出

当复位中断选择位(WDTRCR.RSTIRQS)在寄存器启动模式下或WDT复位时设置为0时,或当WDT复位选项功能选择寄存器0(OFS0)中的中断请求选择位(OFS0.WDTRSTIRQS)在自启动模式时设置为0时, 当看门狗向下计数器下溢或者发生刷新错误时,产生中断(WDT_NMIUNDF)信号,此信号产生的中断用于不可屏蔽中断,也就是事件输出信号。

25.1.3WDT 的启动模式

瑞萨RA6M5处理器的WDT有两种启动模式:自启动模式和寄存器启动模式。

  1. 自启动模式

当WDT启动方式选择位(OFS0.wdtstrt)为0时,WDT将被设置为自启动方式,关闭WDT控制寄存器(WDTCR)、WDT复位控制寄存器(WDTRCR)、WDT计数停止控制寄存器(WDTCSTPR),使能OFS0寄存器的设置。

在复位状态下,WDT寄存器中的选项功能选择寄存器0(OFS0)的设置值如下:

  • 时钟分频比
  • 窗口起始和结束位置
  • 超时时间
  • 复位输出或中断请求
  • 在睡眠模式时计数器停止控制
  1. 寄存器启动模式

当WDT的启动模式选择位[OFS0.WDTSTRT]被置为1时,WDT将被设置为寄存器启动模式,此模式生效后再对寄存器OFS0的设置就不会再生效了,也就是不能在程序正常运行过程中修改WDT的启动模式了。

在寄存器启动模式下,WDT的控制寄存器[WDTCR]、复位控制寄存器[WDTRCR]和计数停止控制寄存器[WDTCSTPR]将会被使能允许设置。
复位后按照下面的步骤设置WDT:

  • 在WDTCR寄存器中设置WDT的时钟分频比;
  • 在WDTCR寄存器中设置窗口监测的开始和结束位置;
  • 在WDTCR寄存器中设置超时周期;
  • 在WDTRCR寄存器中配置重置输出或中断请求输出
  • 在WDTCSTPR寄存器中控制WDT从计数运行态到休眠态的转换;

此后,只要计数器在允许刷新的时间段内刷新,计数器的值就会在每次刷新时重置,并继续向下计数。只要计数继续,WDT就不输出复位信号。但是,如果由于程序失控而导致下计数器无法更新,或者由于计数器在刷新允许的时间之外刷新而发生刷新错误,WDT将输出复位信号或不可屏蔽的中断请求(WDT_NMIUNDF)。可以在WDT复位中断请求选择位(WDTRCR.RSTIRQS)中选择复位输出或中断请求输出。

25.1.4 WDT的工作原理

  1. 计算看门狗超时时间(以PCLKB=50MHz为例)
image3
  1. 窗口监测

在RA6M5的用户手册中给出了一个窗口监测的示例,其窗口期条件如下:

  • WDT是自启动模式
  • 使能了WDT的中断请求;
  • 使能了NMI中断,当向下计数或刷新失败事件发生后会触发NMI中断;
  • 窗口监测的起始位置是超时时间的75%位置,如果超时时间周期值是1000,那么窗口起始位置就是计数值为750的时刻;
  • 窗口监测的结束位置是25%位置,如果超时时间周期值是1000,那么窗口结束位置就是计数值为250的时刻;

那么WDT在各个时刻刷新定时器的表现如下图所示:

总结下来就是:

  • 在窗口期内刷新看门狗会让WDT计数器重新计数且不会触发任何事件或中断;
  • 在没有到窗口期起始位置刷新会触发刷新错误事件并发生中断请求触发NMI中断;
  • 在超过窗口结束位置但是计数没有溢出期间刷新会触发刷新错误时间并发生中断请求触发NMI中断;
  • 如果WDT计数溢出了都没有刷新定时器,那么会触发技术溢出事件,触发NMI中断;

也就是说,如果使用了窗口监测,只有在窗口期刷新定时器才会让系统正常运行,否则都会触发NMI中断。

25.2WDT 模块的使用

25.2.1 模块配置

  1. 添加WDT Stack

在FSP配置界面的“Stacks”中添加WDT Stack的步骤如下:

  1. 配置WDT Stack

首先需要去设置WDT的启动方式,在FSP配置界面的BSP中找到“RA6M5 Family”,点开“OFS0 register settings”,再点开“WDT”,展开的选项就是配置WDT的参数了,如下图所示;

  • Start Mode Select:WDT启动模式选择
    1.1 Automatically activate WDT after a reset (自启动)
    1.2 Stop WDT after a reset (寄存器启动)

  • Timeout Period:WDT计数周期值
    1.1 1024 cycles
    1.2 4096 cycles
    1.3 8192 cycles
    1.4 16384 cycles

  • Clock Frequency Division Ratio:WDT时钟分频系数(4/64/128/512/2048/8192)

  • Window End Position:窗口监测结束位置,默认0%,没有结束位置

  • Window Start Position:窗口监测开始位置,默认100%,没有开始位置

  • Reset Interrupt Request:选择触发复位的中断请求(NMI或Reset)

  • Stop Control:停止对WDT控制的条件
    1.1 Counting continues
    1.2 Stop counting when entering Sleep mode

在此处选择了WDT的启动方式,而在BSP中对于WDT的例如超时周期等参数不会在代码中生效,其它的这些参数会在WDT Stack中配置生效,例如下图:

  • Register Start NMI Support:在寄存器启动方式下是否要NMI中断使能配置位;
  • Name:WDT模块在代码中的设备名称;
  • Reser Control:产生复位的控制条件,可以选择“NMI Generated”或“Reset Output”;
  • NMI Callback:NMI中断服务函数会调用的中断回调函数名;

25.2.2 配置信息解读

在RASC中配置WDT并生成工程后,会在hal_data.c中生成表示WDT设备的wdt_instance_t结构体常量g_wdt:

const wdt_instance_t g_wdt =
{
    .p_ctrl        = &g_wdt_ctrl,
    .p_cfg         = &g_wdt_cfg,
    .p_api         = &g_wdt_on_wdt
};
  • p_ctrl:wdt_ctrl_t类型指针成员,用来记录设备状态,记录一些重要信息(比如回调函数);
  • p_cfg:指向WDT的配置结构体,这个结构体的数值来自在RASC中对WDT的配置,代码如下:
const wdt_cfg_t g_wdt_cfg =
{
    .timeout = WDT_TIMEOUT_16384,
    .clock_division = WDT_CLOCK_DIVISION_8192,
    .window_start = WDT_WINDOW_START_100,
    .window_end = WDT_WINDOW_END_0,
    .reset_control = WDT_RESET_CONTROL_NMI,
    .stop_control = WDT_STOP_CONTROL_ENABLE,
    .p_callback = nmi_callback,
};

p_api:指向了一个wdt_api_t结构体,这个结构体在r_wdt.c中实现,它封装了WDT设备的接口函数,代码如下:

const wdt_api_t g_wdt_on_wdt =
{
    .open        = R_WDT_Open,
    .refresh     = R_WDT_Refresh,
    .statusGet   = R_WDT_StatusGet,
    .statusClear = R_WDT_StatusClear,
    .counterGet  = R_WDT_CounterGet,
    .timeoutGet  = R_WDT_TimeoutGet,
    .callbackSet = R_WDT_CallbackSet,
};

25.2.3 中断回调函数

在RASC中配置了WDT的中断回调函数名字后,会在hal_data.h中声明此回调函数:

#ifndef nmi_callback
void nmi_callback(wdt_callback_args_t * p_args);
#endif

用户需要去实现这个回调函数,例如:

void nmi_callback(wdt_callback_args_t * p_args)
{
    (void)p_args;
}

25.2.4 API接口及其用法

前文已经说过,在FSP库函数中是使用wdt_api_t结构体来封装了WDT的操作方法,原型如下:

typedef struct st_wdt_api
{
    fsp_err_t (* open)(wdt_ctrl_t * const p_ctrl, wdt_cfg_t const * const p_cfg);
    fsp_err_t (* refresh)(wdt_ctrl_t * const p_ctrl);
    fsp_err_t (* statusGet)(wdt_ctrl_t * const p_ctrl, wdt_status_t * const p_status);
    fsp_err_t (* statusClear)(wdt_ctrl_t * const p_ctrl, const wdt_status_t status);
    fsp_err_t (* counterGet)(wdt_ctrl_t * const p_ctrl, uint32_t * const p_count);
    fsp_err_t (* timeoutGet)(wdt_ctrl_t * const p_ctrl, 
                             wdt_timeout_values_t * const p_timeout);
    fsp_err_t (* callbackSet)(wdt_ctrl_t * const p_api_ctrl, 
                              void (* p_callback)(wdt_callback_args_t *),
                              void const * const p_context, 
                              wdt_callback_args_t * const p_callback_memory);
} wdt_api_t;

瑞萨在r_wdt.c中实现了一个wdt_api_t结构体。下面介绍这些接口函数的用法。

  1. 打开WDT设备
fsp_err_t (* open)(wdt_ctrl_t * const p_ctrl, wdt_cfg_t const * const p_cfg);
  • p_ctrl:wdt的控制参数,只是用来记录设备的状态以及一些信息;
  • p_cfg:wdt的配置参数;

用户可以使用以下代码来初始化WDT:

fsp_err_t err = g_wdt.p_api->open(g_wdt.p_ctrl, g_wdt.p_cfg);
assert(FSP_SUCCESS == err);
  1. 刷新WDT设备
fsp_err_t (* refresh)(wdt_ctrl_t * const p_ctrl);
  • p_ctrl:wdt的控制参数

此函数会更新WDT的14位计数器,让它从初始值开始递减;

用户可以参考以下代码刷新WDT:

fsp_err_t err = g_wdt.p_api->refresh(g_wdt.p_ctrl);
assert(FSP_SUCCESS == err);
  1. 获取WDT的状态
fsp_err_t (* statusGet)(wdt_ctrl_t * const p_ctrl, wdt_status_t * const p_status);
  • p_status:WDT状态,它是wdt_status_t枚举类型,原型如下:
typedef enum e_wdt_status
{
    WDT_STATUS_NO_ERROR                    = 0, ///< No status flags set.
    WDT_STATUS_UNDERFLOW_ERROR             = 1, ///< Underflow flag set.
    WDT_STATUS_REFRESH_ERROR               = 2, ///< Refresh error flag set. Refresh outside of permitted window.
    WDT_STATUS_UNDERFLOW_AND_REFRESH_ERROR = 3, ///< Underflow and refresh error flags set.
} wdt_status_t;
  1. 清除WDT的状态
fsp_err_t (* statusClear)(wdt_ctrl_t * const p_ctrl, const wdt_status_t status);
  1. 获取WDT当前的计数值
fsp_err_t (* counterGet)(wdt_ctrl_t * const p_ctrl, uint32_t * const p_count);

只要没有发生溢出中断或者刷新错误中断,用户就可以调用此函数获取WDT当前的计数值,p_count是一个输出参数,里面记录有得到的计数值。

  1. 获取WDT的超时周期值
fsp_err_t (* timeoutGet)(wdt_ctrl_t * const p_ctrl, 
                         wdt_timeout_values_t * const p_timeout);

只要没有发生溢出中断或者刷新错误中断,用户就可以调用此函数获取WDT当前的超时周期值,p_timeout是一个输出参数。里面记录有超时周期值。

25.3 看门狗实验

25.3.1 设计目的

让用户学会使用瑞萨RA6M5的WDT,并观察是否刷新看门狗的现象。

25.3.2 硬件连接

本实验会用到板载串口和按键,请读者参考前文配置。

25.3.3 驱动程序

  1. 初始化WDT

调用open函数即可初始化WDT,再调用刷新函数refresh以触发WDT开始计数:

void WDTDrvInit(void)
{
    /* 在自启动模式下,复位后WDT会理解开始计数 */
    fsp_err_t err = g_wdt.p_api->open(g_wdt.p_ctrl, g_wdt.p_cfg);
    assert(FSP_SUCCESS == err);
    /* 如果是寄存器启动方式,在刷新WDT后才会才是计数 */
    err = g_wdt.p_api->refresh(g_wdt.p_ctrl);
    assert(FSP_SUCCESS == err);
}
  1. 刷新WDT

刷新WDT比较简单,直接调用其refresh函数即可:

void WDTDrvRefresh(void)
{
    fsp_err_t err = g_wdt.p_api->refresh(g_wdt.p_ctrl);
    assert(FSP_SUCCESS == err);
}
  1. NMI中断回调函数

在RASC中使能了WDT的NMI中断,需要自己实现NMI回调函数,代码如下:

__WEAK void DataSaveProcess(void)
{
}
void nmi_callback(wdt_callback_args_t * p_args)
{
    (void)p_args;
    printf("\r\nWarning!Do your most important save working!!\r\n");
    DataSaveProcess();
  1. 使用按键刷新定时器

在按键消抖处理后,刷新看门狗定时器,代码如下:

void KeyProcessEvents(void)
{
    struct IODev *ptLedDev = IOGetDecvice("UserLed");
    struct IODev *ptKeyDev = IOGetDecvice("UserKey");
    ptLedDev->Write(ptLedDev, !ptKeyDev->Read(ptKeyDev));
    WDTDrvRefresh();
}

25.3.4 测试程序

在本次实验中,初始化了各个外设后,主循环中不用做任何事情,所有的操作都是在中断中完成的:

  • 按键中断
  • 滴答定时器消除按键抖动
  • NMI中断处理用户的紧急事件

测试函数代码如下:

void WDTAppTest(void)
{
    SystickInit();
    UARTDrvInit();
    
    struct IODev *ptdev = IOGetDecvice("UserKey");
    if(NULL != ptdev)
        ptdev->Init(ptdev);
    ptdev = IOGetDecvice("UserLed");
    if(NULL != ptdev)
        ptdev->Init(ptdev);
    WDTDrvInit();
    
    while(1)
    {
        /* The code that is watched by iwdt */
    }
}

25.3.5 测试结果

将编译出来的二进制可执行文件烧录到板子上并运行,如果不按按键的话会得到例如下图这样的打印信息:

image8


本章完

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1008350.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

iOS17正式版9月18日正式发布!怎么更新即将发布的iOS17正式版?

苹果在今天举办的“好奇心上头”发布会结束后&#xff0c;推送了iOS 17和iPadOS 17发布候选版本&#xff08;Release Candidate Version&#xff09;&#xff0c;同时宣布将于9月18日面向iPhone和iPad 用户&#xff0c;推送iOS17/iPadOS 17正式版更新。苹果表示iOS 17的设计理念…

C# Onnx Yolov8 Detect 物体检测

效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System…

自动化办公更简单了:新版python-office,有哪些更新?

#职场经验谈# 大家好&#xff0c;这里是程序员晚枫&#xff0c;小破站/小红薯都叫这个名。 去年4月开源了一个Python自动化办公项目&#xff1a;python-office&#xff0c;GitHub和Gitee都能看到。1行代码实现复杂的自动化办公任务&#xff0c;帮助不懂代码的小白&#xff0c;…

处理SQLSyntaxErrorException异常:数据库表 ‘books‘ 不存在;

目录 背景介绍 我的问题中的解决方法 通用方法 背景介绍 今天遇见了这个问题&#xff0c;解决后发出来分享一下 Java应用程序中的SQLSyntaxErrorException&#xff1a;表 bookmanagement.books 不存在问题解决 解决MySQL错误&#xff1a;无法找到表 bookmanagement.books…

Java native 关键字

如你在看 JDK 的源代码的时候&#xff0c;大概率会看到很多方法使用了 native 关键字。 下面是 String 对象 JDK 中的源代码&#xff0c;就带有了一个 native 关键字。 native 是干什么用的 简单来说就是 Java 的 native 方法的实现不是用 Java 实现的&#xff0c;可能在其他…

2023最新AI创作商用ChatGPT源码分享+支持AI绘画

一、SparkAI智能创作系统 SparkAi创作系统是基于国外很火的ChatGPT进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文…

OPENCV--实现meanshift图像分割

Meanshift原理 效果图 API # -*- coding:utf-8 -*- """ 作者:794919561 日期:2023/9/13 """ import cv2 import numpy as npimg = cv2.imread("F:\\learnOpenCV\\openCVLearning\\pictures\\Lena.jpg

计算机视觉的应用14-目标检测经典算法之YOLOv1-YOLOv5的模型架构与改进过程详解,便于记忆

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用14-目标检测经典算法之YOLOv1-YOLOv5的模型架构与改进过程详解&#xff0c;便于记忆。YOLO&#xff08;You Only Look Once&#xff09;是一种目标检测深度学习模型。想象一下&#xff0c;传统的目…

做机器视觉工程师,其实挺没意思的

3.康耐视VisionPro高级脚本系列教程-3.脚本编辑错误和运行错误调试方法&#xff0c;break和Contitinuee的差别_哔哩哔哩_bilibili 其实人生就是“有时有意思&#xff0c;有时没意思”。 心里有太多的不甘心&#xff0c;太多的苦水&#xff0c;是没法再吃学习的苦&#xff0c…

Linux系统编程多线程(C++)

目录 【1】引入如何看待地址空间和列表 【2】什么是线程 【3】线程的优点 【4】线程的缺点 【5】线程异常 【6】线程用途 【7】线程VS进程 【8】Linux线程控制 【8.1】查看轻量级线程指令 【8.2】线程创建 【8.2.1】POSIX线程库 【8.2.2】创建线程 【8.2.3】一次性…

1054. 距离相等的条形码;823. 带因子的二叉树;1878. 矩阵中最大的三个菱形和

1054. 距离相等的条形码 核心思想&#xff1a;隔一个数填一个&#xff0c;优先填写出现次数多的数。注意点就是条形码的长度为奇数和偶数&#xff0c;但是我们遵循先优先填偶数就不会出错即可。 823. 带因子的二叉树 核心思想&#xff1a;递归。定义dfs(val)表示以值val作为根…

[UE虚幻引擎插件介绍] DTSQLite 插件说明 :蓝图操作SQLite3文件,执行SQL语句。

本插件可以在UE里面使用蓝图操作SQLite3文件&#xff0c;并且执行SQL语句&#xff0c;CREATE&#xff0c;SELECT&#xff0c;DELETE&#xff0c;INSERT&#xff0c;UPDATE。 直接操作数据库&#xff0c;并返回相应结果集&#xff0c;并可以把结果集转换为TArray<TMap<FSt…

Microsoft Excel 101 简介

什么是 Microsoft Excel&#xff1f; Microsoft Excel 是一个电子表格程序&#xff0c;用于记录和分析数值数据。 将电子表格想像成构成表格的列和行的集合。 字母通常分配给列&#xff0c;数字通常分配给行。 列和行相交的点称为像元。 单元格的地址由代表列的字母和代表行的…

华为云征文|华为云云耀云服务器L实例使用教学(一)

目录 国内免费云服务器&#xff08;体验&#xff09; 认识国内免费云服务器 如何开通国内免费云服务器 云耀云服务器 HECS HECS适用于哪些场景&#xff1f; 网站搭建 电商建设 开发测试环境 云端学习环境 为什么选择华为云耀云服务器 HECS 国内免费云服务器&#xff…

LeetCode 40. Combination Sum II【回溯,剪枝】中等

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

Loopback for Mac:专业级的音频处理能力

Loopback for Mac是一款功能强大的虚拟音频设备&#xff0c;它能够将应用程序的音频输出路由到其他应用程序的输入&#xff0c;从而实现音频数据的传输和交互。以下是Loopback for Mac的一些主要功能和特色介绍&#xff1a; 创建虚拟音频设备&#xff1a;Loopback可以创建虚拟…

基于Python开发的Excel数据分析系统(源码+可执行程序+程序配置说明书+程序使用说明书)

一、项目简介 本项目是一套基于Python开发的Excel数据分析系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Python学习者。 包含&#xff1a;项目源码、项目文档等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0…

源码编译risc-v虚拟机和编译器 riscv-gnu-toolchain 和 riscv-tools 在ubuntu 22.04

1. 编译 riscv-gnu-toolchain 1.1 预备环境 $ sudo apt-get install autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev 1.2 下载源代码 http…

Linux tcpdump抓包命令

1.tcpdump抓包命令 -c 指定抓取包的数量&#xff0c;即最后显示的数量 -i 指定tcpdump监听的端口。未指定&#xff0c;选择系统中最小的以配置端口。-i any:监听所有网络端口 -i lo:监听lookback接口。-nn 对监听地址以数字方式呈现&#xff0c;且对端口也以数字方式呈现。…

西门子S7-1200F或1500F系列安全PLC的组态步骤和基础编程(一)

西门子S7-1200F或1500F系列安全PLC的组态步骤和基础编程(一) 第一部分:组态配置 具体步骤可参考以下内容: 如下图所示,新建一个项目后,添加一个安全型PLC,这里以1516F-3 PN/DP为例进行说明, 如下图所示,添加CPU完成后,可以看到左侧的项目树中比普通的PLC多了几个选项…