分类: 计算机

  • 解决VSCode remote-ssh连接腾讯云服务器死机的一个方法

    一个2核4GB的腾讯云 Ubuntu 服务器,三番两次死机。最后也没发现到底为啥,反正用 VSCode 连接就老死机,搜了一下可能是爆内存了,因此我们使用增加Swap的方法。(最新消息,别开 VSC 的自动保存,非常占内存!)

    找 ChatGPT 问怎么加虚存。得到答案如下:

    在Linux系统中,你可以通过以下步骤增加虚拟内存:

    1. 创建一个用作交换空间的文件:可以使用dd命令创建一个指定大小的空文件。例如,创建一个8GB大小的交换文件可以使用以下命令:
      bash sudo fallocate -l 8G /swapfile
    2. 设置文件的权限:交换文件应该具有合适的权限以供系统使用,你可以使用以下命令修改文件的权限: sudo chmod 600 /swapfile
    3. 将文件格式化为交换空间: sudo mkswap /swapfile
    4. 启用交换空间:
      bash sudo swapon /swapfile
    5. 设置交换空间的启动顺序:
      为了在系统重启后自动启用交换空间,你需要将交换文件的信息添加到/etc/fstab文件中。打开该文件并在末尾添加以下行: /swapfile none swap sw 0 0 保存并关闭文件。
    6. 使用
      bash free -h
      查看虚存情况。

    实测完美解决死机问题。

  • Linux 学习记录

    快捷键

    窗口相关的

    最大窗口 win + ↑

    最小化窗口 win + ↓

    隐藏窗口 win + H

    窗口放左边 win + ←

    窗口放右边 win + →

    桌面常用快捷键

    Alt + F1:聚焦到桌面左侧任务导航栏,可按上下键进行导航

    Alt + F2:运行命令

    Alt + F4:关闭当前窗口

    Alt + Tab:切换程序窗口

    Alt + 空格:打开窗口菜单

    PrtSc:桌面截图

    Win + A:搜索/浏览程序

    Win + F:搜索/浏览文件

    Win + M:搜索/浏览音乐文件

    Win:搜索/浏览程序、文件、音乐文件等

    常见终端快捷键

    Ctrl + Alt + T:打开终端

    Tab:命令或文件名自动补全

    Ctrl + Shift + C:复制

    Ctrl + Shift + V:粘贴

    Ctrl + Shift + T:在同一个窗口新建终端标签页

    Ctrl + Shift + W:关闭标签页

    Ctrl + Shift + N:新建终端窗口

    Ctrl + Shift + Q:关闭终端窗口

    Ctrl + Shift + PageUp:标签页左移

    Ctrl + Shift + PageDown:标签页右移

    Ctrl + D:关闭标签页

    Ctrl + L:清除屏幕

    Ctrl + C:终止当前任务

    Ctrl + P:显示上一条历史命令

    Ctrl + N:显示下一条历史命令

    Ctrl + R:反向搜索历史命令

    Ctrl + J/M:回车(同enter键功能)

    Ctrl + A:光标移动到行首

    Ctrl + E:光标移动到行尾

    Ctrl + B:关闭想后移动一个位置(backward)

    Ctrl + Z:把当前任务放到后台运行

    Ctrl + PageUp:前一个终端标签页

    Ctrl + PageDown:下一个终端标签页

    F1:打开帮助指南

    F11:全屏切换

    Alt + F:打开“文件”菜单(file)

    Alt + E:打开“编辑”菜单(edit)

    Alt + V:打开“查看“菜单(view)

    Alt + S:打开“搜索”菜单(search)

    Alt + T:打开“终端”菜单(terminal)

    Alt + H:打开“帮助”菜单(help)

    Ctrl + →:光标移动到上一个单词的词首

    Ctrl + ←:光标移动到下一个单词的词尾

    Ctrl + T:将光标位置的字符和前一个字符进行位置交换

    Ctrl + U:剪切从行的开头到光标前一个位置的所有字符

    Ctrl + K:剪切从光标位置到行末的所有字符

    Ctrl + Y:粘贴Ctrl + U/Ctrl + K剪切的内容

    Ctrl + H/*:删除光标位置的前一个字符(backspace键功能)

    Ctrl + D:删除光标位置的一个字符(delete键功能)

    Ctrl + W:删除光标位置的前一个单词(Alt + Backspace组合键功能)

    Ctrl + &:恢复Ctrl + H/D/W删除的内容

    Ctrl + Win + ↑:最大化当前窗口

    Ctrl + Win + ↓:还原/最小化当前窗口

    Ctrl + Win + D:最小化所有窗口

    Win + W:展示所有窗口

    Win + T:打开回收站

    2次连续Tab/4次连续Esc/2次连续Ctrl + I:将显示所有命令和工具名称

    常用Gedit编辑器快捷键

    Ctrl + N:新建文档

    Ctrl + W:关闭文档

    Ctrl + S:保存文档

    Ctrl + Shift + S:另存为

    Ctrl + F:搜索

    Ctrl + H:搜索并替换

    Ctrl + I:跳到某一行

    Ctrl + C:复制

    Ctrl + V:粘贴

    Ctrl + X:剪切

    Ctrl + Q:退出

    常用的一些命令

    查看端口占用

    lsof 命令

    lsof -i:端口号
    #例如
    $ lsof -i:8080
    
    # 其它命令
    lsof -i:8080:查看8080端口占用
    lsof abc.txt:显示开启文件abc.txt的进程
    lsof -c abc:显示abc进程现在打开的文件
    lsof -c -p 1234:列出进程号为1234的进程所打开的文件
    lsof -g gid:显示归属gid的进程情况
    lsof +d /usr/local/:显示目录下被进程开启的文件
    lsof +D /usr/local/:同上,但是会搜索目录下的目录,时间较长
    lsof -d 4:显示使用fd为4的进程
    lsof -i -U:显示所有打开的端口和UNIX domain文件
    

    netstat 命令

    netstat -tunlp | grep 端口号
    netstat -ntlp   //查看当前所有tcp端口
    
    -t (tcp) 仅显示 tcp 相关选项
    -u (udp) 仅显示 udp 相关选项
    -n 拒绝显示别名,能显示数字的全部转化为数字
    -l 仅列出在 Listen (监听) 的服务状态
    -p 显示建立相关链接的程序名
    

    杀进程

    kill 命令

    kill -9 PID
    

    一行解决

    sudo lsof -ti:port | xargs kill -9
    

    升级

    sudo apt-get update
    sudo apt-get upgrade
    

    N

    是很好的Node.js版本管理工具,使用npm安装

    npm -g install n
    

    sudo前缀 管理员运行

    环境变量配置

    管理员打开/etc/profile

    sudo vim /etc/profile
    

    格式如下

    export PATH=写上路径:$PATH
    

    例如

    export PATH=/usr/local/bin/node:$PATH
    

    curl

    cURL是一个利用URL语法在命令行下工作的文件传输工具,它支持文件上传和下载,所以是综合传输工具,但按传统,习惯称cURL为下载工具。

    Node.js

    npm

    npm -g 全局安装,不写入节点, npm install 时不下载该依赖.

    npm -s 安装依赖到 mode_modules 目录下,写入dependencies节点, npm install 时下载该依赖,一般安装生成环境所用依赖, 如 vue, element-ui, echarts

    npm -d 安装依赖到 mode_modules 目录下,写入devDependencies节点, npm install 时下载该依赖,一般安装开发环境所用依赖, 如 wabpack, babel… 原文

    1. npm install moduleName

    安装依赖到 `mode_modules` 目录下,不写入节点, `npm install` 时不下载该依赖.

    2. npm install -g moduleName

    全局安装,不在 `mode_modules` 目录下,不写入节点, `npm install` 时不下载该依赖.

    3. npm install -save moduleName

    安装依赖到 `mode_modules` 目录下,写入`dependencies`节点, `npm install` 时下载该依赖,一般安装生成环境所用依赖, 如 `vue, element-ui, echarts`…

    4. npm install -save -dev moduleName

    安装依赖到 `mode_modules` 目录下,写入`devDependencies`节点, `npm install` 时下载该依赖,一般安装开发环境所用依赖, 如 `wabpack, babel`…

    code-server

    官网

    安装方法

    推荐两种方法

    1. 一个是npm安装 npm i code-server -g #安装 code-server #启动 npm安装我用不了,版本问题,使用N控制版本,但没成功安装。懒得折腾了。
    2. deb安装 deb安装就是安装包安装 curl -fsSL https://code-server.dev/install.sh | sh curl命令把文件下载到了~/.cache/,如果需要打开,执行 cd ~/.cache/ 找到下载的文件,使用dpkg -i命令,在这里是 sudo dpkg -i code-server_3.4.0_amd64.deb #要不要sudo取决于是不是root用户 就安装好了。

    配置文件,修改密码和端口。

    vim   ~/.config/code-server/config.yaml
    

    端口

    bind-addr: 127.0.0.1:8080
    #添加这行 端口任意,我设置的256
    bind-addr: 0.0.0.0:8080
    #外网访问 加这行,上面那行删掉
    

    扩展换源

    打开这个文件 /usr/lib/code-server/lib/vscode/product.json ,添加如下文本(注意json格式,英文逗号的问题,否则可能会导致错误)

      "extensionsGallery": {
        "serviceUrl": "https://marketplace.visualstudio.com/_apis/public/gallery",
        "itemUrl": "https://marketplace.visualstudio.com/items",
        "cacheUrl": "https://vscode.blob.core.windows.net/gallery/index",
        "controlUrl": "",
        "recommendationsUrl": ""
      }
    

    tmux命令介绍:

    # 开启新会话
    tmux new -s code_server
    
    # 如果你还未启动过code-server,则执行以下命令
    systemctl enable --now code-server@root
    
    # 此处的root可改成USER或者你当前linux用户名
    systemctl start [email protected]
    
    # 返回code_server会话
    tmux a -t code_server
    
    # 杀掉code_server会话
    tmux kill -session -t code_server
    
    # 查看code-server状态
    systemctl status [email protected]
    
    # 查看code-server进程
    ps -aux | grep code-server
    
    # 停止code-server服务
    systemctl stop [email protected]
    
    # 杀死code-server进程
    kill <pid>
    


    MySQL

    1. 显示MySQL全部用户 SELECT user, host FROM mysql.user; #显示MySQL全部用户
    2. 登录 mysql #以当前用户登录 mysql -u username #以 username 登录

    help文件

    help

    TeamViewer

    安装后缺少依赖,dpkg –list 软件状态iU

    sudo apt-get -f install
    

    Tmux

    一、简介

    1.1 会话与进程

    命令行的典型使用方式是,打开一个终端窗口(terminal window,以下简称”窗口”),在里面输入命令。用户与计算机的这种临时的交互,称为一次”会话”(session)

    会话的一个重要特点是,窗口与其中启动的进程是连在一起的。打开窗口,会话开始;关闭窗口,会话结束,会话内部的进程也会随之终止,不管有没有运行完。

    一个典型的例子就是,SSH 登录远程计算机,打开一个远程窗口执行命令。这时,网络突然断线,再次登录的时候,是找不回上一次执行的命令的。因为上一次 SSH 会话已经终止了,里面的进程也随之消失了。

    为了解决这个问题,会话与窗口可以”解绑”:窗口关闭时,会话并不终止,而是继续运行,等到以后需要的时候,再让会话”绑定”其他窗口。

    1.2 Tmux 的作用

    Tmux 就是会话与窗口的”解绑”工具,将它们彻底分离。

    (1)它允许在单个窗口中,同时访问多个会话。这对于同时运行多个命令行程序很有用。

    (2)它可以让新窗口”接入”已经存在的会话。

    (3)它允许每个会话有多个连接窗口,因此可以多人实时共享会话。

    (4)它还支持窗口任意的垂直和水平拆分。

    类似的终端复用器还有 GNU Screen。Tmux 与它功能相似,但是更易用,也更强大。

    二、基本用法

    2.1 安装

    Tmux 一般需要自己安装。

    # Ubuntu 或 Debian
    $ sudo apt-get install tmux
    
    # CentOS 或 Fedora
    $ sudo yum install tmux
    
    # Mac
    $ brew install tmux
    

    2.2 启动与退出

    安装完成后,键入tmux命令,就进入了 Tmux 窗口。

    $ tmux
    

    上面命令会启动 Tmux 窗口,底部有一个状态栏。状态栏的左侧是窗口信息(编号和名称),右侧是系统信息。

    按下Ctrl+d或者显式输入exit命令,就可以退出 Tmux 窗口。

    $ exit
    

    2.3 前缀键

    Tmux 窗口有大量的快捷键。所有快捷键都要通过前缀键唤起。默认的前缀键是Ctrl+b,即先按下Ctrl+b,快捷键才会生效。

    举例来说,帮助命令的快捷键是Ctrl+b ?。它的用法是,在 Tmux 窗口中,先按下Ctrl+b,再按下?,就会显示帮助信息。

    然后,按下 ESC 键或q键,就可以退出帮助。

    三、会话管理

    3.1 新建会话

    第一个启动的 Tmux 窗口,编号是0,第二个窗口的编号是1,以此类推。这些窗口对应的会话,就是 0 号会话、1 号会话。

    使用编号区分会话,不太直观,更好的方法是为会话起名。

    $ tmux new -s <session-name>
    

    上面命令新建一个指定名称的会话。

    3.2 分离会话

    在 Tmux 窗口中,按下Ctrl+b (松开Ctrl b) d或者输入tmux detach命令,就会将当前会话与窗口分离。

    $ tmux detach
    

    上面命令执行后,就会退出当前 Tmux 窗口,但是会话和里面的进程仍然在后台运行。

    tmux ls命令可以查看当前所有的 Tmux 会话。

    $ tmux ls
    # or
    $ tmux list-session
    

    3.3 接入会话

    tmux attach命令用于重新接入某个已存在的会话。

    # 使用会话编号
    $ tmux attach -t 0
    
    # 使用会话名称
    $ tmux attach -t <session-name>
    

    3.4 杀死会话

    tmux kill-session命令用于杀死某个会话。

    # 使用会话编号
    $ tmux kill-session -t 0
    
    # 使用会话名称
    $ tmux kill-session -t <session-name>
    

    3.5 切换会话

    tmux switch命令用于切换会话。

    # 使用会话编号
    $ tmux switch -t 0
    
    # 使用会话名称
    $ tmux switch -t <session-name>
    

    3.6 重命名会话

    tmux rename-session命令用于重命名会话。

    $ tmux rename-session -t 0 <new-name>
    

    上面命令将0号会话重命名。

    3.7 会话快捷键

    下面是一些会话相关的快捷键。

    • Ctrl+b d:分离当前会话。
    • Ctrl+b s:列出所有会话。
    • Ctrl+b $:重命名当前会话。

    四、最简操作流程

    综上所述,以下是 Tmux 的最简操作流程。

    1. 新建会话tmux new -s my_session
    2. 在 Tmux 窗口运行所需的程序。
    3. 按下快捷键Ctrl+b d将会话分离。
    4. 下次使用时,重新连接到会话tmux attach-session -t my_session

    五、窗格操作

    Tmux 可以将窗口分成多个窗格(pane),每个窗格运行不同的命令。以下命令都是在 Tmux 窗口中执行。

    5.1 划分窗格

    tmux split-window命令用来划分窗格。

    # 划分上下两个窗格
    $ tmux split-window
    
    # 划分左右两个窗格
    $ tmux split-window -h
    

    5.2 移动光标

    tmux select-pane命令用来移动光标位置。

    # 光标切换到上方窗格
    $ tmux select-pane -U
    
    # 光标切换到下方窗格
    $ tmux select-pane -D
    
    # 光标切换到左边窗格
    $ tmux select-pane -L
    
    # 光标切换到右边窗格
    $ tmux select-pane -R
    

    5.3 交换窗格位置

    tmux swap-pane命令用来交换窗格位置。

    # 当前窗格上移
    $ tmux swap-pane -U
    
    # 当前窗格下移
    $ tmux swap-pane -D
    

    5.4 窗格快捷键

    下面是一些窗格操作的快捷键。

    • Ctrl+b %:划分左右两个窗格。
    • Ctrl+b ":划分上下两个窗格。
    • Ctrl+b <arrow key>:光标切换到其他窗格。<arrow key>是指向要切换到的窗格的方向键,比如切换到下方窗格,就按方向键
    • Ctrl+b ;:光标切换到上一个窗格。
    • Ctrl+b o:光标切换到下一个窗格。
    • Ctrl+b {:当前窗格与上一个窗格交换位置。
    • Ctrl+b }:当前窗格与下一个窗格交换位置。
    • Ctrl+b Ctrl+o:所有窗格向前移动一个位置,第一个窗格变成最后一个窗格。
    • Ctrl+b Alt+o:所有窗格向后移动一个位置,最后一个窗格变成第一个窗格。
    • Ctrl+b x:关闭当前窗格。
    • Ctrl+b !:将当前窗格拆分为一个独立窗口。
    • Ctrl+b z:当前窗格全屏显示,再使用一次会变回原来大小。
    • Ctrl+b Ctrl+<arrow key>:按箭头方向调整窗格大小。
    • Ctrl+b q:显示窗格编号。

    六、窗口管理

    除了将一个窗口划分成多个窗格,Tmux 也允许新建多个窗口。

    6.1 新建窗口

    tmux new-window命令用来创建新窗口。

    $ tmux new-window
    
    # 新建一个指定名称的窗口
    $ tmux new-window -n <window-name>
    

    6.2 切换窗口

    tmux select-window命令用来切换窗口。

    # 切换到指定编号的窗口
    $ tmux select-window -t <window-number>
    
    # 切换到指定名称的窗口
    $ tmux select-window -t <window-name>
    

    6.3 重命名窗口

    tmux rename-window命令用于为当前窗口起名(或重命名)。

    $ tmux rename-window <new-name>
    

    6.4 窗口快捷键

    下面是一些窗口操作的快捷键。

    • Ctrl+b c:创建一个新窗口,状态栏会显示多个窗口的信息。
    • Ctrl+b p:切换到上一个窗口(按照状态栏上的顺序)。
    • Ctrl+b n:切换到下一个窗口。
    • Ctrl+b <number>:切换到指定编号的窗口,其中的<number>是状态栏上的窗口编号。
    • Ctrl+b w:从列表中选择窗口。
    • Ctrl+b ,:窗口重命名。

    七、其他命令

    下面是一些其他命令。

    # 列出所有快捷键,及其对应的 Tmux 命令
    $ tmux list-keys
    
    # 列出所有 Tmux 命令及其参数
    $ tmux list-commands
    
    # 列出当前所有 Tmux 会话的信息
    $ tmux info
    
    # 重新加载当前的 Tmux 配置
    $ tmux source-file ~/.tmux.conf
    

    八、参考链接

    NGINX

    本质上是代理,或者说,转发。

    指令

    $ nginx
    # 启动
    $ nginx -s stop
    # 停止
    $ nginx -s reload
    # 重载
    $ nginx 
    

    相同端口(非默认) http 跳 https

    http访问https端口,默认497错误,是返回400 Bad Request: The plain HTTP request was sent to HTTPS port
    可以修改这个错误处理。 在 server { .. } 中加入一行。

    error_page 497 https://$host$request_uri;
    #默认用302,临时重定向
    error_page 497 =301 https://$host$request_uri;
    #永久重定向
    error_page 497 =307 https://$host$request_uri;
    #临时重定向,不改变请求的方法(如post还是post)
    

    如果重定向后,没有带上正确的端口号,则显式的加上端口号 $server_port

    error_page 497 https://$host:$server_port$request_uri;

    还有一种写法,

    error_page 497 https://$host:$server_port$uri$is_args$args;

    最终写法:

    error_page 497 301 =307 https://$host:$server_port$request_uri;
    #永久重定向,不改变请求的方法(如post还是post),其它端口
    
    error_page 497 301 =307 https://$host$request_uri;
    #443端口
    

    Swap

    free -h #查看内存状态
    sudo fallocate -l 6G /swapfile
    sudo chmod 600 /swapfile
    sudo mkswap /swapfile
    sudo swapon /swapfile
    echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
    
    

    然后修改/etc/sysctl.conf中的vm.swappiness = 70,阿里云可能默认为0,0就是不倾向于使用,100就是更积极地使用。

    最后执行

    sudo sysctl -p
    

  • 物联网工程设计与实施

    范围

    1~5 章,8、9 章

    第一章 物联网工程设计与实施

    1.1 物联网工程主要内容

    1.1.1 概念

    物联网工程 是 研究物联网系统的规划、设计、实施与管理的工程科学。

    1.1.2 内容

    1. 数据感知系统
    2. 数据接入与传输系统
    3. 数据存储系统
    4. 数据处理系统
    5. 应用系统
    6. 控制系统
    7. 安全系统
    8. 机房
    9. 网络管理系统

    1.2 物联网工程设计的目标与约束条件

    1.2.1 目标

    在系统工程科学方法指导下,根据用户需求,设计完善的方案,优选各种技术和产品,科学组织工程实施,保证建设成一个可靠性高、性价比高、易于使用、满足用户需求的系统。

    1.2.2 约束条件

    1. 政策
    2. 预算
    3. 时间
    4. 技术

    1.3 物联网工程设计原则

    1. 围绕设计目标
    2. 考虑应用要求
    3. 在需求、成本、应用、技术等因素之间寻找平衡
    4. 优先选用简单可行方案
    5. 避免简单照抄其它设计方案
    6. 具有可预见性和可扩展性

    第二章 需求分析 可行性研究

    2.1 需求分析

    目标:

    明确用户需求,为设计提供依据。

    内容:

    1. 了解背景
    2. 了解业务和安全性需求
    3. 了解物联网通信需求
    4. 物联网环境条件
    5. 信息处理能力要求
    6. 管理需求
    7. 可扩展性需求

    2.4 可行性研究

    概念:在投资决策之前,对拟建项目进行全面技术、经济分析论证的科学方法。

    目的:综合论证项目建设的必要性、财务的盈利性、经济上的合理性、技术的先进性适应性及建设条件的可能性和可行性,为投资决策提供科学依据。

    内容要求:

    1. 方案具体
    2. 内容真实
    3. 预测准确
    4. 论证严密

    第三章 网络设计

    3.1 逻辑网络设计

    逻辑网络结构描述了设备的互联和分布。

    目标

    1. 合适的运行环境
    2. 成熟稳定的技术选型
    3. 合理的网络结构
    4. 合适的运营成本
    5. 逻辑网络的可扩充性
    6. 逻辑网络的易用性
    7. 逻辑网络的可管理性
    8. 逻辑网络的安全性

    原则

    1. 先进性
    2. 高可靠性
    3. 标准化
    4. 可扩展性
    5. 易管理性
    6. 安全性
    7. 实用性
    8. 开放性

    层次化网络模型

    优点

    1. 降低网络成本
    2. 简化设计元素,易于理解,提高故障隔离程度,保证了网络的稳定性
    3. 改变一个网络节点对整体影响小

    五层模型

    研究角度

    1. 感知层
    2. 传输层
    3. 处理层
    4. 应用层

    物联网工程及实施的角度

    1. 感知层对客观世界物品或环境信息的感知(传感器)。
    2. 接入层为感知层和局域网接入汇聚层/广域网/终端用户访问网络提供支持(网卡/ZigBee模块)。
    3. 汇聚层将网络业务连接到骨干网,负责安全、流量负载、路由相关的策略。
    4. 骨干层(核心层)提供高速的数据传输,连接汇聚层,将数据传输到其他网络。
    5. 数据中心数据汇聚、存储、处理、分发。

    3.2 物理网络设计

    任务是为所涉及的逻辑网络设计特定的物理环境平台。

    第四章 数据中心设计

    任务和目标

    1. 设计高性能计算机系统
    2. 设计服务器系统
    3. 设计数据存储系统
    4. 设计核心网络
    5. 设计机房
    6. 设计机房装修方案

    4.4.2 独立磁盘冗余阵列 RAID

    把多块独立硬盘按不同方式组合形成硬盘组,提供比单个硬盘更高的存储性能 和 数据备份技术。

    第五章 物联网安全设计

    5.1 感知与标识系统安全设计

    5.1.1 RFID 系统安全设计

    RFID 使用的 4 阶段

    1. 感应
    2. 选中
    3. 认证
    4. 应用

    RFID 系统的三个特征

    1. 正确性特征,真实标签被认可
    2. 安全性特征,伪造的标签不被认可
    3. 隐私性特征,标签在未授权时不可被识别跟踪

    第八章 物联网工程实施

    实施过程

    1. 项目招投标阶段
    2. 项目启动阶段
    3. 具体实施阶段
    4. 测试阶段
    5. 项目验收阶段
    6. 售后服务和培训阶段

    第九章 物联网运行维护与管理

    测试内容

    1. 终端测试
    2. 通信线路测试
    3. 网络测试
    4. 数据中心设备测试
    5. 应用系统测试
    6. 安全测试

    测试方法

    1. 主动测试
    2. 被动测试

    ThingsBoard 简介 优缺点 应用

    ThingsBoard 是一种开源的物联网(IoT)平台,旨在帮助用户快速构建、部署和扩展物联网解决方案。它提供了一个灵活的架构和功能丰富的工具,用于连接和管理各种设备、收集和处理设备生成的数据,并通过仪表板和可视化报表展示数据。

    以下是 ThingsBoard 的一些优点:

    • 开源平台:ThingsBoard 是开源的,可以自由访问、使用和修改。这使得用户可以根据自己的需求进行定制和扩展,以满足特定的物联网应用场景。
    • 可扩展性:ThingsBoard 的架构设计具有良好的可扩展性,可以轻松地处理大规模的设备连接和数据处理需求。它支持分布式部署和集群配置,可以处理数千个设备和海量数据。
    • 多协议支持:ThingsBoard 支持多种常见的物联网通信协议,如 MQTT、CoAP、HTTP 等,使得用户可以与各种类型的设备进行连接和通信。
    • 设备管理和控制:ThingsBoard 提供了功能强大的设备管理和控制功能,包括设备注册、配置管理、远程命令和固件升级等。这使得用户可以方便地监控和管理设备状态,并进行远程控制操作。
    • 数据可视化和分析:ThingsBoard 提供了灵活的仪表板和可视化报表功能,可以实时展示设备生成的数据,并支持数据分析和报警。用户可以自定义仪表板来监控设备状态、趋势和关键指标。

    一些 ThingsBoard 的缺点可能包括:

    • 学习曲线:对于没有经验的用户来说,开始使用 ThingsBoard 可能需要一些时间来了解其概念和配置。特别是对于非技术背景的用户,可能需要一些学习和培训。
    • 自定义开发:虽然 ThingsBoard 提供了一些基本的功能和组件,但如果需要更复杂的自定义功能,可能需要进行额外的开发和定制。这可能需要一些编程知识和开发资源。

    ThingsBoard 在许多物联网应用场景中都可以应用,包括但不限于以下几个领域:

    • 工业物联网(IIoT):ThingsBoard 可以用于监控和管理工厂设备、生产线和供应链的数据。它可以提供实时数据分析、故障检测和预测维护等功能,以提高生产效率和质量。
    • 智能城市:ThingsBoard 可以用于监控和控制城市基础设施,如交通信号灯、智能路灯、垃圾桶等。它可以帮助城市管理者优化资源利用、改善交通流动性和提供智能服务。
    • 农业和环境监测:ThingsBoard 可以用于农业领域,监测土壤湿度、气象条件和农作物生长状况,以实现智能灌溉和精细化农业管理。它也可以用于环境监测,监测空气质量、水质和能源消耗等指标。
    • 物流和供应链:ThingsBoard 可以帮助物流和供应链领域监控货物的位置、温度和湿度等信息,以实现实时跟踪和预警。它可以提供实时数据分析和仓储优化,以改善物流效率和降低成本。
  • 物联网工程设计与实施实验

    要求

    一、安装部署分析开源物联网系统ThingsBoard。

    ThingsBoard安装软件及文档百度网盘:

    https://pan.baidu.com/share/init?surl=yOLXUmWXgyO9MYqDzd-aIw

    提取码:1234

    二、分析研究ThingsBoard在不同领域的应用。例如:

    1. 智慧农业监控系统;
    2. 智能家居安防系统;
    3. 物联网粮食仓储系统;
    4. 远程医疗系统:
    5. 智能停车系统;
    6. 智能无人超市系统;
    7. 文物(博物馆)预警监测系统;
    8. 平安校园系统;
    9. 智慧公交系统;
    10. 智能大厦系统等等。

    三、要求:

    1. 在上述应用领域中自选一题,基于ThingsBoard,从 需求分析、方案设计、工程实施 三方面着手,遵循 物联网工程规划与设计原则 ,实现一个较全面的物联网工程项目,撰写一份较完整的设计报告,最后要有自己对该设计的 体会与感悟 ;(也可着重进行某一方面的阐述)。一个项目不超过2人,且分 不同侧重点 独立成文。
    2. 最好10页( 20面左右 ,A4纸双面打印,带封面(包括课程名、班级、学号、姓名、任课老师、成绩等内容)。
    3. 上交时间为本课程结课时间。6.14,纸质档

    要求分析

    物联网工程规划与设计原则:

    1. 清晰的目标和用例定义:在开始物联网项目之前,明确定义项目的目标和用例非常重要。这有助于确定所需的功能和性能,并为后续的工程规划和设计提供指导。
    2. 弹性和可扩展性:考虑到物联网系统的增长和变化,设计具有弹性和可扩展性的架构是关键。系统应能够适应新设备的添加、增加处理能力和容量,并支持未来的功能扩展。
    3. 安全性和隐私保护:物联网系统需要具备安全性和隐私保护的能力。包括数据加密、身份验证和访问控制等安全措施,以确保数据的机密性和完整性,并保护用户的隐私。
    4. 设备和网络互操作性:物联网涉及多个设备和网络之间的通信和互操作性。确保设备和网络能够相互通信、交换数据,并支持不同的通信协议和标准是重要的。
    5. 数据管理和分析:物联网系统生成大量的数据,因此,合理的数据管理和分析策略至关重要。包括数据采集、存储、处理、分析和可视化等方面的设计,以从数据中提取有用的信息和洞察力。
    6. 设备生命周期管理:考虑到物联网设备的寿命周期,包括设备的部署、配置、监测、维护和更新等方面的管理是必要的。确保设备的可管理性和远程维护能力是物联网工程设计中的重要考虑因素。
    7. 故障恢复和容错能力:物联网系统需要具备故障恢复和容错能力,以应对设备故障、通信中断和其他问题。采用冗余设计、备份和恢复策略,以及监测和警报机制,可以帮助及时发现和解决问题。

    软件

    需要安装的一些软件。

    1. JDK(教程中说的是JDK11)
    2. Maven
    3. Node.js
    4. git
    5. idea
    6. PostgreSQL

    软件安装过程

    建议使用Docker

    好处是删的快,用完就删。

    安装文档

    步骤

    1. 安装 Docker Desktop 并运行
    2. 管理员终端运行 docker pull thingsboard/tb-postgres这是安装 ThingsBoard 镜像的命令。
    3. 在Docker Desktop下启动ThingsBoard,不需要多余的操作。
    4. containers里查看容器,大概如下图image-20230610165241946点 9090 端口,它映射到我电脑的 32768 端口上。
    5. 登录,密码如下
  • 传感器网络

    重点

    第一章 绪论

    第三章 WSN 拓扑控制与覆盖技术

    第四章 WSN 通信与组网技术

    第五章 WSN 支撑技术

    为重点

    题型

    选择(20,10*2)

    名词解释(10 分,5*2)

    简答 (25 分,5*5)

    分析计算(35 分)

    综合(10 分)

    WSN 定义

    WSN(Wireless Sensor Network)即无线传感器网络。

    无线传感器网络是大量的静止的或移动的传感器以自组织或多跳的方式构成的无线网络。目的是协作地探测、处理和传输网络覆盖区域内感知对象的监测信息,并报告给用户。

    WSN 特点

    1. 自组织性
    2. 以数据为中心
    3. 应用相关性
    4. 动态性
    5. 网络规模大
    6. 可靠性

    各种拓扑结构的优缺点

    平面网络结构

    特点

    1. 所有节点对等,功能特性一致。
    2. (优点)结构简单,易维护,较好健壮性。
    3. (缺点)没有中心管理节点,采用自组织协同算法,组网算法较为复杂。

    分级网络结构

    特点

    1. 网络分为上层和下层,上层为中心骨干节点,下层一般为传感器节点。
    2. 一个或多个骨干节点,骨干节点之间、一般传感器之间采用平面网络结构。
    3. 骨干节点为对等结构。
    4. 分级网络以簇的形式存在,簇首和成员节点
    5. 扩展性好,便于集中管理。降低成本,提高网络覆盖率、可靠性。
    6. 开销大,硬件成本高,一般传感器之间不能直接通信。

    混合网络结构

    特点

    1. 网络骨干节点之间、一般传感器节点之间都采用平面网络结构。网络骨干节点与一般传感器节点之间采用分级网络结构。
    2. 一般传感器节点之间可以相互通信,不需要通过汇聚骨干节点来转发数据。
    3. 相较于分级网络节点,功能更强,硬件成本更高。

    Mesh 网络结构

    特点

    1. 通常只允许节点与其邻居节点直接通信。
    2. 网络内部节点一般相同。
    3. 节点之间存在多条通信路径,较强容错能力和健壮性。
    4. 虽然不同节点是对等地位,但某个节点可以被指定为簇首,执行额外功能,簇首节点失效,可以由其他节点接替。
    5. 由无线节点构成网络。
    6. 每个节点至少可以和一个其它节点通信。
    7. 自我形成:节点可以自动加入网络,也可以自动离开网络。
    8. 自愈功能:当网络中某个节点失效时,网络可以自动调整,使得网络仍然可以正常工作。
    9. 支持多跳路由:节点可以通过多跳路由的方式与网络中的任何节点通信。
    10. 功耗限制和移动性取决于节点类型。
    11. 多种网络接入方式,星型、Mesh 等。

    定位

    定义

    根据有限的位置已知的节点(锚节点)来确定无线传感器网络中的其他节点(盲节点)的位置。

    四类定位算法

    1. 基于测距的定位算法、距离无关的定位算法。
    2. 基于锚节点定位和无锚节点辅助的定位算法。
    3. 集中式计算定位与分布式计算定位。
    4. 紧密耦合定位与松散耦合定位。

    性能分析

    1. 定位精度
    2. 规模
    3. 锚节点密度
    4. 节点密度
    5. 覆盖率
    6. 容错性和自适应性
    7. 功耗
    8. 成本

    节点位置计算方法

    1. 三边测量法
    2. 三角测量法
    3. 极大似然估计法
    4. 最小最大法

    基于测距的定位算法

    三个阶段:测距、定位、校正

    1. RSSI(Radio Signal Strength Indicator) 定位算法基于接收信号强度,将信号强度转换为距离,然后根据距离计算位置。
    2. TOA(Time of Arrival) 定位算法基于信号传播速度,根据信号传播时间计算距离,然后根据距离计算位置。
    3. TDOA(Time Difference of Arrival) 定位算法基于信号传播速度,根据信号传播时间差计算距离,然后根据距离计算位置。
    4. AOA(Angle of Arrival) 定位算法基于到达角定位机制,通过测量信号的方向,多点定位。(两条线的交点)

    距离无关的定位算法

    1. 质心定位算法
    2. 凸规划定位算法

    典型定位算法

    1. Active Badge 定位算法
    2. Active Office 定位算法
    3. Cricket 定位算法

    WSN 中存在的隐藏终端和暴露终端问题(书上未找到)

    “隐藏终端”(Hidden Stations):在通信领域,基站 A 向基站 B 发送信息,基站 C 未侦测到 A 也向 B 发送,故 A 和 C 同时将信号发送至 B,引起信号冲突,最终导致发送至 B 的信号都丢失了。”隐藏终端”多发生在大型单元中(一般在室外环境),这将带来效率损失,并且需要错误恢复机制。当需要传送大容量文件时,尤其需要杜绝”隐藏终端”现象的发生。

    暴露终端是指在发送节点的覆盖范围内而在接收节点的覆盖范围外的节点,暴露终端因听到发送节点的发送而可能延迟发送。但是,它其实是在接收节点的通信范围之外,它的发送不会造成冲突。这就引入了不必要的延时。

    隐藏终端和暴露终端问题产生的原因:

    由于 ad hoc 网络具有动态变化的网络拓扑结构,且工作在无线环境中,采用异步通信技术,各个移动节点共享同一个通信信道,存在信道分配和竞争问题;为了提高信道利用率,移动节点电台的频率和发射功率都比较低;并且信号受无线信道中的噪声、信道衰落和障碍物的影响,因此移动节点的通信距离受到限制,一个节点发出的信号,网络中的其它节点不一定都能收到,从而会出现“隐藏终端”和“暴露终端”问题。

    隐藏终端和暴露终端问题对 ad hoc 网络的影响:

    隐藏终端”和“暴露终端”的存在,会造成 ad hoc 网络时隙资源的无序争用和浪费,增加数据碰撞的概率,严重影响网络的吞吐量、容量和数据传输时延。在 ad hoc 网络中,当终端在某一时隙内传送信息时,若其隐藏终端在此时隙发生的同时传送信息,就会产生时隙争用冲突。受隐藏终端的影响,接收端将因为数据碰撞而不能正确接收信息,造成发送端的有效信息的丢失和大量时间的浪费(数据帧较长时尤为严重),从而降低了系统的吞吐量和量。当某个终端成为暴露终端后,由于它侦听到另外的终端对某一时隙的占用信息,而放弃了预约该时隙进行信息传送。其实,因为源终端节点和目的终端节点都不一样,暴 露终端是可以占用这个时隙来传送信息的。这样,就造成了时隙资源的浪费。

    隐藏终端和暴露终端问题的解决方法:

    解决隐藏终端问题的思路是使接收节点周围的邻居节点都能了解到它正在进行接收,目前实现的方法有两种:一种是接收节点在接收的同时发送忙音来通知邻居节点,即 BTMA 系列;另一种方法是发送节点在数据发送前与接收节点进行一次短控制消息握手交换,以短消息的方式通知邻居节点它即将进行接收,即 RTS/CTS 方式。这种方式是目前解决这个问题的主要趋势,如已经提出来的 CSMA/CA、MACA、MACAW 等。还有将两种方法结合起来使用的多址协议,如 DBTMA。

    对于隐藏发送终端问题,可以使用控制分组进行握手的方法加以解决。一个终端发送数据之前,首先要发送请求发送分组,只有听到对应该请求分组的应答信号后才能发送数据,而是收到此应答信号的其他终端必须延迟发送。

    在单信道条件下使用控制分组的方法只能解决隐发送终端,无法解决隐藏接收终端和暴露终端问题。为此,必须采用双信道的方法。即利用数据信道收发数据,利用控制信道收发控制信号 .

    数据融合

    概念:充分利用网络中各个节点的信息,通过一定的算法,将各个节点的信息进行融合,得到更加准确的信息。

    好处:

    1. 提高了信息的可信度、可靠性。
    2. 扩展系统的空间、时间覆盖能力。
    3. 减小系统的信息模糊程度。
    4. 改善系统的检测能力。
    5. 提高系统决策的正确性。

    分类:

    根据处理融合信息的方法不同:

    1. 集中式:所有节点的数据都发送到一个中心节点,由中心节点进行数据融合。
    2. 分布式:传感器对自己的数据单独进行处理,再将处理结果发送到中心节点,由中心节点进行数据融合。带宽要求低、计算速度快、可靠性和延续性好、系统生命力强。融合精度没有集中式高。
    3. 混合式:集中式和分布式相结合。系统结构变得复杂。

    根据融合处理的数据种类不同:

    1. 时间融合:同一传感器在不同时间对目标的测量值进行融合。
    2. 空间融合:不同传感器同一时刻对目标的测量值进行融合。
    3. 时空融合:不同传感器在一段时间内对目标的测量值进行融合。

    信息抽象程度不同:

    1. 数据级融合:对原始数据进行融合。
    2. 特征级融合:对数据进行特征提取,再进行融合。
    3. 决策级融合:对数据进行决策,再进行融合。优点:
      1. 灵活
      2. 带宽要求低
      3. 有效反映环境或目标的特征
      4. 具有容错性
      5. 通信量小,抗干扰能力强
      6. 对传感器依赖小
      7. 处理代价低

    MAC层协议中的CSMA/CA协议

    CSMA/CA协议是一种基于信道监听的MAC层协议,其工作原理是:在发送数据前,先监听信道,如果信道空闲,则发送数据;如果信道忙,则等待一段时间再监听,直到信道空闲,然后发送数据。如果信道忙,等待的时间超过了一个阈值,则放弃发送,等待下一次发送机会。

    信道(通信介质资源)分配的方式(动、静态)区别

    静态信道分配:在通信开始前,就已经确定了通信资源的分配情况,通信过程中不再改变。

    动态信道分配:通信过程中,根据通信的需要,动态地分配通信资源。

    RFID 系统的工作流程

    RFID 的定义:

    RFID(Radio Frequency Identification)射频识别技术,是一种无线通信技术,它利用电磁场自动识别标签(Tag)上的信息,存储的信息可以是一个电子产品代码,也可以是一个人的身份证号码,还可以是一个包裹的运输信息等等。

    RFID 系统的组成:

    1. RFID 标签:由芯片和天线组成,用于存储和传输数据。
    2. 阅读器:用于读取标签中的数据。

    RFID 系统的工作流程

    阅读器向标签发送激励信号,激励信号的频率与标签的工作频率相同,标签接收到激励信号后,从中提取能量,激励标签工作。

  • 软件测试复习

    题型

    判断、简答、应用、综合

    重点

    软件测试的定义

    使用人工或自动手段来运行和测定某个系统的过程,其目的在于检验系统是否 满足规定的需求 或是弄清预期结果与实际结果之间的差异。

    缺陷的概念

    质量的含义

    是产品或服务所满足明示或暗示需求能力的固有属性和特征的集合

    质量的特性

    1. 功能适应性
    2. 效率
    3. 兼容性
    4. 易用性
    5. 可靠性
    6. 安全性
    7. 可维护性
    8. 可移植性

    缺陷的定义

    1. 从产品内部看,软件缺陷是指产品开发或维护过程中存在的错误、毛病。
    2. 从外部看,软件缺陷是系统所需要实现的某种功能的失效或违背。

    缺陷的来源、构成

    1. 需求定义
    2. 初步设计
    3. 详细设计
    4. 代码

    集成

    集成是指将各个独立的软件组件(模块、子系统等)合并在一起,以验证它们在整体系统中的交互和协作是否正常工作。集成测试旨在检测不同组件之间的接口问题、数据传递问题、功能一致性以及整体系统的稳定性和可靠性。

    自动化测试的概念

    自动化测试是指使用软件来控制测试设备,执行测试用例,比较实际结果和预期结果,从而自动化地完成测试过程。

    了解什么是压力、动态、静态、回归、阿尔法(伽马、贝塔)测试

    压力测试

    压力测试是指在系统正常工作负载的情况下,通过长时间或超大负荷地运行测试软件,来测试系统的性能指标。可以了解系统可靠性、性能瓶颈。

    动态测试

    动态测试是指在软件运行时,通过运行测试用例来检测软件的功能、性能、安全性等特性。

    静态测试

    静态测试是指在软件运行之前,通过检查源代码、设计文档、用户手册等来检测软件的功能、性能、安全性等特性。

    回归测试

    回归测试是指在软件发生变更之后,通过运行测试用例来检测软件的功能、性能、安全性等特性。

    阿尔法(伽马、贝塔)测试(α测γ测β测)

    阿尔法测试是指在软件开发过程中,由软件开发者在开发环境下,通过运行测试用例来检测软件的功能、性能、安全性等特性。

    黑白盒测试

    黑盒测试

    黑盒测试是指在软件运行时,通过运行测试用例来检测软件的功能、性能、安全性等特性,但是不考虑软件内部的结构和工作原理。

    白盒测试

    白盒测试是指在软件运行时,通过运行测试用例来检测软件的功能、性能、安全性等特性,同时考虑软件内部的结构和工作原理。

    语句覆盖

    语句覆盖是指在软件运行时,要求每个语句至少被执行一次。

    判定覆盖

    判定覆盖是指在软件运行时,要求每个判定的每个可能的结果至少被执行一次。

    条件覆盖

    条件覆盖是指在软件运行时,要求每个判定的每个条件的每个可能的结果至少被执行一次。

    因果图

    因果图是一种图形化的测试用例设计方法,它将程序的逻辑结构表示为一个有向图,图中的节点表示程序中的语句,图中的边表示程序中的控制流。

    测试过程的目的是什么?

    1. 功能测试:验证每个功能是否按照事先定义的要求工作。
    2. 性能测试:评测分析系统在不同负载下的运行情况、性能指标。
    3. 安全性测试:测试系统在应对非授权的访问、故意损坏时的系统防护能力。
    4. 兼容性测试:测试系统在不同的硬件、软件、网络环境下的运行情况。也包括共存、互操作性测试。
    5. 可靠性测试:检验系统是否能保持长期稳定、正常地运行。
    6. 易用性测试:测试系统是否容易学习、使用、理解,界面美观、交互友好。
    7. 回归测试:测试系统在发生变更之后,是否仍然能够正常工作。

    软件缺陷的分级

    分级

    1. 致命的:系统崩溃、数据丢失、系统不可用、系统不稳定、系统不可恢复。
    2. 严重的:系统功能不完整、系统功能不正确、系统性能不足、系统安全性不足。
    3. 一般的:系统界面不美观、系统界面不友好、系统易用性不足、系统易学性不足。
    4. 微小的:错别字、文字排列不整齐等。

    完整软件测试的流程

    软件工程过程来看

    1. 需求评审
    2. 设计评审
    3. 单元测试
    4. 集成测试
    5. 系统测试
    6. 验收测试

    项目管理的角度看

    1. 测试计划
    2. 测试设计
    3. 执行与监控
    4. 结果分析与评估
    5. 项目总结

    接口测试概念

    验证不同软件系统、模块或组件之间的接口是否正常工作。

    接口是不同软件实体之间进行通信和交互的方式,接口测试的目的是确保这些接口能够按照规范进行正确的数据传递、请求处理和响应。

    自动化测试流程

    什么是自动化测试

    把以人为驱动的测试行为转化为机器执行的一种过程。

    流程

    1. 测试环境的搭建和设置
    2. 基于模型实现测试设计的自动化
    3. 脚本自动生成
    4. 测试数据的自动产生
    5. 测试操作步骤的自动执行
    6. 测试结果分析
    7. 测试流程的自动处理
    8. 测试报告自动生成

    上机实验的内容和原理(等价类、决策表、有效等价类和无效等价类)【不会很复杂】

    等价类

    等价类是指在测试过程中,将输入域划分为若干个子集,使得每个子集中的输入数据对于测试来说是等价的。

    1. 弱一般等价类测试
    2. 强一般等价类测试
    3. 弱健壮等价类测试
    4. 强健壮等价类测试

    一般/健壮:是否考虑无效等价类 强/弱:单缺陷假设还是多缺陷假设

    如果实现语言是强类型,则不必使用健壮形式测试。

    决策表

    决策表是一种测试设计技术,它是一种表格,用来描述系统的行为,它的每一行代表一个测试用例,每一列代表一个输入条件或一个动作。

    有效等价类和无效等价类

    有效等价类是指在测试过程中,将输入域划分为若干个子集,使得每个子集中的输入数据对于测试来说是有效的。

    无效等价类是指在测试过程中,将输入域划分为若干个子集,使得每个子集中的输入数据对于测试来说是无效的。

    边界值分析

    边界值测试是软件测试中的一种策略,旨在检测系统在边界条件下的行为和处理能力。边界值测试的基本概念是,错误和异常往往在接近数据范围的边界处发生。

    目前流行的技术怎么进行测试

    1. 单元测试
    2. 集成测试
    3. 系统测试
    4. 专项测试
    5. 软件本地化测试

    笔记

    软件测试-Sofeware Test

    测试用例-Test Case

    测试执行前设计的一套详细测试方案,包括测试环境(硬件、软件、网络)、测试步骤、测试数据、预期结果等。

    SQA – Software Quality Assurance-软件质量保证

    是一项管理性工作,侧重于对流程的评审和监控。

    Test – 测试

    是一项技术性工作,侧重于对产品的评估和验证。

    TDD – Test Driven Development-测试驱动开发

    是一种敏捷开发的技术,它要求在编写功能代码之前,先编写单元测试代码,然后只编写使单元测试通过的功能代码,从而达到测试驱动开发的目的。

    ALAC – Act Like A Customer-像一个客户一样做

    基于客户使用产品的知识开发出的测试方法

    如何降低测试规模,并保证测试的典型性?

    组合分析是一种基于每对参数组合的测试技术。

    V 模型

    一种软件开发过程模型,它将软件开发过程分为软件开发和软件测试两个部分,两个部分是对称的,相互对应。

    W 模型

    V 模型的修改版。

    1. 测试过程和开发过程同步
    2. 测试过程是对开发过程中阶段性成果和最终的产品进行验证的过程。两者相互依赖
    3. 两者各有特点,存在差异。

    判定表

    条件桩:条件(就是表头)

    动作桩:动作(结果的取值)

    条件项:条件桩中的一项的取值

    动作项:在各种条件项组合下采取的动作

    驱动程序和桩模块

    这是单元测试中的概念,在单元测试中为了隔离单元,需要用到驱动程序和桩程序。

    驱动程序:用于驱动被测程序的模块,它调用被测模块,给被测模块传递参数。

    桩程序:模拟被测模块调用的下级模块。当被测模块依赖于其它单元,测试时为了隔离被测模块,需要用桩程序来模拟被测模块调用的下级模块。

    JUnit 5 的常用注解

    1. @Test:标记测试方法
    2. @ParameterizedTest:参数化测试
    3. @RepeatedTest:重复测试
    4. @TestFactory:动态测试
    5. @BeforeEach:在每个测试方法之前执行
    6. @AfterEach:在每个测试方法之后执行
    7. @BeforeAll:在所有测试方法之前执行
    8. @AfterAll:在所有测试方法之后执行
    9. @TestTemplate:测试模板
    10. @TestMethodOrder:测试方法的执行顺序
    11. @DisplayName:测试方法的显示名称
  • Git 学习记录

    Git CMD 和 Git Bash

    • Git CMD 是让 Git 在 Windows CMD 里执行命令,也可以执行 Windows 原生命令。
    • Git Bash 是模拟 Linux 终端环境,支持 Linux 命令。

    Git 基础配置

    配置 Git 用户信息

     git config --global user.name "你的用户名"
     git config --global user.email "你的邮箱"

    说明:

    • --global 表示对当前电脑所有仓库生效。
    • user.nameuser.email 是每个提交的作者信息,记录在 commit 中。

    查看当前配置

     git config --list

    创建和管理仓库

    在 GitHub 上新建仓库

    1. 登录 GitHub,点击右上角“+”,选择“New repository”。
    2. 填写仓库名称,点击“Create repository”。
    3. 复制远程仓库地址,例如:
     https://github.com/你的用户名/你的仓库名.git

    克隆远程仓库

     git clone [email protected]:用户名/仓库名.git

    或 HTTPS:

     git clone https://github.com/用户名/仓库名.git

    本地项目上传流程

    假设本地已有项目目录 my_project/

     cd my_project             # 进入项目目录
     git init                  # 初始化 Git 仓库
     git add .                 # 添加所有文件
     git commit -m "首次提交"   # 本地提交
     git branch -M main        # 将默认分支改名为 main(推荐)
     git remote add origin https://github.com/你的用户名/你的仓库名.git  # 添加远程仓库
     git push -u origin main   # 推送到 GitHub 并设置上游分支

    以后更新项目的流程

     git add .                  # 添加改动文件
     git commit -m "更新说明"    # 提交改动
     git push                   # 推送到远程仓库

    快速创建新项目并上传示例

     mkdir new_project && cd new_project
     echo "# My Project" > README.md
     git init
     git add .
     git commit -m "init"
     git remote add origin https://github.com/你的用户名/你的仓库.git
     git push -u origin main

    Git 常用操作与状态管理

    查看仓库状态

    git status

    查看提交历史

    git log

    简洁版:

    git log --oneline --graph --all

    撤销操作

    • 撤销暂存:
    git reset HEAD <文件名>
    • 撤销工作区修改(恢复到最后一次提交):
    git checkout -- <文件名>
    • 修改最后一次提交信息:
    git commit --amend

    删除分支

    • 删除本地分支:
    git branch -d <分支名>
    • 强制删除未合并本地分支:
    git branch -D <分支名>
    • 删除远程分支:
    git push origin --delete <分支名>

    分支管理

    创建分支

    git branch <分支名>

    切换分支

    git checkout <分支名>
    git switch <分支名>

    创建并切换分支

    git checkout -b <分支名>

    合并分支

    git merge <另一个分支>

    在当前分支执行,合并另一个分支内容到当前分支。

    变基操作

    git rebase <另一个分支>

    使当前分支基于另一个分支的最新提交重新应用,保持提交历史线性。


    处理远程冲突

    当 push 被拒绝,提示:

    error: failed to push some refs

    通常是远程有新的提交,本地未同步。

    解决方法:

    git pull origin main --rebase
    git push origin main

    强制推送的风险

    ⚠️ 强制推送命令:

    git push -f

    会覆盖远程历史,使用前需确认风险,避免覆盖他人工作。


    .gitignore 文件

    用于忽略不想提交的文件,如:

    *.log
    node_modules/
    .env

    Git SSH 连接配置流程

    生成 SSH Key

    ssh-keygen -t ed25519 -C "备注信息"

    参数说明:

    • ssh-keygen:生成 SSH 密钥对。
    • -t ed25519:密钥算法类型,推荐使用 ed25519。
    • -C:注释,便于识别。

    默认保存在 ~/.ssh/id_ed25519,可用 -f 自定义文件名:

    ssh-keygen -t ed25519 -C "备注" -f ~/.ssh/自定义文件名

    添加公钥到 GitHub

    1. 查看公钥内容:
    cat ~/.ssh/id_ed25519.pub

    或自定义路径:

    cat ~/.ssh/自定义文件名.pub
    1. 登录 GitHub:
    • 头像 → Settings → SSH and GPG keys → New SSH key
    • 填写 Title,粘贴公钥内容,保存。

    修改远程仓库地址为 SSH 格式

    查看远程地址:

    git remote -v

    修改为 SSH 地址:

    git remote set-url origin [email protected]:你的用户名/你的仓库名.git

    配置 SSH 使用自定义密钥(可选)

    编辑或创建 ~/.ssh/config 文件:

    Host github.com
    HostName github.com
    User git
    IdentityFile ~/.ssh/自定义密钥文件名

    测试 SSH 连接

    ssh -T [email protected]

    成功显示:

    Hi 你的用户名! You've successfully authenticated, but GitHub does not provide shell access.

    失败则显示 Permission denied (publickey),需检查配置。

    推送代码

    git add .
    git commit -m "首次提交"
    git push origin main

    若远程已有内容,先拉取再推送:

    git pull origin main --rebase
    git push origin main

    SSH 多账户配置(进阶)

    配置多个 SSH Key:

    Host github-personal
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_personal

    Host github-work
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_work

    克隆或推送时用对应别名:

    git clone git@github-personal:用户名/仓库.git

    SSH Key 权限设置

    私钥权限要正确:

     chmod 600 ~/.ssh/id_ed25519

    权限过宽可能导致 SSH 拒绝使用密钥。


    设置默认推送分支

    首次推送时用:

     git push -u origin main

    以后只需:

     git push

    GPG 签名(进阶)

    用于保证提交身份真实性:

     git commit -S -m "message"

  • 射频识别与传感器技术

    头大,学的什么东西。By the way,图还得我自己来。

    PDF放前面,Markdown放这里。

    题型

    1. 选择题 10 分
    2. 名词解释 25 分
    3. 简答题 36 分
    4. 计算分析 15 分
    5. 论述 14 分

    测量方法

    根据获得测量值的方法

    1. 直接测量 实际结果 = 测量结果 y = x
    2. 间接测量 实际结果 y = 一个测得值 x 或多个测得值 x1,x2,…,xn 的函数。 y = f(x) y = f(x1,x2,…,xn)
    3. 组合测量 若实际结果必须经过求解联立方程组求得,称为组合测量。 如:$$
      \left\{\begin{matrix}x_{1}=f_{1}(y_{1},y_{2},…,y_{m}) \\x_{2}=f_{2}(y_{1},y_{2},…,y_{m}) \\\vdots \\x_{3}=f_{3}(y_{1},y_{2},…,y_{m}) \end{matrix}\right.
      $$

    根据测量方式

    1. 偏差式测量 仪表指针的位移决定被测量的量值。精度较低。
    2. 零位式测量 用指零仪表的零位反映测量系统的平衡状态,测量系统平衡时,用已知的标准量决定被测量的量值。
    3. 微差式测量 将被测量与已知标准量相比较,取得差值后,用偏差法测得此值。

    根据测量条件

    1. 等精度测量 影响和决定误差大小的全部因素始终保持不变。
    2. 不等精度测量 不同测量条件下,用不同精度的仪表,不同的测量方法,不同的测量次数,不同的测量者。

    根据被测量变化快慢

    1. 静态测量 被测量在测量过程中固定不变。不需要考虑时间因素对测量的影响。
    2. 动态测量 被测量在测量过程中不断变化。

    根据测量敏感元件是否与被测介质接触

    1. 接触式测量
    2. 非接触式测量

    根据测量系统是否向被测对象施加能量

    1. 主动式测量
    2. 被动式测量

    检测系统的构成

    传感器感受被测量的大小,并输出相对应的输出信号。

    信号调理电路对传感器输出的电信号进行处理。

    显示器将所得信号变成人的感官可以接受的信号。

    数据处理装置对测得的数据进行处理、运算、分析、对动态测试结果进行频谱分析。

    执行机构通断、控制、调节、保护。

    传感器的静态特性和动态特性

    静态特性

    1. 灵敏度$$
      S=\frac{\Delta y}{\Delta x}
      $$
      输出量增量与输入量增量之比。S 越大越灵敏。输入输出特性曲线上某点的斜率就是灵敏度
    2. 线性度 传感器的输出与输入之间数量关系的线性程度。
    3. 迟滞 相同工作条件下,输入量由小到大(正行程)及输入量由大到小(反行程)变化期间其输入输出特性曲线不重合的现象称为迟滞。差值称为迟滞差值。最大迟滞差值 ΔHmax 与满量程输出值 YFS 称为迟滞误差,用 γH 表示。$$
      \gamma_{H}=\frac{\Delta H_{max}}{Y_{FS}}\times 100\%
      $$
    4. 重复性 相同工作条件下,输入量按同一方向做全量程连续多次变化时,所得特性曲线不一致的程度。
    5. 漂移 输入量不变,输出量随时间变化。

    动态特性

    输入量随时间变化时传感器的响应特性。


    金属应变片的工作原理

    电阻应变效应:导体在外界作用下产生机械变形(拉伸 / 压缩)时,其电阻值相应发生变化。

    被测量使弹性元件产生应变,应变再由应变片产生相应的电阻变化,因而通过测量电阻,可以得到被测量的大小。

    半导体应变片工作原理

    半导体材料的电阻率 ρ 随作用应力的变化而变化。

    电阻应变片测量电路

    不平衡电桥

    $$
    易知,E_{D} = E,E_{A} = 0. \\ 初状态为平衡,故有 \\ E_{B} = E_{C} \\ 即有 \\ \frac{R_{2}}{R_{1}}=\frac{R_{4}}{R_{3}} \\ 当 R_{1} 变化,有 \\ E_{B}=E \cdot (\frac{R_{1}+\Delta R_{1}}{R_1+R_2+\Delta R_1})\\ E_C=E \cdot (\frac{R_3}{R_3+R_4})=E \cdot (\frac{R_1}{R_1+R_2})\\ 此时 U_0=E_B-E_C\\ 由糖水不等式,显然 E_B>E_C\\ \begin{split} U_0&=E\cdot \frac{(R_1+\Delta R_1)(R_1+R_2)-R_1(R_1+R_2+\Delta R_1)}{(R_1+R_2+\Delta R_1)(R_1+R_2)}\\ &=E\cdot\frac{\Delta R_1\cdot R_2}{(R_1+R_2)^2+\Delta R_1(R_1+R_2)} \end{split}\\ 相对于 (R_1+R_2)^2 来说,\Delta R_1(R_1+R_2) 可忽略不计\\ 分数上下同除以 R_1^2,令 n=\frac{R_2}{R_1}\\ 故\\ U_0=\frac{n}{(1+n)^2} \cdot \frac{\Delta R_1}{R_1}\cdot E
    $$

    自感式电感传感器工作原理

    利用线圈自感量的变化测量。

    传感器的运动部分与衔铁相连,被测量变化时,衔铁产生位移,引起磁路中电阻变化,使得电感线圈的电感量变化,测量出这种变化,就能确定衔铁位移量大小和方向。

    差动变压器式传感器工作原理

    变压器的次级线圈产生感应电压,两个相同的次级线圈接成差动的形式,即反向串联,即成为差动变压器。铁芯做成活动的,则变成差动变压器式传感器。铁芯运动时,在次级绕组中产生感应电势,测量这种电势即可得到被测量。

    衔铁向上运动,则 U2 > 0。

    电涡流式传感器工作原理

    块状金属导体置于变化的磁场中或在磁场中做切割磁感线运动时,导体内将产生旋涡状的感应电流,称为电涡流。

    当传感器激励线圈通过交变电流 I1 ,线圈周围产生交变磁场 H1 ,使得置于此磁场中的被测导体产生电涡流 I2 ,产生反向的新的交变磁场 H2。使得传感器激励线圈的电感量、阻抗、品质因数变化,即线圈等效阻抗发生变化。

    线圈等效阻抗 Z的变化与被测金属导体电阻率 ρ磁导率 μ几何形状/尺寸因子 r激磁电流频率 f线圈与被测金属导体的距离 x有关,若使得其中一个为变量,其它因素不变,则可通过测量 Z 来测量这个变化量。

    电容式传感器的工作原理

    将被测非电量的变化转换成电容量变化。

    平行板电容器的电容如下

    $$
    C=\frac{\varepsilon A}{d}\\ \\ \varepsilon-平行板间介质介电常数\\ A-极板所覆盖的面积\\ d-极板间距离
    $$

    当被测参数变化使得式中某一参数变化,就可以把参数变化转换为电容变化,通过测量电路就可转换为电量输出。

    分类

    1. 变极距型
    2. 变面积型
    3. 变介质型

    压电效应、逆压电效应

    某些电介质当沿着一定方向对其施力而使其变形时,内部产生极化现象,同时在它两个表面上产生符号相反的电荷,外力去掉后,又重新恢复到不带电的状态,称为 压电效应

    当在电介质极化方向施加电场时,电介质也会产生几何变形,称为 逆压电效应

    霍尔传感器原理与应用

    霍尔效应

    置于磁场中的静止载流导体,当它的电流方向与磁场方向不一致时,载流导体上垂直于电流和磁场的方向上将产生电势差,该电势差称为霍尔电势差。

    应用

    1. 霍尔式位移传感器
    2. 霍尔式转速传感器
    3. 霍尔计数装置

    光电式传感器

    外光电效应

    在光线作用下,物体内电子逸出物体表面向外发射的现象。

    这种电子称为光电子。

    内光电效应

    在光线作用下,物体的导电性能发生变化或产生光生电动势的效应。

    两类

    1. 光电导效应 在光线作用下,半导体材料吸收入射光子能量,若能量大于等于半导体材料的禁带宽度,就激发出 电子 – 空穴对,使载流子浓度增加,半导体导电性增加,阻值减低。是光敏电阻的原理。
    2. 光生伏特效应 光线的作用下能够使物体产生一定方向的电动势的现象。是光电池的原理。

    光敏电阻

    无光照时,光敏电阻阻值很大,电路中电流很小。被一定波长的光范围的光照后,其阻值急剧减小,电路中电流迅速增大。

    光敏二极管

    没有光照射时,反向电阻很大,反向电流很小。被光照射时,形成光电流,光照强度越大,光电流越大。

    因此不受光照射时,光敏二极管处于截止状态,而受到光照射时,光敏二极管处于导通状态。

    光敏三极管

    集电极电流是光电流的 β 倍,因此光敏晶体管具有放大作用。

    光电池

    原理是光生伏特效应,其本质是一个大面积的 PN 结,当光照射到 PN 结的一个面,光子能量大于半导体材料的禁带宽度,电池每吸收一个光子就产生一对自由电子和空穴,电子 – 空穴对从表面向内扩散,建立一个和光照强度有关的电动势。

    光电耦合器件

    是由发光元件(如发光二极管)和光电接收元件(如光敏二极管、光敏三极管等)合并使用,以光作为媒介把输入端的电信号耦合到输出端的一种器件。

    1. 用于实现电隔离的光电耦合器 有时可以取代继电器、变压器、斩波器。
    2. 用于检测物体位置或有无物体的光电开关

    体积小、寿命长、无触点、抗干扰能力强、输出输入绝缘、可以单向传输 模拟信号或数字信号。

    光电开关的工作原理

    光电开关是一种利用感光元件对变化的入射光加以吸收,并进行光电转换,同时加以某种形式的放大和控制,从而获得最终的控制输出“开”“关”信号的器件。

    气敏传感器的工作原理

    原理:利用气体在半导体表面的氧化和还原反应导致敏感元件阻值变化。当氧化型气体吸附到 N 型半导体上,还原型气体吸附到 P 型半导体上时,半导体载流子减少,使电阻值增大。将上述条件反过来则使其电阻值减小。

    湿敏传感器的工作原理

    湿敏传感器是能够感受外界湿度变化,并通过器件材料的物理或化学性质变化,将湿度转化成有用信号的器件。

    超声波传感器的工作原理与应用

    利用超声波在超声场中的物理特性和各种效应而研制的装置称为超声波传感器、换能器或探测器。

    超声波探头:是超声波的发射器和接收器。

    压电式:利用压电材料的逆压电效应把高频电振动转换成高频机械振动,产生超声波。利用压电效应把超声振动转换为电信号,接收超声波。

    应用:

    1. 超声波物位传感器:超声波物位传感器是利用超声波在两种介质的分界面上的反射特性制成的。如果从发射超声脉冲开始,到接收探头接收到反射波为止的这个时间间隔为已知,就可以求出分界面的位置,利用这种方法可以对物位进行测量。
    2. 超声波流量传感器:超声波流量传感器的测定方法是多样的,但目前应用较广的主要是超声波传播速度变化法。超声波在流体中传播时,在静止流体和流动流体中的传播速度是不同的,利用这一特点可以求出流体的速度,再根据横截面积,便可以知道流体的流量。

    红外感应系统的工作原理

    红外辐射的本质是热辐射,温度低的物体辐射的红外线波长长,温度高的物体辐射的红外线波长短。在一般常温下,所有物体都是红外辐射的发射源,但发射的红外波长不同。红外感应实际就是根据物体因表面温度不同会发出不同波段的红外光这一特性进行检测的。

    编码器的原理与应用

    原理

    编码器是将角位移和线位移转换成数字量的一种数字传感器,它以高精度、高分辨率和高可靠性被广泛用于各种位移的测量。

    应用

    1. 角度位置测量
    2. 数字测速

    热电传感器

    热电偶测温原理

    两种不同材料的导体(或半导体)组成一个闭合回路,当两接点温度 T 和 T0 不同时,则在该回路中就会产生电动势,这种现象称为热电效应,该电动势称为热电势。这两种不同材料的导体或半导体的组合称为热电偶,导体 A、B 称为热电极。

    三个基本定律

    中间温度定律 在热电偶测温回路中,tc为热电极上某一点的温度,热电偶 AB 在接点温度为 t、t0 时的热电势 EAB( t, t0) 等于热电偶 AB 在接点温度 t、tc 和 tc、t0 时的热电势 EAB( t, tc ) 和 EAB( tc, t0) 的代数和,即$$
    E_{AB}(t,t_0)=E_{AB}(t,t_C)+E_{AB}(t_C,t_0)
    $$

    均质导体定律 由两种均质导体组成的热电偶,其热电动势的大小只与两材料及两接点温度有关,与热电偶的大小尺寸、形状及沿电极各处的温度分布无关。这条定理说明:热电偶必须由两种不同性质的均质材料构成。

    中间导体定律 在热电偶测温回路内,接入第三种导体时,只要第三种导体的两端温度相同,则对回路的总热电势没有影响。

  • 八段数码管显示解析

    “8段数码管显示”工程解析

    现象:数码管显示“12345678”。

    源代码如下:

    int main()
    {
        Stm32_Clock_Init( 6 );  //传入一个8位二进制数,是倍频系数,使得PLL倍频。也对时钟进行了使能。
        delay_init( 72 );       //延时初始化,就是对系统滴答定时器的初始化。设置了延时倍乘数。
        LED_Init();             //LED使能和初始化。
        LED_SEL = 0;
        show_w1=1;
        show_w2=2;
        show_w3=3;
        show_w4=4;
        show_w5=5;
        show_w6=6;
        show_w7=7;
        show_w8=8;
        while(1)
        {
    
            SetLed(0, show_w1%10);
            delay_ms(1);
            SetLed(1, show_w2%10);
            delay_ms(1);
            SetLed(2, show_w3%10);
            delay_ms(1);
            SetLed(3, show_w4%10);
            delay_ms(1);
            SetLed(4, show_w5%10);
            delay_ms(1);
            SetLed(5, show_w6%10);
            delay_ms(1);
            SetLed(6, show_w7%10);
            delay_ms(1);
            SetLed(7, show_w8%10);
            delay_ms(1);
        }
    }

    此为库函数版。

    库函数解析:

    Stm32_Clock_Init();

    //定义
    //时钟初始化
    void Stm32_Clock_Init(u8 PLL)//传入一个8位的二进制数
    {
        unsigned char temp=0;   
        MYRCC_DeInit();       //复位并配置向量表
        RCC->CR|=0x00010000;  //外部高速时钟使能HSEON
        /*
        HSEON:外部高速时钟使能 (External high-speed clock enable) 
        由软件置’1’或清零。
        */
        while(!(RCC->CR>>17));//等待外部时钟就绪
        RCC->CFGR=0X00000400; //APB1=DIV2;APB2=DIV1;AHB=DIV1;
        PLL-=2;//抵消2个单位
        RCC->CFGR|=PLL<<18;   //设置PLL值 2~16
        RCC->CFGR|=1<<16;     //PLLSRC ON 
        FLASH->ACR|=0x32;     //FLASH 2个延时周期
        //repare
    
        RCC->CR|=0x01000000;  //PLLON
        while(!(RCC->CR>>25));//等待PLL锁定
        RCC->CFGR|=0x00000002;//PLL作为系统时钟    
        while(temp!=0x02)     //等待PLL作为系统时钟设置成功
        {   
            temp=RCC->CFGR>>2;
            temp&=0x03;
        }    
    }            

    总结:

    传入一个8位二进制数,是倍频系数(范围2~16),使得PLL倍频。也对时钟进行了使能和初始化。配置了向量表,复位和配置了相关外设。

    传参类型:u8

    u8是unsigned char类型,8位二进制。

    时钟树

    HSE(High Speed External Clock signal):高速外部时钟信号

    HSI(High Speed Internal Clock signal):高速内部时钟信号

    LSE(Low Speed External Clock signal):低速外部时钟信号

    LSI(Low Speed Internal Clock signal):低速内部时钟信号

    USB预分频器:48MHz,连接USB。

    APB1(低速)外设:UART2,TIMER2等。

    APB2(高速)外设:UART1,SPI1等。

    PLL锁相环:
    作用:

    ​ 抬高频率。

    输入:

    ​ HSE和HSI,通过PLLSRC选择(通过寄存器PLLCFGR的第22位决定:0:HSI;1:HSE)。

    输出:

    ​ PLLCLK(系统时钟)和PLL48CLK。PLLCLK在多路选择开关处,根据需要传给SYSCLK。

    MYRCC_DeInit(void)

    //把所有时钟寄存器复位
    void MYRCC_DeInit(void)
    {                                                               
        RCC->APB1RSTR = 0x00000000;//复位结束             
        RCC->APB2RSTR = 0x00000000; 
    
        RCC->AHBENR = 0x00000014;  //睡眠模式闪存和SRAM时钟使能.其他关闭.      
        RCC->APB2ENR = 0x00000000; //外设时钟关闭.               
        RCC->APB1ENR = 0x00000000;   
        RCC->CR |= 0x00000001;     //使能内部高速时钟HSION                                                                 
        RCC->CFGR &= 0xF8FF0000;   //复位SW[1:0],HPRE[3:0],PPRE1[2:0],PPRE2[2:0],ADCPRE[1:0],MCO[2:0]                     
        RCC->CR &= 0xFEF6FFFF;     //复位HSEON,CSSON,PLLON
        RCC->CR &= 0xFFFBFFFF;     //复位HSEBYP          
        RCC->CFGR &= 0xFF80FFFF;   //复位PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE 
        RCC->CIR = 0x00000000;     //关闭所有中断
        //配置向量表    
    
        #ifdef  VECT_TAB_RAM
        MY_NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
        #else   
        MY_NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
        #endif
        //配置中断向量表基址和偏移量
    }

    实际上是设置了向量表的复位,外设的复位,关闭所有中断。。

    RCC结构体
    /*------------- Reset and Clock Control --------------*/
    typedef struct
    {
      vu32 CR;        //时钟控制寄存器
      vu32 CFGR;    //时钟配置寄存器
      vu32 CIR;        //时钟中断寄存器
      vu32 APB2RSTR;//APB2 外设复位寄存器
      vu32 APB1RSTR;//APB1 外设复位寄存器
      vu32 AHBENR;    //AHB外设时钟使能寄存器
      vu32 APB2ENR;    //APB2 外设时钟使能寄存器
      vu32 APB1ENR;    //APB1 外设时钟使能寄存器
      vu32 BDCR;    //备份域控制寄存器
      vu32 CSR;        //控制/状态寄存器
    } RCC_TypeDef;    

    向量表的定义。

    vu32(无符号长整型)
    typedef volatile unsigned long  vu32;

    注意到RCC结构体中寄存器的格式是 vu32 。vu32 即 volatile unsigned long

    volatile即“易变的”。

    C++会对代码进行优化,内部不影响IO的代码并不会被编译。

    int main() {
        int i = 0;
        i++;
        cout << "hello world" << endl;
    }

    按照代码,这个程序会在内存中预留int大小的空间,初始化这段内存为0,然后这段内存中的数据加1,最后输出“hello world”到标准输出中。

    但是根据这段代码编译出来的程序(加-O2选项),不会预留int大小的内存空间,更不会对内存中的数字加1。他只会输出“hello world”到标准输出中。

    编译器为了优化代码,修改了程序的逻辑。实际上C++标准是允许写出来的代码和实际生成的程序不一致的。

    虽说优化代码是件好事情,但是也不能让编译器任意修改程序逻辑,不然的话我们没办法写可靠的程序了。所以C++对这种逻辑的改写是有限制的,这个限制就是在编译器修改逻辑后,程序对外界的IO依旧是不变的。

    怎么理解呢?实际上我们可以把我们写出来的程序看做是一个黑匣子,如果按照相同的顺序输入相同的输入,他就每次都会以同样的顺序给出同样的输出。这里的输入输出包括了标准输入输出、文件系统、网络IO、甚至一些system call等等,所有程序外部的事物都包含在内。

    所以对于程序使用者来说,只要两个黑匣子的输入输出是完全一致的,那么这两个黑匣子是一致的,所以编译器可以在这个限制下任意改写程序的逻辑。这个规则又叫as-if原则。

    volatile关键字的作用

    volatile让该变量的地位相当于输入输出,不能改变顺序,不能忽略。所以类似取消优化。

    RCC->CR|=0x00010000;

    第16位:外部高速时钟使能HSEON

    HSEON:外部高速时钟使能 (External high-speed clock enable)

    由软件置’1’或清零。

    while(!(RCC->CR>>17));

    RCC_CR中第17位是HSERDY,即外部时钟就绪位,当外部时钟就绪时,HSERDY位就等于1了,RCC-CR>>17语句将第17位移到第0位,于是RCC-CR就等于0x00000001了,(!(RCC-CR>>17))值即为0了,while(!(RCC-CR>>17))就执行完了。

    RCC->CFGR=0X00000400;

    CFGR的第10位设为1。

    PPRE1[2:0]:低速APB预分频(APB1) (APB low-speed prescaler (APB1))

    由软件置’1’或清’0’来控制低速APB1时钟(PCLK1)的预分频系数。

    警告:软件必须保证APB1时钟频率不超过36MHz。

    0xx:HCLK不分频

    100:HCLK 2分频

    101:HCLK 4分频

    110:HCLK 8分频

    111:HCLK 16分频

    此处是置为100,即HCLK2分频。

    PLL-=2; RCC->CFGR|=PLL<<18;

    此两步是设置了倍频系数,倍频系数设置如下图

    RCC->CFGR|=1<<16;

    设置了CFGR第16位。

    PLLSRC:PLL输入时钟源 (PLL entry clock source)

    由软件置’1’或清’0’来选择PLL输入时钟源。

    只能在关闭PLL时才能写入此位。

    0:HSI振荡器时钟经2分频后作为PLL输入时钟

    1:HSE时钟作为PLL输入时钟。

    RCC->CR|=0x01000000;

    第24位置1,作用是PLL使能。

    PLLON:PLL使能 (PLL enable)

    由软件置’1’或清零。

    当进入待机和停止模式时,该位由硬件清零。

    当PLL时钟被用作或被选择将要作为系统时钟 时,该位不能被清零。

    0:PLL关闭;

    1:PLL使能。

    while(!(RCC->CR>>25));

    等待PLL时钟锁定。

    PLLRDY:PLL时钟就绪标志 (PLL clock ready flag)

    PLL锁定后由硬件置’1’。

    0:PLL未锁定;

    1:PLL锁定。

    RCC->CFGR|=0x00000002;

    PLL输出作为系统时钟;

    SW[1:0]:系统时钟切换 (System clock switch)

    由软件置’1’或清’0’来选择系统时钟源。

    在从停止或待机模式中返回时或直接或间接作为系统时钟的HSE出现故障时,由硬件强制选择 HSI作为系统时钟(如果时钟安全系统已经启动)

    00:HSI作为系统时钟;

    01:HSE作为系统时钟;

    10:PLL输出作为系统时钟;

    11:不可用

    delay_init();

    延时初始化,就是对系统滴答定时器的初始化。设置了延时倍乘数。

    传参:8位二进制数。

    推挽输出

    推挽输出既可以输出低电平,也可以输出高电平,可以直接驱动功耗不大的数字器件。可以理解成,输出0,1。

    CPU 写 1,外部引脚输出高电平。

    CPU 写 0,外部引脚输出低电平。

    开漏输出

    CPU 写 0,外部引脚接地。

    CPU 写 1,外部引脚悬空。

    LED_Init()

    LED初始化。

    LED_SEL = 0;

    总结:

    操作 用 GPIOB_ODR_Addr 和 n 初始化的地址 的内存空间。n = 3 。赋值为0

    BITBAND(addr, bitnum)

    #define BITBAND(addr, bitnum) ((addr & 0xF000 0000)+0x200 0000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
    1. 将 addr 高四位(28~31)设为1。第25位+1。
    2. 只保留addr的低20位(0-19),左移5位(5-24)。加上bitnum左移2位的数值。

    两步相加。为BITBAND(addr, bitnum)。是一个初始化的地址。

    MEM_ADDR(addr)

    #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 

    MEM_ADDR(addr)表示addr地址处的值。

    BIT_ADDR(addr, bitnum)

    #define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))

    BIT_ADDR(addr, bitnum) 表示用addr和bitnum初始化的地址的值。

    PBout(n)

    #define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)

    表示用 GPIOB_ODR_Addr 和 n 初始化的地址的值。或者说取地址处的内存空间进行操作。

    GPIOB_ODR_Addr是 (GPIOB_BASE+12) 即 0x40010C0C 。n仍然是一个“偏移量”,实际上是寄存器内的“地址”。

    什么是偏移量?

    ​ 例如GPIOA_BASE = (APB2PERIPH_BASE + 0x0800) 。而 GPIOA 又包含几个寄存器。

    ​ 所以每个寄存器都有一定偏移量。相当于寄存器在这个 GPIO 中的位置。

    LED_SEL

    #define LED_SEL PBout(3) 

    即 n = 3 ;

    show_w

    定义:无符号字符类型,8位二进制。

    void SetLed(u8 w, u8 value)

    void SetLed(u8 w, u8 value)
    {
        SEL0 = w%2;             //取w第0位
        SEL1 = w/2%2;           //取w第1位
        SEL2 = w/4;             //取w第2位
        LedValue(segTable[value]);
    }
    #define SEL0 PBout(0)
    #define SEL1 PBout(1)
    #define SEL2 PBout(2)
    /***************************数码管段选***************************/
    u8 segTable[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
    void LedValue(u8 value)
    {
        GPIOE->ODR &= ~(0xff<<8);       //清除数据,只保留低8位
        GPIOE->ODR |= value<<8;         //设置8~15位
    }

    SetLed 函数传入两个参数,第一个是位选,第二个是段选

    void delay_ms(u16 nms)

    void delay_ms(u16 nms)
    {                  
        u32 temp;          
        SysTick->LOAD=(u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit)
        SysTick->VAL =0x00;           //清空计数器
        SysTick->CTRL=0x01 ;          //开始倒数  
        do
        {
            temp=SysTick->CTRL;
        }
        while(temp&0x01&&!(temp&(1<<16)));//等待时间到达   
        SysTick->CTRL=0x00;       //关闭计数器
        SysTick->VAL =0X00;       //清空计数器           
    }

    延时函数,以ms为单位。