当前位置: 首页 > news >正文

ESP32学习笔记_FreeRTOS(6)——Event and Notification

摘要(From AI):
这篇博客详细介绍了 FreeRTOS 中的事件组和任务通知机制,讲解了事件组如何通过位操作实现任务间的同步与通信,以及任务如何通过通知机制进行阻塞解除和数据传递。博客提供了多个代码示例,展示了如何使用事件组和任务通知在多任务环境中实现任务同步,特别适用于任务间的依赖关系和信号传递

前言:本文档是本人在依照B站UP:Michael_ee的视频教程进行学习时所做的学习笔记,可能存在疏漏和错误,如有发现,敬请指正。

文章目录

    • Event Group
      • Event Group Wait
        • xEventGroupCreate()
        • xEventGroupSetBits()
        • xEventGroupWaitBits()
        • Example Code:Event Group Synchronization with Multiple Tasks
      • Event Group Sync
        • xEventGroupSync()
        • Example Code:Event Group Synchronization
    • Notification
      • Notification Sync
        • xTaskNotifyGive()
        • ulTaskNotifyTake()
        • Example Code:Simple Task Notification in FreeRTOS
      • Notification Value
        • xTaskNotify()
        • xTaskNotifyWait()
        • Example Code:Task Notification with Conditional Actions Based on Values

参考资料
Michael_ee 视频教程
freeRTOS官网
espressif 在线文档


Event Group

事件组是一种同步机制,用于任务之间的通信。它们允许任务设置、清除和等待多个事件的组合

每个事件组有多个位,任务可以操作这些位来表示不同的状态或事件。

关键功能

  • 位操作​事件组可以被看作是一个二进制位的集合,任务可以对这些位进行设置、清除和等待
  • 同步机制​任务可以等待事件组中的某些位变为设定状态(例如,位为1),这样可以使任务在等待某些事件发生时暂停执行,直到事件发生
  • 多任务通信​事件组可以在多个任务之间传递信息

使用场景

  • 在多个任务之间传递控制信号或数据标志
  • 实现任务之间的依赖关系,如任务A完成某项工作后,任务B才可以执行

Event Group Wait

xEventGroupCreate()

创建一个新的事件组,并返回可以引用创建的事件组的句柄

事件组包含的标志位(或位)的数量依赖于 configUSE_16_BIT_TICKS​ 配置项

  • 如果 configUSE_16_BIT_TICKS = 1​,则事件组有 8 位(标志位)

  • 如果 configUSE_16_BIT_TICKS = 0​,则事件组有 24 位(标志位)

  • 配置文件路径(v5.3.1)idf\v5.3.1\esp-idf\components\freertos\config\include\freertos

#include "FreeRTOS.h"
#include "event_groups.h"EventGroupHandle_t xEventGroupCreate( void );

返回值

EventGroupHandle_t​创建了事件组,返回的值是创建的事件组的句柄

NULL​无法创建事件组,因为可用的 FreeRTOS 堆内存不足

xEventGroupSetBits()

在RTOS事件组中设置位

  • 这个函数不能从中断中调用
#include "FreeRTOS.h"
#include "event_groups.h"EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToSet );

参数

xEventGroup​需要设置 bit 的事件组

uxBitsToSet​一个按位的值,表示要在事件组中设置的一个或多个位

  • 通过设置不同的二进制值来指定要等待的位

    • 如果想等待 bit 0 和 bit 2 设置,uxBitsToWaitFor​ 应该是 0x05​(即 00000101​)
    • 如果想等待 bit 0、bit 1 和 bit 2 设置,uxBitsToWaitFor​ 应该是 0x07​(即 00000111​)
  • 可以根据需求组合多个位来构造不同的掩码值

返回值

EventBits_t​事件组中各位(bits)在调用 xEventGroupSetBits()​ 函数返回时的状态

可能被改变状态的情况

  1. 自动清除(xClearBitsOnExit​ 参数

    1. 当调用 xEventGroupSetBits()​ 设置位后,可能有任务正在等待这些位(通过 xEventGroupWaitBits()​),如果等待任务设置了 xClearBitsOnExit​ 参数为 pdTRUE​,则这些位在任务被唤醒时会自动被清除,在 xEventGroupSetBits()​ 返回时,返回值中的位可能已经被清除
  2. 高优先级 Task 清除位

    1. 如果设置事件位后,有更高优先级的任务因这些位的设置从阻塞状态切换为就绪状态(Ready),并立即执行,它可能会修改事件组的值

xEventGroupSetBits()​ 返回时,返回值可能反映的是任务执行后事件组的状态,而不是立即设置位后的状态

xEventGroupWaitBits()

读取RTOS事件组中的位,可选择进入阻塞状态(带超时)以等待一个位或一组位被设置

  • 这个函数不能从中断中调用
#include "FreeRTOS.h"
#include "event_groups.h"EventBits_t xEventGroupWaitBits( const EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait );

参数

xEventGroup​需要测试(查看)bit 的事件组

uxBitsToWaitFor​一个位运算值,用于指定在事件组中要等待的位

  • 不能被设置为0

xClearOnExit​设置是否清除事件

  • pdTRUE

    • 如果设置为 pdTRUE​,那么在函数返回时,事件组中由 uxBitsToWaitFor指定的那些位会被清除(即设置为 0),前提是函数返回的原因不是超时
    • 这通常用于在检测到某些事件发生后,自动清除事件状态,避免其他任务误判这些事件仍然有效。
  • pdFALSE

    • 如果设置为 pdFALSE​,事件组中的位不会被清除,即便函数成功返回。这种方式适用于需要让其他任务也能检测到这些位的场景

xWaitForAllBits​决定任务等待位时的逻辑条件是 逻辑 AND(等待所有指定的位都被设置)还是 逻辑 OR(只需等待任意一个指定的位被设置)

  • pdTRUE​(逻辑 AND)

    • 函数会等待事件组中的所有指定位都被设置为 1
    • 如果所有位在等待时间内都被设置,函数返回
    • 如果等待时间到期(xTicksToWait​ 超时),函数返回超时结果
  • pdFALSE​(逻辑 OR)

    • 函数会等待事件组中的任意一个指定位被设置为 1
    • 如果任意一位在等待时间内被设置,函数立即返回
    • 如果等待时间到期且没有任何位被设置,函数返回超时结果

xTicksToWait​等待一个/全部 bit 的最大时间

返回值

EventBits_t​事件组的当前值,这个值表示函数返回时,事件组中哪些位(bits)是被设置(1)的

Example Code:Event Group Synchronization with Multiple Tasks
#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"#include "freeRTOS/event_groups.h"EventGroupHandle_t eventGroup;#define BIT_0 (1 << 0)
#define BIT_4 (1 << 4)void Task1(void *pvParam)
{printf("Task1 is running\n");while (true){printf("Task1 is begin to wait\n");// xEventGroupWaitBits(eventGroup, BIT_0 | BIT_4, pdTRUE, pdFALSE, portMAX_DELAY);// // 检测第一位和第四位是否被设置,如果设置则唤醒Task1// // 检测完成后,第一位和第四位将被清除// printf("BIT_0 or BIT_4 is set, Task1 is woken up\n");xEventGroupWaitBits(eventGroup, BIT_0 | BIT_4, pdTRUE, pdTRUE, portMAX_DELAY);printf("BIT_0 or BIT_4 is set, Task1 is woken up\n");vTaskDelay(pdMS_TO_TICKS(1000));}
}void Task2(void *pvParam)
{printf("Task2 is running\n");vTaskDelay(pdMS_TO_TICKS(1000));while (true){printf("Task2 is begin to set bit0\n");xEventGroupSetBits(eventGroup, BIT_0);vTaskDelay(pdMS_TO_TICKS(5000));printf("Task2 is begin to set bit4\n");xEventGroupSetBits(eventGroup, BIT_4);vTaskDelay(pdMS_TO_TICKS(5000));}
}void app_main(void)
{eventGroup = xEventGroupCreate(); // 创建事件组if (eventGroup == NULL){printf("Event group creation failed\n");}else{vTaskSuspendAll();xTaskCreatePinnedToCore(Task1, "Task1", 2048, NULL, 1, NULL, 0);xTaskCreatePinnedToCore(Task2, "Task2", 2048, NULL, 1, NULL, 0);xTaskResumeAll();}
}

Event Group Sync

wait​和sync​的不同:

wait

等待事件组的 Task(设为 waitTask) 在进入 wait 状态后,等待设置事件组的 Task(设为 setTask)对事件组进行设置,waitTask 在检测到事件组满足要求后继续运行,setTask 在调用xEventGroupSetBits()​后不阻塞,继续运行

sync

setTask 在设置事件组的目标位后进入阻塞状态,等待其它 setTask 对事件组进行设置,当满足各 setTask 对事件组的要求后,所有进入阻塞状态的 setTask 同时进入运行状态

即 setTask 在设置事件组之后也在 wait 事件组

xEventGroupSync()

在事件组中设置位,然后等待在同一事件组中设置位的组合

此功能通常用于同步多个任务(通常称为任务集合),其中每个任务在继续之前必须等待其他任务到达同步点

如果uxBitsToWaitFor​参数指定的位被设置或在该时间内被设置,则该函数将在其时间到期之前返回,这种情况下,由uxBitsToWaitFor​指定的所有位将在函数返回之前自动清除

这个函数不能从中断中调用

#include "FreeRTOS.h"
#include "event_groups.h"EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait );

参数

xEventGroup​需要设置 bit 的时间组

uxBitsToSet​一个位运算值,用于指定在事件组中要设置的位

uxBitsToWaitFor​一个位运算值,用于指定在事件组中要等待的位

xTicksToWait​等待 bits 的最大时间

返回值

EventBits_t​表示事件组的状态,具体包括以下两种情况:

  1. 等待的位被设置

    • 如果 xEventGroupSync()​ 返回是因为所有等待的位被设置,则返回值是事件组中这些位在被清除前的状态
  2. 超时到期

    • 如果 xEventGroupSync()​ 返回是因为超时时间到期,则可能并非所有等待的位都被设置,返回值表示超时时事件组的状态

Example Code:Event Group Synchronization
#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"#include "freeRTOS/event_groups.h"EventGroupHandle_t eventGroup;#define BIT_0 (1 << 0)
#define BIT_1 (1 << 1)
#define BIT_2 (1 << 2)
#define ALL_SYNC_BITS (BIT_0 | BIT_1 | BIT_2)void Task0(void *pvParam)
{printf("Task0 is running\n");while (true){vTaskDelay(pdMS_TO_TICKS(1000));printf("Task0 set BIT_0\n");xEventGroupSync(eventGroup, BIT_0, ALL_SYNC_BITS, portMAX_DELAY); // 设置 BIT_0,进入同步等待printf("Task0 sync\n");vTaskDelay(pdMS_TO_TICKS(5000));}
}void Task1(void *pvParam)
{printf("Task1 is running\n");while (true){vTaskDelay(pdMS_TO_TICKS(3000));printf("Task1 set BIT_1\n");xEventGroupSync(eventGroup, BIT_1, ALL_SYNC_BITS, portMAX_DELAY);printf("Task1 sync\n");vTaskDelay(pdMS_TO_TICKS(5000));}
}void Task2(void *pvParam)
{printf("Task2 is running\n");while (true){vTaskDelay(pdMS_TO_TICKS(6000));printf("Task2 set BIT_2\n");xEventGroupSync(eventGroup, BIT_2, ALL_SYNC_BITS, portMAX_DELAY);printf("Task2 sync\n");vTaskDelay(pdMS_TO_TICKS(5000));}
}void app_main(void)
{eventGroup = xEventGroupCreate(); // 创建事件组if (eventGroup == NULL){printf("Event group creation failed\n");}else{vTaskSuspendAll();xTaskCreatePinnedToCore(Task0, "Task0", 2048, NULL, 1, NULL, 0);xTaskCreatePinnedToCore(Task1, "Task1", 2048, NULL, 1, NULL, 0);xTaskCreatePinnedToCore(Task2, "Task2", 2048, NULL, 1, NULL, 0);xTaskResumeAll();}
}

Notification

每个任务都有一个 32 位的通知值,该值在任务创建时初始

任务通知是直接发送给任务的事件,它可以解除接收任务的阻塞,并可选择更新接收任务的通知值

通知值有两种用法:按位、增量

Notification Sync

xTaskNotifyGive()

使目标任务的通知值递增

  • RTOS 任务通知功能在默认情况下是启用的,并且可以从构建中排除(每个任务节省8字节)通过在 FreeRTOSConfig.h​ 设置configUSE_TASK_NOTIFICATIONS​为0
#include "FreeRTOS.h"
#include "task.h"BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );

参数

xTaskToNotify​被通知的任务的句柄,其通知值递增(增量用法

返回值

总是返回pdPASS

ulTaskNotifyTake()

任务可以使用 ulTaskNotifyTake()​ 来选择性地阻塞,等待通知值变为非零,在任务的通知值不为零时返回

在退出时可以选择将通知值清零(此时通知值类似于二值信号量)或将通知值递减(此时通知值更像计数信号量)

#include "FreeRTOS.h"
#include "task.h"uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );

参数

xClearCountOnExit

  • pdFALSE

    • 每次成功调用后通知值减 1,类似计数信号量的效果
  • pdTRUE

    • 每次成功调用后通知值重置为 0,类似二值信号量的效果

xTicksToWait​等待通知的最大时间

返回值

任务的通知值在被递减或清除之前的值

Example Code:Simple Task Notification in FreeRTOS
#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"#include "freeRTOS/event_groups.h"TaskHandle_t task0Handle = NULL;
TaskHandle_t task1Handle = NULL;void Task0(void *pvParam)
{printf("Task0 is running\n");while (true){printf("Task0 is waitting for notification\n");ulTaskNotifyTake(pdTRUE, portMAX_DELAY);printf("Task0 got notification\n"); // Task0 等待 Task1 的通知vTaskDelay(pdMS_TO_TICKS(1000));}
}void Task1(void *pvParam)
{printf("Task1 is running\n");vTaskDelay(pdMS_TO_TICKS(5000));while (true){printf("Task1 is sending notification\n");xTaskNotifyGive(task0Handle); // Task1 通知 Task0vTaskDelay(pdMS_TO_TICKS(5000));}
}void app_main(void)
{vTaskSuspendAll();xTaskCreatePinnedToCore(Task0, "Task0", 2048, NULL, 1, &task0Handle, 0);xTaskCreatePinnedToCore(Task1, "Task1", 2048, NULL, 1, &task1Handle, 0);xTaskResumeAll();
}

Notification Value

xTaskNotify()

用于直接向任务发送事件并解除阻塞,并可选地以以下方式之一更新接收任务的通知值

  • 将一个 32 位的数字写入通知值
  • 增加一个(增量)通知值
  • 设置一个或多个通知值
  • 保持通知值不变
#include "FreeRTOS.h"
#include "task.h"BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );

参数

xTaskToNotify​被通知的 Task 句柄

ulValue​用于更新被通知任务的通知值,如何解释 ulValue 取决于 eAction 参数的值

eAction

  • eNoAction​任务被通知,但通知值不变
  • eSetBits​任务的通知值与 ulValue 进行按位或(or) 操作
  • eIncrement​任务的通知值加 1
  • eSetValueWithOverwrite​任务的通知值被无条件设置为 ulValue,即使之前已经有通知
  • eSetValueWithoutOverwrite​如果任务已经有通知待处理,则通知值不会被改变xTaskNotify()​ 将返回 pdFAIL​;如果任务没有待处理的通知,则其通知值会被设置为 ulValue

返回值

在除eSetValueWithoutOverwrite​所有其他情况下,返回 pdPASS

xTaskNotifyWait()

如果接收任务已经被阻塞并等待通知,当一个通知到达时,接收任务将从阻塞状态移除并清除通知

#include "FreeRTOS.h"
#include "task.h"BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait );

参数

ulBitsToClearOnEntry

  • 在调用 xTaskNotifyWait()​ 时,通知值中的某些位会在函数进入时被清除
  • 如果 ulBitsToClearOnEntry​ 设置为 0x01,则任务通知值中的第 0 位会在函数进入时被清除
  • 如果设置为 0xffffffff​(ULONG_MAX​),则通知值的所有位都会被清除,相当于将通知值重置为 0
  • 注意:仅当调用时没有挂起的通知时,清除操作才会执行

ulBitsToClearOnExit

  • 在接收到通知后,在函数退出前通知值中的某些位会被清除
  • 如果设置为 0xffffffff​(ULONG_MAX​),则通知值的所有位都会被清除

pulNotificationValue

  • 用于将任务的通知值传递给调用者
  • 保存的是 在清除ulBitsToClearOnExit的位之前的通知值
  • 如果不需要获取通知值,可以将其设置为 NULL

xTicksToWait​最大等待时间

返回值

  • pdTRUE​接收到了通知,或在调用时通知已挂起
  • pdFALSE​在等待超时时间内没有接收到通知

Example Code:Task Notification with Conditional Actions Based on Values
#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"#include "freeRTOS/event_groups.h"TaskHandle_t task0Handle = NULL;
TaskHandle_t task1Handle = NULL;void Task0(void *pvParam)
{printf("Task0 is running\n");uint32_t notifiedValue = 0;while (true){xTaskNotifyWait(0x00, 0xffffffff, &notifiedValue, portMAX_DELAY);if (notifiedValue == 0x00000001) // 当接收到的通知值为 0x01 时,执行相应操作{printf("Task0 get notification: bit_0\n");}else if (notifiedValue == 0x00000002){printf("Task0 get notification: bit_1\n");}else if (notifiedValue == 0x00000004){printf("Task0 get notification: bit_2\n");}else{printf("Task0 get notification: unknown\n");}vTaskDelay(pdMS_TO_TICKS(3000));}
}void Task1(void *pvParam)
{printf("Task1 is running\n");vTaskDelay(5000 / portTICK_PERIOD_MS);while (true){printf("Task1 is sending notification\n");xTaskNotify(task0Handle, 0x01, eSetValueWithOverwrite); // 发送 bit_0,覆盖之前的值vTaskDelay(5000 / portTICK_PERIOD_MS);xTaskNotify(task0Handle, 0x02, eSetValueWithOverwrite);vTaskDelay(5000 / portTICK_PERIOD_MS);xTaskNotify(task0Handle, 0x03, eSetValueWithOverwrite);vTaskDelay(5000 / portTICK_PERIOD_MS);xTaskNotify(task0Handle, 0x04, eSetValueWithOverwrite);vTaskDelay(5000 / portTICK_PERIOD_MS);}
}void app_main(void)
{vTaskSuspendAll();xTaskCreatePinnedToCore(Task0, "Task0", 2048, NULL, 1, &task0Handle, 0);xTaskCreatePinnedToCore(Task1, "Task1", 2048, NULL, 1, &task1Handle, 0);xTaskResumeAll();
}

相关文章:

ESP32学习笔记_FreeRTOS(6)——Event and Notification

摘要(From AI): 这篇博客详细介绍了 FreeRTOS 中的事件组和任务通知机制&#xff0c;讲解了事件组如何通过位操作实现任务间的同步与通信&#xff0c;以及任务如何通过通知机制进行阻塞解除和数据传递。博客提供了多个代码示例&#xff0c;展示了如何使用事件组和任务通知在多任…...

多监控m3u8视频流,怎么获取每个监控的封面图(纯前端)

文章目录 1.背景2.问题分析3.解决方案3.1解决思路3.2解决过程3.2.1 封装播放组件3.2.2 隐形的视频div3.2.3 截取封面图 3.3 结束 1.背景 有这样一个需求&#xff1a; 给你一个监控列表&#xff0c;每页展示多个监控&#xff08;至少12个&#xff0c;m3u8格式&#xff09;&…...

ExpGCN:深度解析可解释推荐系统中的图卷积网络

一、引言 在当今信息爆炸的时代&#xff0c;推荐系统已成为电子商务和社交网络中不可或缺的工具&#xff0c;旨在为用户筛选出符合其兴趣的信息。传统的协同过滤&#xff08;CF&#xff09;技术通过挖掘用户与项目之间的交互记录来生成推荐&#xff0c;但这种方法简化了模型&a…...

ChatGPT Prompt 编写指南

一、第一原则&#xff1a;明确的意图​ 你需要明确地表达你的意图和要求&#xff0c;尽可能具体、描述性、详细地描述所需的上下文、你期望的结果等。你的要求越明确&#xff0c;越有希望获得你想要的答案。​ 糟糕的案例 ❌​ ​ 写一首关于 OpenAI 的诗。​ ​ 更好的案…...

【脑机接口数据处理】 如何读取Trode 的.rec文件 原始数据?

文章目录 函数简介文件下载函数语法基本用法带时间跳过的用法带选项参数的用法输出结构使用示例 注意事项 MATLAB中读取Trodes文件的实用函数——readTrodesFileContinuous 在处理神经科学实验数据时&#xff0c;经常会遇到Trodes格式的文件。这些文件包含了丰富的神经信号数据…...

反转字符串中的单词 II:Swift 实现与详解

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…...

蓝桥杯训练—矩形面积交

文章目录 一、题目二、示例三、解析四、代码 一、题目 平面上有两个矩形&#xff0c;它们的边平行于直角坐标系的X轴或Y轴&#xff0c;对于每个矩形&#xff0c;我们给出它的一对相对顶点的坐标&#xff0c;请你编程写出两个矩形的交的面积 输入格式&#xff1a; 输入包含两行…...

如何设置HTTPS站点防御?

设置HTTPS站点防御涉及到多个层面的安全措施&#xff0c;包括但不限于配置Web服务器、应用安全头信息、使用内容安全策略&#xff08;CSP&#xff09;、启用HSTS和OCSP Stapling等。下面是一些关键的步骤来增强HTTPS网站的安全性&#xff1a; 1. 使用强加密协议和密钥交换算法…...

光谱相机如何还原色彩

多光谱通道采集 光谱相机设有多个不同波段的光谱通道&#xff0c;可精确记录每个波长的光强信息。如 8 到 16 个甚至更多的光谱通道&#xff0c;每个通道负责特定波长范围的光信息记录。这使得相机能分辨出不同光谱组合产生的相同颜色感知&#xff0c;而传统相机的传感器通常只…...

doris:导入概览

Apache Doris 提供了多种导入和集成数据的方法&#xff0c;您可以使用合适的导入方式从各种源将数据导入到数据库中。Apache Doris 提供的数据导入方式可以分为四类&#xff1a; 实时写入&#xff1a;应用程序通过 HTTP 或者 JDBC 实时写入数据到 Doris 表中&#xff0c;适用于…...

Linux 操作二:文件映射与文件状态

Linux 操作二&#xff1a;文件映射与文件状态查询 文件映射 ​ mmap是一种内存映射文件的方法&#xff0c;即将一个文件或者其它对象映射到进程的地址空间&#xff0c;实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。实现这样的映射关系后&#xff0c;进程…...

ASP .NET Core 学习 (.NET 9)- 创建 API项目,并配置Swagger及API 分组或版本

本系列为个人学习 ASP .NET Core学习全过程记录&#xff0c;基于.NET 9 和 VS2022 &#xff0c;实现前后端分离项目基础框架搭建和部署&#xff0c;以简单、易理解为主&#xff0c;注重页面美观度和后台代码简洁明了&#xff0c;可能不会使用过多的高级语法和扩展&#xff0c;后…...

电脑换固态硬盘

参考&#xff1a; https://baijiahao.baidu.com/s?id1724377623311611247 一、根据尺寸和缺口可以分为以下几种&#xff1a; 1、M.2 NVME协议的固态 大部分笔记本是22x42MM和22x80MM nvme固态。 在京东直接搜&#xff1a; M.2 2242 M.2 2280 2、msata接口固态 3、NGFF M.…...

Android BitmapShader实现狙击瞄具十字交叉线准星,Kotlin

Android BitmapShader实现狙击瞄具十字交叉线准星&#xff0c;Kotlin <?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.…...

MySQL8数据库全攻略:版本特性、下载、安装、卸载与管理工具详解

大家好&#xff0c;我是袁庭新。 MySQL作为企业项目中的主流数据库&#xff0c;其5.x和8.x版本尤为常用。本文将详细介绍MySQL 8.x的特性、下载、安装、服务管理、卸载及管理工具&#xff0c;旨在帮助用户更好地掌握和使用MySQL数据库。 1.MySQL版本及下载 企业项目中使用的…...

机器学习之决策树(DecisionTree)

决策树中选择哪一个特征进行分裂&#xff0c;称之为特征选择。 特征选择是找出某一个特征使得分裂后两边的样本都有最好的“归宿”&#xff0c;即左边分支的样本属于一个类别、右边分支的样本属于另外一个类别&#xff0c;左边和右边分支包含的样本尽可能分属同一类别&#xff…...

Qt Desiogn生成的ui文件转化为h文件

1.找到这个工具 2.查找到ui文件以及要转化为的h文件的路径。 3.在1中的工具输入uic /xx/xxx.ui -o /xx/xxx.h即可得到结果。...

python编程-OpenCV(图像读写-图像处理-图像滤波-角点检测-边缘检测)边缘检测

OpenCV中边缘检测四种常用算子&#xff1a; &#xff08;1&#xff09;Sobel算子 Sobel算子是一种基于梯度的边缘检测算法。它通过对图像进行卷积操作来计算图像的梯度&#xff0c;并将梯度的大小作为边缘的强度。它使用两个3x3的卷积核&#xff0c;分别用于计…...

【论文阅读】VCD-FL: Verifiable, collusion-resistant, and dynamic federated learning

VCD-FL: Verifiable, collusion-resistant, and dynamic federated learning -- VCD-FL:可验证可抵抗共谋攻击的动态联邦学习 来源背景介绍相关工作本文贡献预备知识 系统模型威胁模型具体实现初始化本地训练梯度加密承诺生成插值优化 密文聚合聚合结果验证梯度解密结果验证恶意…...

浙江安吉成新照明电器:Acrel-1000DP 分布式光伏监控系统应用探索

安科瑞吕梦怡 18706162527 摘 要&#xff1a;分布式光伏发电站是指将光伏发电组件安装在用户的建筑物屋顶、空地或其他适合的场地上&#xff0c;利用太阳能进行发电的一种可再生能源利用方式&#xff0c;与传统的大型集中式光伏电站相比&#xff0c;分布式光伏发电具有更灵活…...

记一次数据库连接 bug

整个的报错如下&#xff1a; com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Metho…...

STM32 FreeRTOS 信号量

信号量的简介 reeRTOS中的信号量是一种用于任务间同步和资源管理的机制。信号量可以是二进制的&#xff08;只能取0或1&#xff09;也可以是计数型的&#xff08;可以是任意正整数&#xff09;。信号量的基本操作包括“获取”和“释放”。 比如动车上的卫生间&#xff0c;一个…...

计算机网络 | 什么是公网、私网、NAT?

关注&#xff1a;CodingTechWork 引言 计算机网络是现代信息社会的基石&#xff0c;而网络通信的顺畅性和安全性依赖于有效的IP地址管理和网络转换机制。在网络中&#xff0c;IP地址起到了标识设备和进行数据传输的核心作用。本文将详细讨论公网IP、私网IP以及NAT转换等网络技…...

学技术学英文:通过jmeter命令行工具生成聚合报告文件到csv文件

单词 汉语意思 音标 aggregate 聚合 /ˈɡrɪɡeɪt/ command-line 命令行 /kəˈmnd laɪn/ distribution 分布 /ˌdɪstrɪˈbjuːʃn/ extractor 提取器 /ɪkˈstrktər/ granulation 细分 /ˌɡrnjuˈleɪʃn/ jmeter JMeter&#xff08;软件&#xff0…...

数据库开发支持服务

文章目录 前言适用产品服务范围前提条件责任矩阵交互项目 服务流程交付件项目完成标志 前言 数据库开发支持服务是为了达成客户业务系统开发、测试、上线运行提供的具体技术支撑&#xff0c;内容包括数据库开发指导、性能调优、第三方平台对接支持、应用对接与上线支持等。数据…...

【SQL 中的分组查询与联合查询详解】

文章目录 SQL 中的分组查询与联合查询详解1. GROUP BY分组查询1.1 语句格式1.2 示例说明1.2.1 分别查询哥哥组和弟弟组的英语成绩总和1.2.2 查询哥哥组的所有成绩总和 2. 联合查询2.1 内连接2.1.1 语法格式2.1.2 执行过程 2.2 外连接2.2.1 左外连接2.2.2 右外连接 2.3 自连接2.…...

如何提高自动化测试覆盖率和效率

用ChatGPT做软件测试 在现代软件开发中&#xff0c;自动化测试已经成为保证软件质量的重要手段。然而&#xff0c;在实践中&#xff0c;自动化测试的覆盖率和效率常常受到限制&#xff0c;导致潜在缺陷未能及时发现或测试资源浪费。因此&#xff0c;提升自动化测试的覆盖率和效…...

Vue3 nginx 打包后遇到的问题

前端vite文件配置 export default defineConfig({plugins: [vue(),DefineOptions()],base:./,resolve:{alias:{:/src, //配置指向src目录components:/src/components,views:/src/views}},server:{// host:0.0.0.0,// port:7000,proxy:{/api:{target:xxx, // 目标服务器地址 &am…...

【PCIe 总线及设备入门学习专栏 5.3.2 -- PCIe 枚举与 PCIe PHY firmware 的区别与联系】

文章目录 OverviewPCIe 枚举与PCIe PHY固件的区别与联系1. PCIe 枚举2. PCIe PHY固件3. 区别4. 联系 举例说明实例场景 1&#xff1a;服务器启动 PCIe 网卡的过程实例场景 2&#xff1a;PCIe 热插拔设备的调试 Overview 本文将详细介绍 PCIe 枚举与 PCIe PHY firmware 的区别与…...

电动汽车超级充电设备与车辆之间的通讯协议对27930-2015国标的修改记录

左侧为团体标准 右侧为国标 1.CHM SPN 2600 数据修改为 团标数据&#xff1a; 0x534331 &#xff0c;国标数据&#xff1a;0x000101 2.BRM SPN 2565 数据修改为 团标数据&#xff1a; 0x53…...

案例分析一

张某&#xff08;10多年IT工作经验&#xff09;应聘一家国企单位&#xff0c;面试官&#xff08;技术副主管&#xff09;面试时问了些无关痛痒的问题&#xff0c;谈到薪资时强调我权限范围内的数额就那么多&#xff0c;再多就需要走申请流程进行操作了。 没几天入职后&#xf…...

2.5G PoE交换机 TL-SE2109P 简单开箱评测,8个2.5G电口+1个10G光口(SFP+)

TPLINK&#xff08;普联&#xff09;的万兆上联的2.5G网管交换机TL-SE2109P简单开箱测评。8个PoE 2.5G电口&#xff0c;1个万兆SFP上联口。 2.5G交换机 TL-SE2420 简单开箱评测&#xff0c;16个2.5G电口4个10G光口(SFP)&#xff1a;https://blog.zeruns.com/archives/837.html…...

mysql存电话号码应该用int还是string类型

在MySQL中&#xff0c;存储电话号码一般建议使用**STRING 类型**&#xff08;通常是 VARCHAR&#xff09;&#xff0c;而不是 INT 类型&#xff0c;原因如下&#xff1a; 1. 电话号码不是数字用于计算的值 电话号码本质上是一个标识符&#xff0c;不需要进行数学运算。如果用…...

解决本地运行MR程序访问权限问题

文章目录 1. 提出问题2. 解决问题2.1 临时解决方案2.2 永久解决方案 3. 小结 1. 提出问题 运行DeduplicateIPsDriver类&#xff0c;抛出如下异常&#xff1a; 该错误信息表明在尝试运行 DeduplicateIPsDriver 类时&#xff0c;遇到了 HDFS&#xff08;Hadoop 分布式文件系统&a…...

Codeforces Round 997 (Div. 2) A~C

今天的封面是水母猫猫和佩佩&#xff0c;原图在这里&#xff0c;记得关注画师夏狩大大 至此&#xff0c;天鹅完成了连续四场比赛在四个不同比赛上四次分的壮举&#xff01;&#xff08;ABC388&#xff0c;CodeChef169&#xff0c;牛客月赛109&#xff0c;CF997&#xff09; 这场…...

3. Go函数概念

在 Go 语言中&#xff0c;函数被称为一等公民&#xff08;First-Class Citizens&#xff09;&#xff0c;意味着函数可以像其他数据类型&#xff08;如整数、字符串、结构体等&#xff09;一样作为变量传递、返回、赋值等。这使得 Go 在编程时具备了极大的灵活性。 1、函数概念…...

python-44-嵌入式数据库SQLite和DuckDB

文章目录 1 SQLite1.1 世界上最流行的数据库1.1 SQLite简介1.2 插入语句1.3 查询数据1.4 更新数据1.5 删除数据2 DuckDB2.1 DuckDB简介2.2 DuckDB与Python结合使用2.2.1 创建表2.2.2 分析语句2.2.3 导出为parquet文件2.3 Windows中使用DuckDB3 参考附录1 SQLite Python的一个特…...

使用 Java 和 FreeMarker 实现自动生成供货清单,动态生成 Word 文档,简化文档处理流程。

在上一篇博客中主要是使用SpringBootApache POI实现了BOM物料清单Excel表格导出&#xff0c;详见以下博客&#xff1a; Spring Boot Apache POI 实现 Exc&#xff08;&#xff09;el 导出&#xff1a;BOM物料清单生成器&#xff08;支持中文文件名、样式美化、数据合并&#…...

R语言的并发编程

R语言的并发编程 引言 在现代计算中&#xff0c;如何有效地利用计算资源进行数据处理和分析已成为一个重要的研究方向。尤其在大数据时代&#xff0c;数据量的急剧增加让单线程处理方式显得力不从心。为了解决这一问题&#xff0c;各种编程语言都开展了并发编程的研究和应用。…...

音乐播放器实现:前端HTML,CSS,JavaScript综合大项目

音乐播放器实现:前端HTML&#xff0c;CSS&#xff0c;JavaScript综合大项目 项目概述项目视图效果一、侧边栏相关代码&#xff08;一&#xff09;HTML代码&#xff08;二&#xff09;css代码 二、登录页面&#xff08;一&#xff09;HTML代码&#xff08;二&#xff09;css代码…...

PixArt--alpha笔记

PixArt-α 是华为发布的文生图模型。 训练策略分解&#xff1a;设计三个不同训练步骤&#xff0c;分别优化像素依赖、文本图像对齐和图像审美质量。高效T2I transformer&#xff1a;将 cross-attention融入 Diffusion Transformer (DiT)注入文本条件&#xff0c;简化计算密集的…...

内网渗透测试工具及渗透测试安全审计方法总结

1. 内网安全检查/渗透介绍 1.1 攻击思路 有2种思路&#xff1a; 攻击外网服务器&#xff0c;获取外网服务器的权限&#xff0c;接着利用入侵成功的外网服务器作为跳板&#xff0c;攻击内网其他服务器&#xff0c;最后获得敏感数据&#xff0c;并将数据传递到攻击者&#xff0…...

java工程学习步骤

1、安装idea&#xff0c;安装maven&#xff0c;mysql数据库 2、创建一个多maven的springboot的项目&#xff0c;可以正常启动以及可以访问web页面 3、引入日志使用slflogbck进行日志打印&#xff0c;同时封装统一的日志打印工具&#xff0c;idea安装maven analyzer工具&#…...

使用Flask和Pydantic实现参数验证

使用Flask和Pydantic实现参数验证 1 简介 Pydantic是一个用于数据验证和解析的 Python 库&#xff0c;版本2的性能有较大提升&#xff0c;很多框架使用Pydantic做数据校验。 # 官方参考文档 https://docs.pydantic.dev/latest/# Github地址 https://github.com/pydantic/pyd…...

LabVIEW 蔬菜精密播种监测系统

在当前蔬菜播种工作中&#xff0c;存在着诸多问题。一方面&#xff0c;播种精度难以达到现代农业的高标准要求&#xff0c;导致种子分布不均&#xff0c;影响作物的生长发育和最终产量&#xff1b;另一方面&#xff0c;对于小粒径种子&#xff0c;传统的监测手段难以实现有效监…...

统信UOS系统安装redis

1、yum引入redis yum install redis2、创建日志文件夹 mkdir -p /var/log/redis mkdir -p /var/lib/redis3、添加用户 useradd redis -s /usr/sbin/nologin4、文件夹赋权限 chown -R redis:root /var/log/redis chown redis:root /etc/redis.conf chown -R redis:root /var…...

课程如何抵御脑腐的冲击

课程需要引导学生逐步形成深度思考的能力&#xff0c;才有可能抵御‘Brain Rot’&#xff0c;否则都不会取得任何改善。 一步步失去的思维力&#xff0c;需要一步步引导恢复&#xff0c;类似康复训练。这是一个非常长期而艰辛但又十分有意义和有价值的工作。 这是一篇类似工作转…...

2.4 如何学习表示学习(Representation Learning)

如何学习表示学习(Representation Learning) 学习表示学习(Representation Learning)是理解和掌握机器学习、深度学习以及人工智能的关键一步。表示学习主要关注从原始数据中提取有效的特征或表示,使得模型能够高效处理和理解复杂的数据。以下是一些系统的方法,帮助你一…...

介绍下常用的前端框架及时优缺点

以下是一些常用的前端框架及其优缺点介绍&#xff1a; React • 优点 • 组件化架构&#xff1a;可构建可复用的UI组件&#xff0c;提高开发效率和组件可维护性。 • 虚拟DOM&#xff1a;高效更新页面&#xff0c;减少直接操作DOM的性能开销。 • 灵活性和可扩展性&#xf…...

Rust 猜数字游戏:从 0 到 1 的完整实现与深入解析

一、项目概述 1.1 为什么选择“猜数字”&#xff1f; “猜数字”是编程入门中非常经典的一个项目。它看似简单&#xff0c;却能很好地展示&#xff1a; 输入输出 (I/O)&#xff1a;提示用户输入并读取内容。随机数&#xff1a;每次运行生成一个随机值&#xff0c;保证游戏的…...