ZigBee案例笔记 - 无线点灯

news2024/11/29 22:46:16

文章目录

      • 无线点灯实验概述
      • 工程关键字
      • 工程文件夹介绍
      • Basic RF软件设计框图简单说明
      • 工程操作
        • Basic RF启动流程
        • Basic RF发送流程
        • Basic RF接收流程
      • 无线点灯案例
      • 无线点灯现象

无线点灯实验概述

ZigBee无线点灯实验(即Basic RF工程),由TI公司提供的学习例程,是入门ZigBee无线通讯的经典实验,暂时没有用到协议栈,但实验所体现出来的数据发送、接收和使用协议栈的数据通讯模式是差不多的,而且 TI 公司的 Basic RF 工程代码段都有进行注释容易看懂及运用,将这个实验掌握后,将可以更好的过渡到协议栈的内容学习

工程关键字

学习无线控制实验需要线简单了解以下几个关键字

  • CCM - Counter with CBC-MAC (mode of operation)
  • HAL - Hardware Abstraction Layer (硬件抽象层)
  • PAN - Personal Area Network (个人局域网)
  • RF - Radio Frequency (射频)
  • RSSI - Received Signal Strength Indicator (接收信号强度指示)

实验中用到的Basic RF 工程源码CC2530 BasicRF.rar需要用户到TI官网注册下载,所下载的案例源码仅针对TI公司的ZigBee开发板进行配置的,烧录到其他ZigBee开发板需要修改配置后才能正常使用

工程文件夹介绍

Basic RF工程下载连接 TI官网Basic RF工程压缩包下载
拿到工程源码CC2530 BasicRF.rar解压后可以看到目录下有3个文件夹,如图分别是docs文件夹、ide文件夹和source文件夹
在这里插入图片描述
将docs文件夹、ide文件夹和source文件夹展开后如下
在这里插入图片描述
docs文件夹
打开文件夹里面仅有一个名为 CC2530_Software_Examples 的 PDF 文档,文档的主要内容是介绍 BasicRF 的特点、结构及使用,如果使用 TI 的开发板的话阅读这个文档就可以做 Basic RF 里面的实验了,阅读文档可以知道,Basic RF工程包含三个实验例程:无线点灯、传输质量检测、谱分析应用
ide文件夹
打开文件夹后会有三个文件夹和一个 cc2530_sw_examples.eww 工程,这个工程是上面提及的三个实验例程工程的集合,也包含了无线点灯的实验工程,在IAR 环境中打开,在 workspace 看到3个实验工程如图
在这里插入图片描述
ide\settings文件夹
在每个基础实验的文件夹里面都会有的,主要保存用户工程的 IAR 环境配置

ide\srf05_cc2530\iar文件夹
这里放有三个工程,light_switch.eww、per_test.eww、spectrum_analyzer.eww,如果不习惯cc2530_sw_examples.eww 工程中几个工程集合在一起看,可以在这里直接对应的实验工程

source文件夹
文件夹里面有 apps 文件夹和 components 文件夹

source\apps文件夹
存放 Basic RF 三个实验(light_switch、per_test、spectrum_analyzer)的应用实现的源代码,即用户代码存放的地方

source\components文件夹
包含 BasicRF 的应用程序使用不同组件的源代码

Basic RF软件设计框图简单说明

在这里插入图片描述
Hardware layer
硬件层,在最底下,是实现数据传输的基础

Hardware Abstraction layer
它提供了一种接口来访问 TIMER,GPIO,UART,ADC 等硬件资源,这些接口都通过相应的函数进行实现

Basic RF layer
为双向无线传输提供一种简单的协议,Basic RF 由 TI 公司提供,它包含了 IEEE 802.15.4 标准的数据包的收发功能但并没有使用到协议栈,它仅仅是是让两个结点进行简单的通信,也就是说Basic RF 仅仅是包含着 IEEE 802.15.4 标准的一小部分而已。其主要特点有:

  • 不会自动加入协议、也不会自动扫描其他节点也没有组网指示灯(LED3)。
  • 没有协议栈里面所说的协调器、路由器或者终端的区分,节点的地位都是相等的。
  • 没有自动重发的功能。

Basic RF layer 为双向无线通信提供了一个简单的协议,通过这个协议能够进行数据的发送和接收

Application layer
是用户应用层,它相当于用户使用 Basic RF 层和 HAL 的接口,也就是说我们通过在 Application layer 就可以使用到封装好的 Basic RF 和 HAL 的函数

工程操作

TI的Basic RF工程目录下CC2530 BasicRF\ide\srf05_cc2530\iar\light_switch.eww打开无线点灯工程
在这里插入图片描述
Basic RF 还提供了安全通信所使用的 CCM-64 身份验证和数据加密,它的安全性可以通过在工程文件里面定义 SECURITY_CCM,右键工程列表打开Option,如图工程中不需要启用安全通信加密,在SECURITY_CCM前面加上x,取消加密
在这里插入图片描述

Basic RF启动流程

确保外围器件没有问题,创建一个 basicRfCfg_t 的数据结构,并初始化其中的成员,在basic_rf.h 代码中可以找到结构体定义

/***********************************************************************************
* TYPEDEFS
*/

typedef struct {
    uint16 myAddr;				//16 位的短地址(就是节点的地址) 
    uint16 panId;				//节点的 PAN ID
    uint8 channel;				//RF 通道(必须在 11-26 之间)
    uint8 ackRequest;			//目标确认就置 true 
#ifdef SECURITY_CCM				//是否加密,预定义里取消了加密
    uint8* securityKey;
    uint8* securityNonce;
#endif
} basicRfCfg_t;

调用 basicRfInit()函数进行RF无线通信协议的初始化,在 basic_rf.c 代码中可以找到函数定义,函数对 Basic RF 的数据结构初始化,设置节点的传输通道,短地址,PAN ID

uint8 basicRfInit(basicRfCfg_t* pRfConfig)
{
    if (halRfInit()==FAILED)
        return FAILED;

    halIntOff();

    // Set the protocol configuration
    pConfig = pRfConfig;
    rxi.pPayload   = NULL;

    txState.receiveOn = TRUE;
    txState.frameCounter = 0;

    // Set channel
    halRfSetChannel(pConfig->channel);

    // Write the short address and the PAN ID to the CC2520 RAM
    halRfSetShortAddr(pConfig->myAddr);
    halRfSetPanId(pConfig->panId);

    // if security is enabled, write key and nonce
    #ifdef SECURITY_CCM
    basicRfSecurityInit(pConfig);
    #endif

    // Set up receive interrupt (received data or acknowlegment)
    halRfRxInterruptConfig(basicRfRxFrmDoneIsr);

    halIntOn();

    return SUCCESS;
}
Basic RF发送流程

创建一个buffer存放无线发送的指令,调用 basicRfSendPacket()函数发送,并查看其返回值,在 basic_rf.c 中可以找到函数定义,其中传参为目标节点的短地址 destAddr,发送的buffer指针 pPayload 和buffer长度 length,调用函数给目的短地址发送指定长度的数据,发送成功时返回 SUCCESS,失败则返回 FAILED

uint8 basicRfSendPacket(uint16 destAddr, uint8* pPayload, uint8 length)
{
    uint8 mpduLength;
    uint8 status;

    // Turn on receiver if its not on
    if(!txState.receiveOn) {
        halRfReceiveOn();
    }

    // Check packet length
    length = min(length, BASIC_RF_MAX_PAYLOAD_SIZE);

    // Wait until the transceiver is idle
    halRfWaitTransceiverReady();

    // Turn off RX frame done interrupt to avoid interference on the SPI interface
    halRfDisableRxInterrupt();

    mpduLength = basicRfBuildMpdu(destAddr, pPayload, length);

    #ifdef SECURITY_CCM
    halRfWriteTxBufSecure(txMpdu, mpduLength, length, BASIC_RF_LEN_AUTH, BASIC_RF_SECURITY_M);
    txState.frameCounter++;     // Increment frame counter field
    #else
    halRfWriteTxBuf(txMpdu, mpduLength);
    #endif

    // Turn on RX frame done interrupt for ACK reception
    halRfEnableRxInterrupt();

    // Send frame with CCA. return FAILED if not successful
    if(halRfTransmit() != SUCCESS) {
        status = FAILED;
    }

    // Wait for the acknowledge to be received, if any
    if (pConfig->ackRequest) {
        txState.ackReceived = FALSE;

        // We'll enter RX automatically, so just wait until we can be sure that the ack reception should have finished
        // The timeout consists of a 12-symbol turnaround time, the ack packet duration, and a small margin
        halMcuWaitUs((12 * BASIC_RF_SYMBOL_DURATION) + (BASIC_RF_ACK_DURATION) + (2 * BASIC_RF_SYMBOL_DURATION) + 10);

        // If an acknowledgment has been received (by RxFrmDoneIsr), the ackReceived flag should be set
        status = txState.ackReceived ? SUCCESS : FAILED;

    } else {
        status = SUCCESS;
    }

    // Turn off the receiver if it should not continue to be enabled
    if (!txState.receiveOn) {
        halRfReceiveOff();
    }

    if(status == SUCCESS) {
        txState.txSeqNumber++;
    }

#ifdef SECURITY_CCM
    halRfIncNonceTx();          // Increment nonce value
#endif

    return status;
}
Basic RF接收流程

调用basicRfPacketIsReady()函数检测节点是否准备好读取新的数据包,在 basic_rf.c 中可以找到函数定义,如果准备好则返回TURE

uint8 basicRfPacketIsReady(void)
{
    return rxi.isReady;
}

调用 basicRfReceive()函数,把收到的数据复制到接收节点的buffer 中,代码可以在 basic_rf.c 中可以找到函数定义,函数接收来自 Basic RF 层的数据包,并为所接收的数据和 RSSI 值配置缓冲区

uint8 basicRfReceive(uint8* pRxData, uint8 len, int16* pRssi)
{
    // Accessing shared variables -> this is a critical region
    // Critical region start
    halIntOff();
    memcpy(pRxData, rxi.pPayload, min(rxi.length, len));
    if(pRssi != NULL) {
        if(rxi.rssi < 128){
            *pRssi = rxi.rssi - halRfGetRssiOffset();
        }
        else{
            *pRssi = (rxi.rssi - 256) - halRfGetRssiOffset();
        }
    }
    rxi.isReady = FALSE;
    halIntOn();

    // Critical region end

    return min(rxi.length, len);
}

无线点灯案例

上面的配置流程了解了无线点灯的代码配置流程后,开始修改工程源码,无线点灯实验需要用到2块ZigBee节点板,一块作为ZigBee无线发送节点(按键发送无线指令),另一块作为ZigBee无线接收节点(接收无线指令控灯),在Basic RF工程中功能实现的代码都在light_switch.c文件中,开头用宏定义配置了节点主要参数,包含发送节点和接收节点的16位短地址、RF通道、PAN ID等关键参数

/***********************************************************************************
* CONSTANTS
*/
// Application parameters
#define RF_CHANNEL                25      // 2.4 GHz RF channel

// BasicRF address definitions
#define PAN_ID                0x2007
#define SWITCH_ADDR           0x2520
#define LIGHT_ADDR            0xBEEF
#define APP_PAYLOAD_LENGTH        1
#define LIGHT_TOGGLE_CMD          0

// Application states
#define IDLE                      0
#define SEND_CMD                  1

// Application role
#define NONE                      0
#define SWITCH                    1
#define LIGHT                     2
#define APP_MODES                 2

创建发送节点和接收节点的buffer,创建节点结构体

/***********************************************************************************
* LOCAL VARIABLES
*/
static uint8 pTxData[APP_PAYLOAD_LENGTH];
static uint8 pRxData[APP_PAYLOAD_LENGTH];
static basicRfCfg_t basicRfConfig;

在main函数里有很多配置是实验中用不到的,比如LCD屏幕显示、遥感按键操作等,可以直接屏蔽不需要的代码部分,修改后的main函数如下(屏蔽部分已删除,详细可自行查看工程),main函数中配置了发送节点/接收节点的结构体共同部分(PAN_ID、RF_CHANNEL、TRUE),初始化板级硬件和RF无线功能、关闭板载LED,然后是按照不同节点进入不同的节点函数进行循环(发送节点进入appSwitch()函数,屏蔽appLight()函数,接收节点进入appLight()函数,屏蔽appSwitch()函数),工程不会运行到HAL_ASSERT(FALSE)函数,以下为发送节点的main函数

void main(void)
{

    // Config basicRF
    basicRfConfig.panId = PAN_ID;
    basicRfConfig.channel = RF_CHANNEL;
    basicRfConfig.ackRequest = TRUE;
#ifdef SECURITY_CCM
    basicRfConfig.securityKey = key;
#endif

    // Initalise board peripherals
    halBoardInit();

    // Initalise hal_rf
    if(halRfInit()==FAILED) {
      HAL_ASSERT(FALSE);
    }

    // Indicate that device is powered
    halLedClear(1);
    halLedClear(2);
    
    //无线点灯核心函数
    appSwitch();
//    appLight();
    
    // Role is undefined. This code should not be reached
    HAL_ASSERT(FALSE);
}

发送节点函数appSwitch(),将点灯指令放到pTxData发送数组中,配置发送节点短地址后初始化节点结构体,发送节点不需要做无线接收调用basicRfReceiveOff()函数关闭无线接收功能;在while循环中判断按键是否按下,按下则调用basicRfSendPacket()函数发送无线信息,LED2闪烁提示无线信息已发送,随后进入低功耗模式等待按键再次按下

static void appSwitch()
{
#ifdef ASSY_EXP4618_CC2420
    halLcdClearLine(1);
    halLcdWriteSymbol(HAL_LCD_SYMBOL_TX, 1);
#endif

    pTxData[0] = LIGHT_TOGGLE_CMD;

    // Initialize BasicRF
    basicRfConfig.myAddr = SWITCH_ADDR;
    if(basicRfInit(&basicRfConfig)==FAILED) {
      HAL_ASSERT(FALSE);
    }

    // Keep Receiver off when not needed to save power
    basicRfReceiveOff();

    // Main loop
while (TRUE) {
// 按键判断
        if( halButtonPushed() == HAL_BUTTON_1 ) {

            basicRfSendPacket(LIGHT_ADDR, pTxData, APP_PAYLOAD_LENGTH);
            HAL_LED_TGL_2();
            halMcuWaitMs(50);
            HAL_LED_TGL_2();

            // Put MCU to sleep. It will wake up on joystick interrupt
            halIntOff();
            halMcuSetLowPowerMode(HAL_MCU_LPM_3); // Will turn on global
            // interrupt enable
            halIntOn();

        }
    }
}

接收节点函数appLight()(需要屏蔽main函数中的appSwitch()),配置接收节点短地址后初始化节点结构体,basicRfReceiveOn()函数打开无线接收功能,在while循环中检测接收节点是否做好接收无线数据包的准备,然后判断是否收到数据包;在收到数据包后判断无线指令是否为点灯指令,是的话闪烁LED2提示成功接收无线消息,将LED1状态进行反转完成控灯操作

static void appLight()
{
//    halLcdWriteLine(HAL_LCD_LINE_1, "Light");
//    halLcdWriteLine(HAL_LCD_LINE_2, "Ready");
    
#ifdef ASSY_EXP4618_CC2420
    halLcdClearLine(1);
    halLcdWriteSymbol(HAL_LCD_SYMBOL_RX, 1);
#endif

    // Initialize BasicRF
    basicRfConfig.myAddr = LIGHT_ADDR;
    if(basicRfInit(&basicRfConfig)==FAILED) {
      HAL_ASSERT(FALSE);
    }
    basicRfReceiveOn();

    // Main loop
    while (TRUE) {
        while(!basicRfPacketIsReady());

        if(basicRfReceive(pRxData, APP_PAYLOAD_LENGTH, NULL)>0) {
            if(pRxData[0] == LIGHT_TOGGLE_CMD) {
                HAL_LED_TGL_2();
                halMcuWaitMs(50);
                HAL_LED_TGL_2();
                halLedToggle(1);
            }
        }
    }
}

如果所用到的ZigBee开发板并不是TI公司的开发板,需要检查工程中的按键引脚和LED引脚定义是否可以直接应用到所用的ZigBee开发板上,在hal_board.h文件中找到LED和按键的端口引脚宏定义,按照ZigBee开发板原理图做对应修改

// LEDs
#define HAL_BOARD_IO_LED_1_PORT        1   // Green
#define HAL_BOARD_IO_LED_1_PIN         0
#define HAL_BOARD_IO_LED_2_PORT        1   // Red
#define HAL_BOARD_IO_LED_2_PIN         1
#define HAL_BOARD_IO_LED_3_PORT        1   // Yellow
#define HAL_BOARD_IO_LED_3_PIN         4
#define HAL_BOARD_IO_LED_4_PORT        0   // Orange
#define HAL_BOARD_IO_LED_4_PIN         1


// Buttons
#define HAL_BOARD_IO_BTN_1_PORT        1   // Button S1 by YUAN
#define HAL_BOARD_IO_BTN_1_PIN         2

无线点灯现象

工程编译成功后分别上传至ZigBee发送节点和ZigBee接收节点
在这里插入图片描述
按下发送节点的按键进行控制指令发送,观察接收节点板的LED1状态
在这里插入图片描述

在这里插入图片描述

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

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

相关文章

neovim调试linux内核过程中索引不到对应头文件问题

大家好&#xff0c;我叫徐锦桐&#xff0c;个人博客地址为www.xujintong.com&#xff0c;github地址为https://github.com/jintongxu。平时记录一下学习计算机过程中获取的知识&#xff0c;还有日常折腾的经验&#xff0c;欢迎大家访问。 一、环境 neovim–0.9.4 mason的clang…

中小微医院机构云服务(云HIS)平台源码

云HIS&#xff08;Cloud-Based Healthcare Information System&#xff09;重新定义了HIS&#xff0c;目标是为中小型医疗卫生机构提供优质经济的医疗卫生信息化产品及服务&#xff1b;是以健康档案为主线、以电子病历为核心、以云计算技术为基础的医疗卫生系统。云HIS作为基于…

GoogleNetv1:Going deeper with convolutions更深的卷积神经网络

文章目录 GoogleNetv1全文翻译论文结构摘要1 引言2 相关工作3 动机和高层考虑稀疏矩阵 4 结构细节引入1x1卷积核可以减少通道数 5 GoogleNet6 训练方法7 ILSVRC 2014 分类挑战赛设置和结果8 ILSVRC 2014检测挑战赛设置和结果9 总结 论文研究背景、成果及意义论文图表 GoogleNet…

【小沐学Python】Python实现免费天气预报获取(OpenWeatherMap)

文章目录 1、简介1.1 工具简介1.2 费用1.3 注册1.4 申请key 2、接口说明2.1 One Call 3.02.2 Current Weather and Forecasts collection2.2.1 API 调用2.2.2 API 参数 2.3 Historical Weather collection2.4 Weather Maps collection2.5 Other weather APIs 3、接口测试3.1 例…

无监督学习(下)

1.高斯混合模型(GMM) (1)简单概念 高斯混合模型是一种概率模型&#xff0c;它假定实例是由多个参数未知的高斯分布的混合生成的。从单个高斯分布生成的所有实例都形成一个集群&#xff0c;通常看起来像一个椭圆。每个集群都可以由不同的椭圆形状&#xff0c;大小&#xff0c;密…

【C# 技术】 C# 常用排序方式——自定义数据排序

C# 常用排序方式——自定义数据排序 前言 在最近的项目中经常会对C#中的数据进行排序&#xff0c;对于基本数据类型&#xff0c;其排序方式比较简单&#xff0c;只需要调用内置算法即可实现&#xff0c;但对于自定义数据类型以及自定义排序规则的情况实现起来就比较麻烦&…

美团到店终端从标准化到数字化的演进之路

总第580篇 | 2023年第032篇 本文整理自美团技术沙龙第76期《大前端研发协同效能提升与实践》。前端团队在产研多角色协同形式上存在不同阶段&#xff0c;而大前端多技术栈在各阶段都有其独特的实践&#xff0c;同时又有类似的演进路线。本文从到店终端团队移动端和前端技术栈持…

最详细GIT学习笔记

1. Git简介 1.1. Git介绍 Git(读音为/gɪt/) 是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从很小到非常大的项目版本管理。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 1.2. 主流的版本控制器 Git(分布式…

金融帝国实验室(Capitalism Lab)官方正版游戏『2024新年特卖优惠』

「金融帝国实验室」&#xff08;Capitalism Lab&#xff09;Enlight 官方正版游戏「2024新年特卖」 ■优惠时限&#xff1a;2024.01.01&#xff5e;01.31 ■游戏开发商&#xff1a;Enlight Software Ltd. 请您认准以下官方正版游戏购买链接&#xff1a;支持“支付宝&am…

【数据结构-单链表】(C语言版本)

今天分享的是数据结构有关单链表的操作和实践&#xff08;图解法&#xff0c;图变化更利于理解&#xff09; 记录宗旨&#x1f4dd;&#xff1a; 眼&#xff08;脑&#xff09;过千遍&#xff0c;不如手过一遍。 我们都知道单链表是一种常见的链表数据结构&#xff0c;由一系列…

【Delphi】IOS上架踩坑记 - 2024年第一天

目录 一、前言&#xff1a; 二、IOS程序上架网址 三、踩坑记 1. 关于版本中的 CFBundleIdentifier 参数&#xff08;Transporter 提示&#xff09; 2. IOS APP 程序图标要求&#xff08;Transporter 提示&#xff09; 3. 关于版本中的 CFBundleShortVersionString 参数&a…

小波理论与应用:理解小波

1 简介 来自源的信号通常处于时域。例如正弦信号、生物医学信号等。任何时域信号都可以使用数学变换进行处理或变换到频域&#xff08;谱域&#xff09;。傅里叶变换是一种流行或著名的变换&#xff0c;它将时域信号转换为频域信号&#xff0c;而不失一般性。 在绘制时域信号…

智能客服系统要素分析:提升客户满意度与工作效率的关键要素

智能客服系统是企业建立完善服务框架的重要工具。市面上存在着形态各异的各种客服系统&#xff0c;如何选择一款最适合自己企业的产品是很多采购人员想知道的问题。事实上&#xff0c;不同的智能客服系统之间的主要功能并未存在太大的区别&#xff0c;它们往往会在一些亮点功能…

m系列mac配置Tomcat

配置上走了些弯路 翻了不少博客各有各的说法&#xff0c;此说明是本人亲自尝试&#xff0c;电脑是m芯片mbp如果不是mac系统&#xff0c;勿跟风尝试 一、下载和安装Tomcat 1.下载 首先&#xff0c;打开Tomcat官网&#xff1a;https://tomcat.apache.org&#xff0c;选择Downlo…

oracle 9i10g编程艺术-读书笔记1

根据书中提供的下载代码链接地址&#xff0c;从github上找到源代码下载地址。 https://github.com/apress下载好代码后&#xff0c;开始一段新的旅行。 设置 SQL*Plus 的 AUTOTRACE 设置 SQL*Plus 的 AUTOTRACE AUTOTRACE 是 SQL*Plus 中一个工具&#xff0c;可以显示所执行…

计算机网络物理层 习题答案及解析

2-1 下列选项中&#xff0c;不属于物理层接口规范定义范畴的是&#xff08; D &#xff09;。 A. 引脚功能 B. 接口形状 C. 信号电平 D. 传输媒体 【答案】D 【解析】 2-2 某网络在物理层规定&#xff0c;信号的电平范围为- 15V~15V &#xff0c; 电线长…

tp5+workman(GatewayWorker) 安装及使用

一、安装thinkphp5 1、宝塔删除php禁用函数putenv、pcntl_signal_dispatch、pcntl_wai、pcntl_signal、pcntl_alarm、pcntl_fork&#xff0c;执行安装命令。 composer create-project topthink/think5.0.* tp5 --prefer-dist 2、配置好站点之后&#xff0c;浏览器打开访问成…

VSCode使用Remote SSH远程连接Windows 7

结论 VSCode Server不能启动&#xff0c;无法建立连接。 原因 .vscode-server 目录中的 node.exe 无法运行。 原因是Node.js仅在Windows 8.1、Windows Server 2012 R2或更高版本上受支持。 由于vscode基于node.js v14&#xff0c;不支持Windows 7操作系统。 另&#xff…

为即将到来的量子攻击做好准备的 4 个步骤

当谈到网络和技术领域时&#xff0c;一场风暴正在酝酿——这场风暴有可能摧毁我们数字安全的根本结构。这场风暴被称为 Q-Day&#xff0c;是即将到来的量子计算时代的简写&#xff0c;届时量子计算机的功能将使最复杂的加密算法变得过时。 这场量子革命正以惊人的速度到来&am…

LVM和磁盘配额

一&#xff1a;LVM概述&#xff1a; LVM 是 Logical Volume Manager 的简称&#xff0c;译为中文就是逻辑卷管理。 能够在保持现有数据不变的情况下&#xff0c;动态调整磁盘容量&#xff0c;从而提高磁盘管理的灵活性 /boot 分区用于存放引导文件&#xff0c;不能基于LVM创建…