《FreeRTOS任务删除篇》
任务删除函数
- 源码
- 1. 进入临界区
- 1.1 第一步
- 1.2 第二步
- 1.3 第三步
- 1.4 第四步
- 2. 获取待删除任务的任务控制块TCB
- 3. 从就绪/延迟列表中删除任务
- 4. 从事件列表中删除任务
- 5. 如果待删除任务是当前运行的任务
- 6. 如果待删除任务是其它任务
- 7. 退出临界区
- 7.1 第一步
- 7.2 第二步
- 7.3 第三步
- 7.4 第四步
- 8. 如果待删除的任务不是当前运行的任务
- 9. 如果待删除的任务不是当前运行的任务
- 介绍FreeRTOS任务删除函数的执行过程,逐行分析源代码。
- 要使用任务删除函数vTaskDelete,需要配置宏INCLUDE_vTaskDelete为1。
- 删除任务函数vTaskDelete的参数为待删除任务的任务句柄(即任务控制块)。
- 当函数参数为NULL时,代表删除的是调用函数的任务本身(即正在运行的任务)。
源码
/* 示例,在正在运行的任务中调用任务删除函数。*/
vTaskDelete(NULL);
/* 任务删除 */
#if ( INCLUDE_vTaskDelete == 1 ) /* 需要INCLUDE_vTaskDelete宏配置为1 */void vTaskDelete( TaskHandle_t xTaskToDelete ) /* 函数参数为待删除任务的任务句柄,可以用NULL代替当前任务句柄。 */{TCB_t * pxTCB;taskENTER_CRITICAL(); /* 进入临界区,本质是关闭全局中断。 */{/* If null is passed in here then it is the calling task that is* being deleted.* 如果在此处传递NULL,则删除的是调用函数的任务本身。*/pxTCB = prvGetTCBFromHandle( xTaskToDelete );/* Remove task from the ready/delayed list.* 从就绪/延迟列表中删除任务* 如果删除后列表中没有列表项,则uxListRemove返回0*//* 将任务控制块的成员状态列表项xStateListItem从列表中移除 */if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ){taskRESET_READY_PRIORITY( pxTCB->uxPriority );}else{mtCOVERAGE_TEST_MARKER();}/* Is the task waiting on an event also?* 任务是否也在等待事件?* 任务控制块的成员xEventListItem是否挂载在其他列表中*/if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ){/* 将事件列表项从等待事件列表中移出 */( void ) uxListRemove( &( pxTCB->xEventListItem ) );}else{mtCOVERAGE_TEST_MARKER();}/* Increment the uxTaskNumber also so kernel aware debuggers can* detect that the task lists need re-generating. This is done before* portPRE_TASK_DELETE_HOOK() as in the Windows port that macro will* not return.* 同时自增uxTaskNumber,以便内核感知调试器可以检测到任务列表需要重新生成。* 这是在portPRE_TASK_DELETE_HOOK之前完成的,因为在Windows端口中,宏不会返回*/uxTaskNumber++; /* 任务列表需要重新生成 *//* 删除的是调用任务本身时 */if( pxTCB == pxCurrentTCB ){/* A task is deleting itself. This cannot complete within the* task itself, as a context switch to another task is required.* Place the task in the termination list. The idle task will* check the termination list and free up any memory allocated by* the scheduler for the TCB and stack of the deleted task.* 一个任务正在删除自己。* 这无法在任务本身内完成,因为需要切换到另一个任务的上下文。* 将任务放入等待结束列表中。* 空闲任务将检查等待结束列表,并释放调度器为准备删除任务分配的TCB和堆栈内存。*/vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xStateListItem ) );/* Increment the ucTasksDeleted variable so the idle task knows* there is a task that has been deleted and that it should therefore* check the xTasksWaitingTermination list.* 递增ucTasksDeleted变量,以便空闲任务知道有一个任务已被删除,* 因此它应该检查xTasksWaitingTermination列表。*/++uxDeletedTasksWaitingCleanUp;/* Call the delete hook before portPRE_TASK_DELETE_HOOK() as* portPRE_TASK_DELETE_HOOK() does not return in the Win32 port.* 在调用portPRE_TASK_delete_hook之前调用delete钩子,* 因为portPRE_TAS K_delete_ hook在Win32端口中不返回。*/traceTASK_DELETE( pxTCB );/* The pre-delete hook is primarily for the Windows simulator,* in which Windows specific clean up operations are performed,* after which it is not possible to yield away from this task -* hence xYieldPending is used to latch that a context switch is* required.* 预删除挂钩主要用于Windows模拟器,* 在该模拟器中执行特定于Windows的清理操作,之后不可能放弃此任务,* 因此xYieldPending用于锁定需要进行上下文切换。*/portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending );}else{--uxCurrentNumberOfTasks; /* 当前任务个数自减一 */traceTASK_DELETE( pxTCB );/* Reset the next expected unblock time in case it referred to* the task that has just been deleted.* 重置下一个预期的解锁时间,以防它引用了刚刚被删除的任务*/prvResetNextTaskUnblockTime();}}taskEXIT_CRITICAL(); /* 退出临界区,本质是开启全局中断 *//* If the task is not deleting itself, call prvDeleteTCB from outside of* critical section. If a task deletes itself, prvDeleteTCB is called* from prvCheckTasksWaitingTermination which is called from Idle task.* 如果任务不是删除自己,请从临界区外部调用prvDeleteTCB。* 如果任务删除自己,则从空闲任务调用的prvCheckTasksWaitingTermination中调用prvDeleteTCB删除任务*/if( pxTCB != pxCurrentTCB ){prvDeleteTCB( pxTCB );}/* Force a reschedule if it is the currently running task that has just* been deleted.* 如果删除的是当前正在运行的任务,则强制重新开启一次任务调度*/if( xSchedulerRunning != pdFALSE ) /* 任务调度器正在运行中 */{if( pxTCB == pxCurrentTCB ) /* 删除的是当前正在运行的任务 */{configASSERT( uxSchedulerSuspended == 0 );portYIELD_WITHIN_API();}else{mtCOVERAGE_TEST_MARKER();}}}#endif /* INCLUDE_vTaskDelete */
1. 进入临界区
taskENTER_CRITICAL(); /* 进入临界区,本质是关闭全局中断。 */
1.1 第一步
#define taskENTER_CRITICAL() portENTER_CRITICAL() /* 从任务中进入临界区 */
1.2 第二步
#define portENTER_CRITICAL() vPortEnterCritical()
1.3 第三步
void vPortEnterCritical( void )
{portDISABLE_INTERRUPTS();ulCriticalNesting++;
}
1.4 第四步
#define portDISABLE_INTERRUPTS() __asm(" setc INTM") /* 关闭全局中断 */
2. 获取待删除任务的任务控制块TCB
portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL; /* 指向当前运行的任务控制块。 */
/** Several functions take a TaskHandle_t parameter that can optionally be NULL,* where NULL is used to indicate that the handle of the currently executing* task should be used in place of the parameter. This macro simply checks to* see if the parameter is NULL and returns a pointer to the appropriate TCB.* 有几个函数接受一个TaskHandle_t参数,该参数可以选择设置为NULL,* 其中NULL用于表示使用当前正在执行的任务的句柄来代替该参数。* 此宏只是检查参数是否为NULL,并返回指向相应TCB的指针。*/
#define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? pxCurrentTCB : ( pxHandle ) )
3. 从就绪/延迟列表中删除任务
/* Remove task from the ready/delayed list.* 从就绪/延迟列表中删除任务* 如果删除后列表中没有列表项,则返回0*/
if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 )
{taskRESET_READY_PRIORITY( pxTCB->uxPriority );
}
else
{mtCOVERAGE_TEST_MARKER();
}
/* 从列表中移除待移除的列表项 */
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
{/* The list item knows which list it is in. Obtain the list from the list* item.* 从列表项的成员pxContainer可以知道它在哪个列表中。从列表项中获取列表。* */List_t * const pxList = pxItemToRemove->pxContainer;/* 将列表项从列表中移除 */pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;/* Only used during decision coverage testing.* 仅在决策覆盖率测试期间使用。*/mtCOVERAGE_TEST_DELAY();/* Make sure the index is left pointing to a valid item.* 确保索引指向有效项*/if( pxList->pxIndex == pxItemToRemove ) /* 如果列表的列表索引号指向待移除的列表项 */{pxList->pxIndex = pxItemToRemove->pxPrevious; /* 将索引号指向待移除列表项的前一个列表项 */}else{mtCOVERAGE_TEST_MARKER();}pxItemToRemove->pxContainer = NULL; /* 将待删除列表项的成员pxContainer设置为NULL,表示其不属于任何列表 */( pxList->uxNumberOfItems )--; /* 列表的列表项个数减一 */return pxList->uxNumberOfItems; /* 返回列表中剩余的列表项个数 */
}
4. 从事件列表中删除任务
/* Is the task waiting on an event also?* 任务是否也在等待事件?* 任务控制块的成员xEventListItem是否挂载在其他列表中*/
if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
{/* 将事件列表项从等待事件列表中移出 */( void ) uxListRemove( &( pxTCB->xEventListItem ) );
}
else
{mtCOVERAGE_TEST_MARKER();
}
/** Return the list a list item is contained within (referenced from).* 返回列表项所挂载的列表** @param pxListItem The list item being queried. pxListItem表示正在查询的列表项。* @return A pointer to the List_t object that references the pxListItem. 指向挂载pxListItem的List_t对象的指针*/
#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer )
5. 如果待删除任务是当前运行的任务
- 将列表项xStateListItem按尾部插入法挂载到xTasksWaitingTermination列表中
- 变量uxDeletedTasksWaitingCleanUp自增一,以供空闲任务使用。
/* 删除的是调用任务本身时 */
if( pxTCB == pxCurrentTCB )
{/* A task is deleting itself. This cannot complete within the* task itself, as a context switch to another task is required.* Place the task in the termination list. The idle task will* check the termination list and free up any memory allocated by* the scheduler for the TCB and stack of the deleted task.* 一个任务正在删除自己。* 这无法在当前任务执行内部完成,因为还需要切换到另一个任务的上下文。* 因此将待删除任务放入等待结束任务列表中。* 空闲任务将检查等待结束任务列表,并释放调度器为待删除任务分配的TCB和堆栈内存。*/vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xStateListItem ) );/* Increment the ucTasksDeleted variable so the idle task knows* there is a task that has been deleted and that it should therefore* check the xTasksWaitingTermination list.* 递增ucTasksDeleted变量,以便空闲任务知道有一个任务已被删除,* 因此它应该检查xTasksWaitingTermination列表。* */++uxDeletedTasksWaitingCleanUp;/* Call the delete hook before portPRE_TASK_DELETE_HOOK() as* portPRE_TASK_DELETE_HOOK() does not return in the Win32 port.* 在调用portPRE_TASK_delete_hook之前调用delete钩子,* 因为portPRE_TAS K_delete_ hook在Win32端口中不返回。* */traceTASK_DELETE( pxTCB );/* The pre-delete hook is primarily for the Windows simulator,* in which Windows specific clean up operations are performed,* after which it is not possible to yield away from this task -* hence xYieldPending is used to latch that a context switch is* required.* 预删除挂钩主要用于Windows模拟器,* 在该模拟器中执行特定于Windows的清理操作,之后不可能放弃此任务,* 因此xYieldPending用于锁定需要进行上下文切换。* */portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending );
}
6. 如果待删除任务是其它任务
--uxCurrentNumberOfTasks; /* 当前任务个数自减一 */
traceTASK_DELETE( pxTCB );/* Reset the next expected unblock time in case it referred to* the task that has just been deleted.* 重置下一个预期的解锁时间,以防它引用了刚刚被删除的任务,即下一个解除等待准备运行的任务就是待删除任务。*/
prvResetNextTaskUnblockTime();
/* 重置下一个任务解锁时间 */
static void prvResetNextTaskUnblockTime( void )
{if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) /* 延迟任务列表是否为空 */{/* The new current delayed list is empty. Set xNextTaskUnblockTime to* the maximum possible value so it is extremely unlikely that the* if( xTickCount >= xNextTaskUnblockTime ) test will pass until* there is an item in the delayed list.* 当前新的延迟列表为空。将xNextTaskUnblockTime设置为最大可能值*/xNextTaskUnblockTime = portMAX_DELAY;}else{/* The new current delayed list is not empty, get the value of* the item at the head of the delayed list. This is the time at* which the task at the head of the delayed list should be removed* from the Blocked state.* 当前新的延迟列表不为空,请获取延迟列表头部项目的值。* 此时,应将延迟列表开头的任务从“阻塞”状态中删除。* 即准备让下一个被阻塞的任务开始执行*/xNextTaskUnblockTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxDelayedTaskList );}
}
/** Access macro to determine if a list contains any items. The macro will* only have the value true if the list is empty.* 访问宏以确定列表是否包含任何列表项。只有当列表为空时,宏才会具有值true。*/
#define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE )
PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. 指向当前正在使用的延迟任务列表*/
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/** Access macro to retrieve the value of the list item at the head of a given list. * 访问宏以检索给定列表开头的列表项的值*/
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue ) /* 末尾列表项的下一个列表项即为头部列表项。 */
PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. 在调度程序启动之前,已初始化为portMAX_DELAY*/
7. 退出临界区
taskEXIT_CRITICAL(); /* 退出临界区,本质是开启全局中断 */
7.1 第一步
#define taskEXIT_CRITICAL() portEXIT_CRITICAL()
7.2 第二步
#define portEXIT_CRITICAL() vPortExitCritical()
7.3 第三步
void vPortExitCritical( void )
{ulCriticalNesting--;if( ulCriticalNesting == 0 ){portENABLE_INTERRUPTS();}
}
7.4 第四步
#define portENABLE_INTERRUPTS() __asm(" clrc INTM") /* 打开全局中断 */
8. 如果待删除的任务不是当前运行的任务
/* If the task is not deleting itself, call prvDeleteTCB from outside of* critical section. If a task deletes itself, prvDeleteTCB is called* from prvCheckTasksWaitingTermination which is called from Idle task.* 如果任务不是删除自己,请从临界区外部调用prvDeleteTCB。* 如果任务删除自己,则从空闲任务调用的prvCheckTasksWaitingTermination中调用prvDeleteTCB删除任务*/
if( pxTCB != pxCurrentTCB )
{prvDeleteTCB( pxTCB );
}
/* 删除任务控制块,根据分配内存的方式释放TCB和堆栈内存 */
#if ( INCLUDE_vTaskDelete == 1 )static void prvDeleteTCB( TCB_t * pxTCB ){/* This call is required specifically for the TriCore port. It must be* above the vPortFree() calls. The call is also used by ports/demos that* want to allocate and clean RAM statically.* 此调用是TriCore端口特有的。它必须位于vPortFree调用之上。* 该调用也被希望静态分配和清理RAM的端口/演示使用。* */portCLEAN_UP_TCB( pxTCB );#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) || ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) ){/* Free up the memory allocated for the task's TLS Block. */configDEINIT_TLS_BLOCK( pxCurrentTCB->xTLSBlock );}#endif#if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( portUSING_MPU_WRAPPERS == 0 ) ){/* The task can only have been allocated dynamically - free both* the stack and TCB.* 该任务只能是被动态分配,需要释放堆栈和TCB* */vPortFreeStack( pxTCB->pxStack );vPortFree( pxTCB );}#elif ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */{/* The task could have been allocated statically or dynamically, so* check what was statically allocated before trying to free the* memory.* 任务可以静态或动态分配,因此在尝试释放内存之前,请检查静态分配的内容* */if( pxTCB->ucStaticallyAllocated == tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ){/* Both the stack and TCB were allocated dynamically, so both* must be freed.* 堆栈和TCB都是动态分配的,因此必须释放它们。* */vPortFreeStack( pxTCB->pxStack );vPortFree( pxTCB );}else if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_ONLY ){/* Only the stack was statically allocated, so the TCB is the* only memory that must be freed.* 只有堆栈是静态分配的,因此TCB是唯一必须释放的内存。* */vPortFree( pxTCB );}else{/* Neither the stack nor the TCB were allocated dynamically, so* nothing needs to be freed.* 堆栈和TCB都不是动态分配的,因此不需要释放任何内容* */configASSERT( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB );mtCOVERAGE_TEST_MARKER();}}#endif /* configSUPPORT_DYNAMIC_ALLOCATION */}#endif /* INCLUDE_vTaskDelete */
9. 如果待删除的任务不是当前运行的任务
/* Force a reschedule if it is the currently running task that has just* been deleted.* 如果删除的是当前正在运行的任务,则强制重新开启一次任务调度*/
if( xSchedulerRunning != pdFALSE ) /* 任务调度器正在运行中 */
{if( pxTCB == pxCurrentTCB ) /* 删除的是当前正在运行的任务 */{configASSERT( uxSchedulerSuspended == 0 );portYIELD_WITHIN_API();}else{mtCOVERAGE_TEST_MARKER();}
}
PRIVILEGED_DATA static volatile BaseType_t xSchedulerRunning = pdFALSE;
#ifndef portYIELD_WITHIN_API#define portYIELD_WITHIN_API portYIELD
#endif
#define portYIELD() do{bYield = 1; __asm(" INTR INT14");}while(0)
相关文章:
《FreeRTOS任务删除篇》
任务删除函数 源码1. 进入临界区1.1 第一步1.2 第二步1.3 第三步1.4 第四步 2. 获取待删除任务的任务控制块TCB3. 从就绪/延迟列表中删除任务4. 从事件列表中删除任务5. 如果待删除任务是当前运行的任务6. 如果待删除任务是其它任务7. 退出临界区7.1 第一步7.2 第二步7.3 第三步…...

递归算法专题一>Pow(x, n)
题目: 解析: 代码: public double myPow(double x, int n) {return n < 0 ? 1.0 / pow(x,-n) : pow(x,n); }private double pow(double x, int n){if(n 0) return 1.0;double tmp pow(x,n / 2);return n % 2 0 ? tmp * tmp : tmp …...

数据结构第一讲
数据结构定义 算法的定义 什么是好算法? 空间复杂度 时间复杂度 例子1 打印1到N之间的正整数 有递归和循环两种方法实现。 但是在数字变大后,递归的方法会导致内存占用过多而崩溃。 而循环则不会 例子2 写程序给定多项式在X处的值 从里往外算的算…...
SHELL笔记(循环)
在 Shell 编程中,循环结构是极为重要的一部分,它能够让我们轻松地重复执行特定的代码块,从而高效地处理各种重复性任务。本文将详细介绍 Shell 中常见的循环结构,包括 for 循环、while 循环和 until 循环,并通过具体的…...

SpringBoot多文件上传
多文件上传是在单文件上传的基础上修改而来,不了解单文件上传可以参考上一篇。以下在将修改部分展示如下: 一、修改upload.html文件: <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title&g…...

MyBatis-数据库连接池、属性文件config.properties、类名简化、MyBatis的整体架构
一、数据库连接池 1、概述 存储实现创建好的连接对象的容器 2、优点 避免了频繁创建和销毁连接对象 3、使用 在使用到连接对象时可在数据库连接池中直接获取 4、实现 不需要我们去实现,框架和一些第三方有现成的组件(C3P0、ADCP、德鲁伊(阿里巴巴)ÿ…...

Flink-Source的使用
Data Sources 是什么呢?就字面意思其实就可以知道:数据来源。 Flink 做为一款流式计算框架,它可用来做批处理,也可以用来做流处理,这个 Data Sources 就是数据的来源地。 flink在批/流处理中常见的source主要有两大类…...

C0031.在Clion中使用mingw编译器来编译opencv的配置方法
mingw编译器编译opencv库的配置方法...
Android——连接MySQL(Java版)
Android——连接MySQL(Java版) 目录: Android——连接MySQL(Java版)一、JDBC1、什么是JDBC2、载入JDBC3、创建JDBC的工具类 二、使用数据库 一、JDBC 1、什么是JDBC JDBC全称Java Database Connectivity,译为Java语言连接数据库,是sun公司制…...
「四」体验HarmonyOS端云一体化开发模板——工程目录结构与云侧工程一键部署AGC云端
关于作者 白晓明 宁夏图尔科技有限公司董事长兼CEO、坚果派联合创始人 华为HDE、润和软件HiHope社区专家、鸿蒙KOL、仓颉KOL 华为开发者学堂/51CTO学堂/CSDN学堂认证讲师 开放原子开源基金会2023开源贡献之星 「目录」 「一」HarmonyOS端云一体化概要 「二」体验HarmonyOS端云一…...
Kotlin:后端开发的新宠
在当今的软件开发领域,编程语言的选择对于项目的成功至关重要。Kotlin,一种由 JetBrains 开发的编程语言,近年来在后端领域逐渐崭露头角,展现出了广阔的应用前景。 一、Kotlin 简介 Kotlin 是一种基于 JVM(Java Virt…...

SSM全家桶 1.Maven
或许总要彻彻底底地绝望一次 才能重新再活一次 —— 24.11.20 maven在如今的idea中已经实现自动配置,不需要我们手动下载 一、Maven的简介和快速入门 Maven 是一款为 Java 项目构建管理、依赖管理的工具(软件),使用 Maven 可以自动化构建测试、打包和发…...

SpringBoot 集成 html2Pdf
一、概述: 1. springboot如何生成pdf,接口可以预览可以下载 2. vue下载通过bold如何下载 3. 一些细节:页脚、页眉、水印、每一页得样式添加 二、直接上代码【主要是一个记录下次开发更快】 模板位置 1. 导入pom包 <dependency><g…...
利用 Watchtower 自动监听并更新正在运行的 Docker 容器
本文首发于只抄博客,欢迎点击原文链接了解更多内容。 前言 大部分 VPS 和 NAS 用户或多或少都有用 Docker 来部署一些 Self-hosting 的服务,其中大部分项目都是开源项目,更新频率非常高,特别是一些版本 0.x 的项目,及…...

Nodejs开发仿马蜂窝旅游小程序API接口,服务器端开发,商家后台 Vue3+微信小程序+koa+mongodb+node.js
文章目录 🚀 开启您的互联网创业新篇章一、🔥 课程亮点:二、🌐 适合人群:学习这个课程后,您将会收获到三、旅游后台管理系统1.后台登录界面2.后台首页 四、前台旅游小程序1.首页展示2.目的地界面3.搜索功能…...
极限失控的大模型使电力系统面临的跨域攻击风险及应对措施
目录: 0 引言 1 就大模型发生极限失控的风险进行讨论的必要性、紧迫性 1.1 预训练的数据来源 1.2 能力涌现与不可解释性 1.3 大模型与物质世界的连接 1.4 数量效应与失控 1.5 大模型发生极限失控的风险 1.5.1 人工智能反叛所需要素能力的拼图 1.5.2 火种源…...
mybatis-plus方法无效且字段映射失败错误排查
问题: Invalid bound statement (not found): com.htlc.assetswap.mapper.WalletMapper.insert,并且select * 进行查询时带下划线的字段未成功映射。 排查: 1.检查WalletMapper接口,确保继承自BaseMapper 2.启用驼峰命名法映射。a…...

librdns一个开源DNS解析库
原文地址:librdns一个开源DNS解析库 – 无敌牛 欢迎参观我的个人博客:无敌牛 – 技术/著作/典籍/分享等 介绍 librdns是一个开源的异步多功能插件式的解析器,用于DNS解析。 源代码地址:GitHub - vstakhov/librdns: Asynchrono…...
Unity3D 逻辑服的Entity, ComponentData与System划分详解
前言 在Unity3D中,逻辑服(Entity, ComponentData和System)是一种非常高效的组件化设计模式,它可以帮助开发者更好地管理游戏中的实体和逻辑。本文将详细介绍Unity3D逻辑服的概念以及如何实现Entity、ComponentData和System的划分。 对惹,这…...

跟《经济学人》学英文:2024年11月23日这期 Why British MPs should vote for assisted dying
Why British MPs should vote for assisted dying A long-awaited liberal reform is in jeopardy in jeopardy:在危险中 jeopardy:美 [ˈdʒepərdi] 危险;危机;风险; 原文: THIS NEWSPAPER believes …...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

stm32wle5 lpuart DMA数据不接收
配置波特率9600时,需要使用外部低速晶振...

基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)
引言 在嵌入式系统中,用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例,介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单,执行相应操作,并提供平滑的滚动动画效果。 本文设计了一个…...
鸿蒙HarmonyOS 5军旗小游戏实现指南
1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发,采用DevEco Studio实现,包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...
React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?
系列回顾: 在上一篇《React核心概念:State是什么?》中,我们学习了如何使用useState让一个组件拥有自己的内部数据(State),并通过一个计数器案例,实现了组件的自我更新。这很棒&#…...
手动给中文分词和 直接用神经网络RNN做有什么区别
手动分词和基于神经网络(如 RNN)的自动分词在原理、实现方式和效果上有显著差异,以下是核心对比: 1. 实现原理对比 对比维度手动分词(规则 / 词典驱动)神经网络 RNN 分词(数据驱动)…...