FreeRTOS学习——链表list

FreeRTOS学习——链表(列表)list,仅用于记录自己阅读与学习源码

FreeRTOS Kernel V10.5.1

参考大佬的好文章:
freertos内核原理 Day1(链表)
FreeRTOS-链表的源码解析

*list_t只能存储指向list_item_t的指针。每个list_item_t都包含一个数值(xItemValue)。大多数时候,列表是按项目值升序排列的。

*创建的列表已包含一个列表项。此项的值是可以存储的最大值,因此它始终位于列表的末尾,并充当标记。列表成员pxHead始终指向此标记,即使它位于列表的末尾。这是因为尾部包含一个返回指针,指向列表的真正头部。

*除了它的值外,每个列表项还包含一个指向列表中下一个项的指针(pxNext)、一个指向它所在列表的指针(pxContainer)和一个指向包含它的对象的指针。为了提高列表操作的效率,包含了后两个指针。包含列表项的对象和列表项本身之间实际上存在双向链接。

链表结构体

关于链表的结构体,有三个,分别是

1. 节点结构体
2. 尾节点结构体(mini节点)
3. 链表结构体

可以看大佬的博客freertos内核原理 Day1(链表),非常清晰

节点结构体 ListItem_t

/** 列表可以包含的唯一对象类型的定义*/
struct xLIST_ITEM
{listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE           /*< 链表节点完整性检查值1 */configLIST_VOLATILE TickType_t xItemValue;          /*< 链表节点值,用于阻塞升序排序 */struct xLIST_ITEM * configLIST_VOLATILE pxNext;     /*< 指向链表中的下一个节点 */struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< 指向链表中的上一个节点 */void * pvOwner;                                     /*< 指向拥有该链表节点的对象 (一般是TCB) . */struct xLIST * configLIST_VOLATILE pxContainer;     /*< 指向节点所在的链表. */listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE          /*< 链表节点完整性检查值2. */
};
typedef struct xLIST_ITEM ListItem_t;

若宏configLIST_VOLATILE定义为空,且若完整性检查宏configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES也为0的话(见下面关于链表宏部分),那么这个链表节点结构体其实就长这个样子,一下子干净多了。

struct xLIST_ITEM
{TickType_t xItemValue;          /*< 链表节点值,用于阻塞升序排序 */struct xLIST_ITEM * pxNext;     /*< 指向链表中的下一个节点 */struct xLIST_ITEM * pxPrevious; /*< 指向链表中的上一个节点 */void * pvOwner;                 /*< 指向拥有该链表节点的对象 (一般是TCB) . */struct xLIST * pxContainer;     /*< 指向节点所在的链表. */
};
typedef struct xLIST_ITEM ListItem_t;

链表节点值TickType_t xItemValue;为什么是TickType_t 类型呢,阻塞时间就是多少个TickType_t ,这个值用于插入延迟列表时,将节点从低到高的排列,阻塞时间段的在最前面,只要前面的没有唤醒,那么后面的也一定在阻塞,因为是升序排列的。

尾节点结构体(mini节点) MiniListItem_t

#if ( configUSE_MINI_LIST_ITEM == 1 )struct xMINI_LIST_ITEM{listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< 链表节点完整性检查值1 */configLIST_VOLATILE TickType_t xItemValue;struct xLIST_ITEM * configLIST_VOLATILE pxNext;struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;};typedef struct xMINI_LIST_ITEM MiniListItem_t;
#elsetypedef struct xLIST_ITEM      MiniListItem_t;
#endif

如果宏configUSE_MINI_LIST_ITEM 为1 ,则定义xMINI_LIST_ITEM 为MiniListItem_t,否则就把普通节点xLIST_ITEM定义为尾节点。

与普通节点相比,尾节点结构体少了pvOwner和pxContainer

链表结构体(根节点) List_t

/** 调度器使用的队列类型的定义*/
typedef struct xLIST
{listFIRST_LIST_INTEGRITY_CHECK_VALUE      /*< 链表完整性检查值1 */volatile UBaseType_t uxNumberOfItems;ListItem_t * configLIST_VOLATILE pxIndex; /*< 索引指针,通过调用listGET_OWNER_OF_NEXT_ENTRY ()来遍历链表的指针 */MiniListItem_t xListEnd;                  /*< 尾节点拥有最大的xItemValue值. */listSECOND_LIST_INTEGRITY_CHECK_VALUE     /*< 链表完整性检查值2 */
} List_t;

注意,尾节点结构体MiniListItem_t 和链表结构体List_t并不是链表连接起来的,而是MiniListItem_t 是List_t的一部分,可以把List_t想象成一个大东西,而这个大东西 在链表的尾部,也可以说在头尾,因为是双向链表。List_t通过MiniListItem_t 链接起整个链表,只要获取了List_t,就能一节一节的获取整个链表,List_t也可以叫做根节点。

链表操作

初始化链表 vListInitialise

void vListInitialise( List_t * const pxList )
{/* 将索引指针指向尾节点 */pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*尾节点xListEnd使用mini节点结构体,节省RAM *//*给尾节点完整性检查值 赋值,尾节点只有一个完整性检查值 */listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );/* 尾节点值为最大值0xffffffffUL,确保其为最后一个节点*/pxList->xListEnd.xItemValue = portMAX_DELAY;/* 当链表为空时,尾节点的前后指针指向尾节点自己 */pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );     pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd ); /* 如果尾节点没有使用mini节点结构体,则初始化其pvOwner和pxContainer指针 */#if ( configUSE_MINI_LIST_ITEM == 0 ){pxList->xListEnd.pvOwner = NULL;pxList->xListEnd.pxContainer = NULL;listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );}#endif/*节点数量为0*/pxList->uxNumberOfItems = ( UBaseType_t ) 0U;/* 给链表完整性检查值 赋值 */listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
}
  1. 链表索引指针指向尾节点
  2. 尾节点值设为最大值,且前后指针都指向自己
  3. 节点数量为0

初始化链表节点 vListInitialiseItem

void vListInitialiseItem( ListItem_t * const pxItem )
{/* pxContainer指该节点属于哪个链表,初始值为NULL,确保该节点没有在任何链表中. */pxItem->pxContainer = NULL;/* 给节点完整性检查值 赋值. */listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
}

链表尾部插入节点 vListInsertEnd

void vListInsertEnd( List_t * const pxList,ListItem_t * const pxNewListItem )
{ListItem_t * const pxIndex = pxList->pxIndex;/* 完整性检查,可以检查链表结构体在内存中是否被重写 */listTEST_LIST_INTEGRITY( pxList );listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );/* 将新节点 pxNewListItem 插入到 pxIndex 之前  */pxNewListItem->pxNext = pxIndex;pxNewListItem->pxPrevious = pxIndex->pxPrevious;/* 覆盖率测试,不影响功能,仅用于覆盖率测试 */mtCOVERAGE_TEST_DELAY();pxIndex->pxPrevious->pxNext = pxNewListItem;pxIndex->pxPrevious = pxNewListItem;/* 将节点的pxContainer指针指向链表 */pxNewListItem->pxContainer = pxList;/*链表节点数量加1*/( pxList->uxNumberOfItems )++;
}
  1. 将新节点 pxNewListItem 插入到 pxIndex 之前
  2. 将节点的pxContainer指针指向链表
  3. 链表节点数量加1

链表插入节点 vListInsert

void vListInsert( List_t * const pxList,ListItem_t * const pxNewListItem )
{ListItem_t * pxIterator;const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;/* 完整性检查,可以检查链表结构体在内存中是否被重写 */listTEST_LIST_INTEGRITY( pxList );listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );/* 将新的列表项插入列表,按xItemValue顺序排序* 如果节点值是最大值,则插入到尾节点之前*/if( xValueOfInsertion == portMAX_DELAY ){pxIterator = pxList->xListEnd.pxPrevious;}else{/* *** NOTE ************************************************************  如果程序崩溃,可能原因如下:**   1) 栈溢出*   2) 优先级分配错误*   3) 从关键部分或当调度程序暂停时调用API函数,或从中断调用不以“FromISR”结尾的API函数*   4) 在队列或信号量初始化之前 或 调度程序启动之前使用它(中断是在vTaskStartScheduler()被调用之前触发的吗?)*   5) 果FreeRTOS端口支持中断嵌套,则确保滴答中断的优先级等于或低于configMAX_SYSCALLINTERRUPT_priority**********************************************************************/for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) {/* 这里什么都不做,只是遍历链表到要插入的位置* 如果节点值相同,则插入到相同值的节点之后*/}}/* 插入新节点 */pxNewListItem->pxNext = pxIterator->pxNext;pxNewListItem->pxNext->pxPrevious = pxNewListItem;pxNewListItem->pxPrevious = pxIterator;pxIterator->pxNext = pxNewListItem;/* 将新节点的pxContainer指针指向链表 */pxNewListItem->pxContainer = pxList;/*链表节点数量加1*/( pxList->uxNumberOfItems )++;
}
  1. 确认要插入的位置,如果节点值是最大值,则插入到尾节点之前,否则遍历链表
  2. 插入新节点
  3. 将新节点的pxContainer指针指向链表
  4. 链表节点数量加1

从链表移除节点 uxListRemove

UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
{/* 获取节点所在的链表 */List_t * const pxList = pxItemToRemove->pxContainer;/*将节点从链表中移除*/pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;/* 覆盖率测试,不影响功能,仅用于覆盖率测试 */mtCOVERAGE_TEST_DELAY();/* 确保索引指针指向有效的节点 */if( pxList->pxIndex == pxItemToRemove ){pxList->pxIndex = pxItemToRemove->pxPrevious;}else{/*覆盖率测试,不影响功能,仅用于覆盖率测试*/mtCOVERAGE_TEST_MARKER();}/* 将节点的pxContainer指针指向NULL */pxItemToRemove->pxContainer = NULL;/*链表节点数量减 1*/( pxList->uxNumberOfItems )--;/*返回链表中剩余节点数量*/return pxList->uxNumberOfItems;
}
  1. 将节点从链表中移除
  2. 将节点的pxContainer指针指向NULL
  3. 链表节点数量减 1并返回链表中剩余节点数量

链表宏

configLIST_VOLATILE

*列表结构成员是在中断内修改的,因此应该声明为volatile。然而,它们只能以功能原子的方式进行修改(在调度器挂起的关键部分内),并且要么通过引用传递到函数中,要么通过volatile变量进行索引。因此,在迄今为止测试的所有用例中,可以省略volatile限定符,以便在不影响功能行为的情况下提供适度的性能改进。IAR、ARM和GCC编译器在为最大优化设置相应编译器选项时生成的汇编指令已经过检查,并被认为符合预期。也就是说,随着编译器技术的进步,特别是如果使用了激进的跨模块优化(一个没有得到很大程度应用的用例),那么正确的优化就可能需要volatile限定符。预计编译器会删除基本代码,因为如果列表结构成员上没有volatile限定符,并且进行了积极的跨模块优化,编译器认为代码是不必要的,这将导致调度器完全和明显的失败。如果遇到这种情况,那么只需在FreeRTOSConfig.h中将configLIST_volatile定义为volatile,就可以将volatile限定符插入列表结构中的相关位置(如本注释块底部的示例所示)。如果未定义configLIST_VOLATILE,则下面的预处理器指令将完全#define configLIST_VOLATILE。

*要使用volatile列表结构成员,请在FreeRTOSConfig.h中添加以下行(不带引号):“#define configLIST_volatile volatile”

#ifndef configLIST_VOLATILE#define configLIST_VOLATILE
#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */

简单点说就是在迄今为止测试的所有用例中,可以省略volatile。但是如果使用了激进的跨模块优化,就可能需要volatile限定符,那么就在FreeRTOSConfig.h中添加:“#define configLIST_volatile volatile”。

现在configLIST_VOLATILE是定义为空的,因为volatile可以省略。

configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES

可用于在列表结构中放置已知值的宏,然后检查已知值在应用程序执行过程中是否损坏。这些可能会捕获内存中被覆盖的列表数据结构。它们不会捕获因FreeRTOS配置或使用不正确而导致的数据错误
在这里插入图片描述
在FreeRTOS中,这段宏定义与列表数据完整性检查相关。具体来说,它们的作用是根据configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES宏的值决定是否启用数据完整性检查功能。
(默认为0,即不开启)

当configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES被设置为0时,这段代码通过定义一系列宏为空操作(即不执行任何操作),来关闭列表数据的完整性检查功能。这意味着在使用列表数据结构时,系统不会进行额外的完整性校验,这样可以降低运行时的开销,适用于对性能要求较高的场景。

这些宏的具体定义如下:

*listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE :列表节点完整检查值1
*listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE:列表节点完整检查值2。
这两个用于表示列表节点完整性检查的值,若不启用则为空。若启用了会在列表节点结构体中添加
TickType_t xListItemIntegrityValue1;
和TickType_t xListItemIntegrityValue2;

*listFIRST_LIST_INTEGRITY_CHECK_VALUE :列表完整检查值1
*listSECOND_LIST_INTEGRITY_CHECK_VALUE:列表完整检查值2
同上面两个值类似,用于表示整个列表的完整性检查值,同样不启用时为空。

*listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE(pxItem):赋值列表节点完整性检查值1
*listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE(pxItem):
它会赋值列表节点中的xListItemIntegrityValue为定义的值#define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL

*listSET_LIST_INTEGRITY_CHECK_1_VALUE(pxList) :赋值列表完整性检查值1
*listSET_LIST_INTEGRITY_CHECK_2_VALUE(pxList):
同上面两个值类似

*listTEST_LIST_ITEM_INTEGRITY(pxItem):用于测试列表节点的完整性
*listTEST_LIST_INTEGRITY(pxList):用于测试整个列表的完整性
上面的宏不是已经幅过值了吗,那么这两个宏就是检查上面的值有没有发生变化

总之,这些宏确保在不需要数据完整性检查时,代码的执行不会受影响,从而提高系统的性能。同时,若需要进行完整性检查(即configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES设置为非零值),这些宏可以被重新定义,以执行必要的检查逻辑。这样的设计使得FreeRTOS能够灵活地在不同的应用场景中进行配置。

listGET_OWNER_OF_NEXT_ENTRY

/** 链表成员pxIndex用于遍历列表* 调用listGET_OWNER_OF_NEXT_ENTRY会将pxIndex递增到列表中的下一个节点,并返回该节点的拥有者pxOwner(一般是TCB)。* 因此,通过多次调用此函数,可以遍历列表中包含的每个项目。* 列表项的pxOwner参数是指向拥有该列表项的对象的指针。在调度器中,这通常是一个任务控制块。*/
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )                                           \{                                                                                          \List_t * const pxConstList = ( pxList );                                               \/* 链表索引pxIndex指向下一个节点*/               \/* 确保不返回尾节点  */                         \( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;                           \if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \{                                                                                      \( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;                       \}                                                                                      \( pxTCB ) = ( pxConstList )->pxIndex->pvOwner;                                         \}

listREMOVE_ITEM

/** 删除节点* 不返回值的uxListRemove()的版本。通过内联对xTaskIncrementTick()进行了轻微优化*/
#define listREMOVE_ITEM( pxItemToRemove ) \{                                     \/* 获取节点所在的链表 */                                                              \List_t * const pxList = ( pxItemToRemove )->pxContainer;                 \\( pxItemToRemove )->pxNext->pxPrevious = ( pxItemToRemove )->pxPrevious; \( pxItemToRemove )->pxPrevious->pxNext = ( pxItemToRemove )->pxNext;     \/* 确保索引指针指向正确的节点 */              \if( pxList->pxIndex == ( pxItemToRemove ) )                              \{                                                                        \pxList->pxIndex = ( pxItemToRemove )->pxPrevious;                    \}                                                                        \\( pxItemToRemove )->pxContainer = NULL;                                  \( pxList->uxNumberOfItems )--;                                           \}

listINSERT_END

/** 内联版本vListInsertEnd()对xTaskIncrementTick()进行了轻微优化.** 通过多次调用listGET_OWNER_OF_NEXT_ENTRY.确保插入的节点位于最后一个节点** 列表成员pxIndex用于遍历列表,调用listGET_OWNER_OF_NEXT_ENTRY会将pxIndex递增到列表中的下一个节点。* 使用vListInsertEnd将节点有效地放置在pxIndex指向的列表位置。* 这意味着在pxIndex参数再次指向要插入的项之前,列表中的所有其他项都将由listGET_OWNER_OF_NEXT_ENTRY返回。*/
#define listINSERT_END( pxList, pxNewListItem )           \{                                                     \ListItem_t * const pxIndex = ( pxList )->pxIndex; \\/* 链表完整性检查 */                                 \listTEST_LIST_INTEGRITY( ( pxList ) );                                  \listTEST_LIST_ITEM_INTEGRITY( ( pxNewListItem ) );                      \\/* 通过调用listGET_OWNER_OF_NEXT_ENTRY(). 确保插入的节点位于最后一个节点*/     \( pxNewListItem )->pxNext = pxIndex;                 \( pxNewListItem )->pxPrevious = pxIndex->pxPrevious; \\pxIndex->pxPrevious->pxNext = ( pxNewListItem );     \pxIndex->pxPrevious = ( pxNewListItem );             \\/* 将节点的pxContainer指针指向链表 */                    \( pxNewListItem )->pxContainer = ( pxList );         \\( ( pxList )->uxNumberOfItems )++;                   \}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Taro】初识 Taro

笔记来源&#xff1a;编程导航。 概述 Taro 官方文档&#xff1a;https://taro-docs.jd.com/docs/ &#xff08;跨端开发框架&#xff09; Taro 官方框架兼容的组件库&#xff1a; taro-ui&#xff1a;https://taro-ui.jd.com/#/ &#xff08;最推荐&#xff0c;兼容性最好&…

【渗透测试】-vulnhub源码框架漏洞-Os-hackNos-1

vulnhub源码框架漏洞中的CVE-2018-7600-Drupal 7.57 文章目录  前言 1.靶场搭建&#xff1a; 2.信息搜集&#xff1a; 主机探测&#xff1a; 端口扫描&#xff1a; 目录扫描&#xff1a; 3.分析&#xff1a; 4.步骤&#xff1a; 1.下载CVE-2018-7600的exp 2.执行exp: 3.写入木…

电玩店ps5倒计时软件试用版下载 佳易王电玩计时计费管理系统操作教程

一、前言 电玩店ps5倒计时软件试用版下载 佳易王电玩计时计费管理系统操作教程 佳易王电玩店计时计费软件&#xff0c;有两款&#xff0c;其中一款可显示倒计时剩余分钟数&#xff0c;另外一款是显示用了多长时间&#xff0c;都可以设置定时语音提醒。 二、显示倒计时软件图文…

【超详细】基于YOLOv8训练无人机视角Visdrone2019数据集

主要内容如下&#xff1a; 1、Visdrone2019数据集介绍 2、下载、制作YOLO格式训练集 3、模型训练及预测 4、Onnxruntime推理 运行环境&#xff1a;Python3.8&#xff08;要求>3.8&#xff09;&#xff0c;torch1.12.0cu113&#xff08;要求>1.8&#xff09;&#xff0c…

策略模式与工厂模式的区别

《策略模式与工厂模式的区别》 策略模式&#xff08;Strategy Pattern&#xff09; 和 工厂模式&#xff08;Factory Pattern&#xff09; 都是常见的设计模式&#xff0c;虽然它们在设计目标上有一些相似之处&#xff0c;如解耦代码、增强扩展性&#xff0c;但它们的应用场景和…

基于单片机的智能小车的开发与设计

摘要&#xff1a;本文论述了基于 STC89C52 单片机的智能小车的开发与设计过程。该设计采用单片机、电机驱动及光电循迹等技术&#xff0c;保证小车在无人管理状态下&#xff0c;能按照预先设定的线路实现自动循迹功能。在电路结构设计中力求方便&#xff0c;可操作&#xff0c;…

文件操作

文件的由来&#xff1a;在程序中&#xff0c;之前每一个程序都是需要运行然后输入数据&#xff0c;当程序结束时输入的数据也随之消散&#xff0c;为了下一次运行时不再输入数据就有文件的由来&#xff0c;使用文件我们可以将数据直接存放在电脑的硬盘上&#xff0c;做到了数据…

软件著作权登记所需要的材料

软件著作权登记所需材料全面解析 在当今数字化时代&#xff0c;软件著作权作为保护软件开发者智力劳动成果的重要法律手段&#xff0c;其登记过程显得尤为重要。 一、软件著作权登记申请表 首先&#xff0c;软件著作权登记需要提交的最基本材料是《软件著作权登记申请表》。这份…

照片写真记录摄影作品记录网站源码

完美适应iPad&#xff0c;平板&#xff0c;手机竖屏不支持lazy&#xff0c;横屏可以&#xff0c;但建议使用平板查看效果&#xff0c; 有服务器直接上传解压使用&#xff0c;环境nginxphp&#xff0c; 没有服务器也没关系&#xff0c;可以直接使用html

前端项目代码开发规范及工具配置

在项目开发中&#xff0c;良好的代码编写规范是项目组成的重要元素。本文将详细介绍在项目开发中如何集成相应的代码规范插件及使用方法。 项目规范及工具 集成 EditorConfig集成 Prettier1. 安装 Prettier2. 创建 Prettier 配置文件3. 配置 .prettierrc4. 使用 Prettier 集成 …

计算机毕业设计 基于Python的食品销售数据分析系统 SpringBoot+Vue 前后端分离 附源码 讲解 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

LeetCode Hot100 C++ 哈希 1.两数之和

LeetCode Hot100 C 1.两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案&#xff0c;并且你不能使用两次相同的元素。 你可以按…

基于STM32的智能花盆控制系统设计-设计说明书设计

设计摘要&#xff1a; 随着人们对室内绿植的热爱与需求日益增长&#xff0c;智能花盆控制系统作为一种新兴的智能化管理方式&#xff0c;受到了广泛关注。本文旨在设计一种基于STM32的智能花盆控制系统&#xff0c;以实现对花盆的自动浇水、温湿度监测和光照控制等功能。 在硬…

Android轻量级RTSP服务使用场景分析和设计探讨

技术背景 好多开发者&#xff0c;对我们Android平台轻量级RTSP服务模块有些陌生&#xff0c;不知道这个模块具体适用于怎样的场景&#xff0c;有什么优缺点&#xff0c;实际上&#xff0c;我们的Android平台轻量级RTSP服务模块更适用于内网环境下、对并发要求不高的场景&#…

基于对数变换的图像美白增强,Matlab实现

博主简介&#xff1a;matlab图像处理&#xff08;QQ:3249726188&#xff09; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本次案例是基于对数变换的图像美白增强&#xff0c;用matlab实现。 一、案例背景和算法介绍 这次案例是美白算法&…

大数据可视化-三元图

三元图是一种用于表示三种变量之间关系的可视化工具&#xff0c;常用于化学、材料科学和地质学等领域。它的特点是将三个变量的比例关系在一个等边三角形中展示&#xff0c;使得每个点的位置代表三个变量的相对比例。 1. 结构 三个角分别表示三个变量的最大值&#xff08;通常…

爬虫 ----hook

目录 定义&#xff1a; 了解什么是hook? 举例 hook XHR请求 XMLHttpRequest 案例地址&#xff1a; Interceptors-拦截器 HOOK cookie操作 cookie 示范 常见的hook代码总结 1.Hook Cookie 2.Hook Header 3.Hook URL 4.Hook JSON.stringify 5.Hook JSON.parse 6.Ho…

蓝桥杯嵌入式的学习总结

一. 前言 嵌入式竞赛实训平台(CT117E-M4) 是北京国信长天科技有限公司设计&#xff0c;生产的一款 “ 蓝桥杯全国软件与信息技术专业人才大赛-嵌入式设计与开发科目 “ 专用竞赛平台&#xff0c;平台以STM32G431RBT6为主控芯片&#xff0c;预留扩展板接口&#xff0c;可为用户提…

conda环境下module ‘numba.types‘ has no attribute ‘Macro‘问题解决

1 问题描述 conda环境下运行数据处理&#xff0c;报出如下错误&#xff1a; Traceback (most recent call last):File "train_preprocess.py", line 13, in <module>import audioFile "/opt/service/lipsync/audio.py", line 1, in <module>…

橙子质量检测系统源码分享

橙子质量检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…