嵌入式实时操作系统笔记3:FreeRTOS移植(STM32F407)_编写简单的FreeRTOS任务例程

上文讲到UC/OS III系统的移植,那篇文章是失败了的,网络上的资料真是层次不清,多有遗漏步骤,导致单片机连操作系统的初始化都卡在那,这次换个赛道,学FreeRTOS吧......

今日任务如标题所示:FreeRTOS移植(STM32F407)_编写简单的FreeRTOS任务例程

文章提供测试代码讲解、完整工程下载、测试效果图

这次总算是成功了!也是成功触碰到操作系统的领域了

目录

FreeRTOS移植准备:

准备STM32F407VET6空项目:

下载FreeRTOS V202212.00源码:

提取FreeRTOS V202212.00源码:

工程添加FreeRTOS源码:

添加文件到FreeRTOS/port:

添加文件到FreeRTOS/src:

添加FreeRTOSConfig.h:

所有工程源码添加情况如下所示:

 魔棒添加各个头文件路径:

 FreeRTOS/includes:

工程修改一些文件:

修改 FreeRTOSConfig.h :

修改stm32f4xx_it.h:

修改系统时钟初始化函数:

修改systick中断服务函数:

主函数:

问题解决:

编译报错:FCARM - Output Name not specified, please check 'Options for Target - Utilities'

编译报错:钩子函数未定义:

最终实现0报错:

编写简单的FreeRTOS任务例程:

宏定义各个任务:

主函数创建开始任务:

编写START_TASK 开始任务函数:

编写其余任务函数:

测试效果图:

测试遇到的问题:

1、只有task3一个最后初始化的任务能执行:

2、串口经常断开与PC的连接,且LED亮度闪烁不定:

测试工程说明:

测试工程下载:

测试工程文件注释勘误:

网上查阅资料贴出:


FreeRTOS移植准备:

准备STM32F407VET6空项目:

这里我使用了自己封装的裸机开发空项目文件,它的介绍如下,下载网址也同步贴出:

https://download.csdn.net/download/qq_64257614/89338792?spm=1001.2014.3001.5503

下载FreeRTOS V202212.00源码:

官方网址贴出:

FreeRTOS - Market leading RTOS (Real Time Operating System) for embedded systems with Internet of Things extensions

官网提供的github链接太卡了,建议去代码托管网站下载:

FreeRTOS Real Time Kernel (RTOS) - Browse /FreeRTOS at SourceForge.net

我这里就直接下载目前的最新版本了:

 点这个zip文件下载就行了:

提取FreeRTOS V202212.00源码:

目录   FreeRTOSv202212.00\FreeRTOS\Source  下的就是源码:

在STM32空项目文件夹目录新建文件夹FreeRTOS:并移动文件:

然后在FreeRTOSv202212.00\FreeRTOS\Source\portable 目录将这俩文件夹移动到PORT

最后直接将 目录 FreeRTOSv202212.00\FreeRTOS\Source 下的include文件夹移动到在STM32空项目文件夹目录新建文件夹FreeRTOS

最后复制FreeRTOSv202212.00\FreeRTOS\Demo\CORTEX_M4F_STM32F407ZG-SK 中的 FreeRTOSConfig.h 到文件夹至此移动结束:

工程添加FreeRTOS源码:

先新建俩个分组:

FreeRTOS/src
FreeRTOS/port

添加文件到FreeRTOS/port

点击---FreeRTOS/src----AddFiles

添加以下目录中所有文件 :\FreeRTOS\PORT\RVDS\ARM_CM4F

如果查找不到文件,别忘记将文件类型改为 ALL Files

添加完后应如是:

方才添加时发现,有俩个ARM_M4相关的文件夹供选择,那它们有何区别呢:

  1. ARM_CM4F:这通常表示针对ARM Cortex-M4F内核的源代码。STM32F407VET6是一个基于ARM Cortex-M4F的处理器,它包含了浮点单元(FPU),因此如果你打算使用到浮点运算,那么选择ARM_CM4F的文件可能更为合适。
  2. ARM_CM4_MPU:这通常与ARM Cortex-M4处理器中的内存保护单元(MPU)相关。MPU用于提供硬件级别的内存访问控制,以防止一个任务或进程访问到另一个任务或进程的内存区域。如果你的项目需要这种级别的内存保护,那么你可能需要选择ARM_CM4_MPU的文件。
  3. 至此我们知道了STM32F407VET6 需要添加的是ARM_CM4F 文件夹中的内容!

然后再添加添加以下目录中的文件 :\FreeRTOS\FreeRTOS\PORT\MemMang

这里我们就添加heap4.c即可,(这个是选择一个添加的,具体介绍下面会提到)

添加heap4.c
  • heap_1.c这是一个非常简单的内存管理实现,它使用一个静态分配的数组作为堆。适用于那些内存需求相对固定且不需要复杂的内存管理的应用。
  • heap_2.c这个实现提供了比heap_1更复杂的内存管理,包括内存碎片合并等特性。但它仍然基于一个静态分配的数组。
  • heap_3.cheap_4.c这些实现提供了更复杂的内存管理算法,但它们可能并不总是适合嵌入式系统,因为它们可能需要更多的RAM或处理时间。
  • heap_5.c(可能称为heap_5x.c):这是一个基于最佳适应(best-fit)算法的堆实现,它提供了较好的内存碎片管理,但可能需要更复杂的实现和更多的处理时间。
  • heap_x.c这是一个用户定义的内存管理实现,允许你根据自己的需求编写自定义的内存管理代码。

添加文件到FreeRTOS/src

点击---FreeRTOS/src----AddFiles

添加以下目录中所有文件 :\FreeRTOS\SRC

如果查找不到文件,别忘记将文件类型改为 ALL Files

添加文件到 FreeRTOS/src

添加FreeRTOSConfig.h:

由之前移动提取源码的操作可知,这个.h文件目录在截图所示文件夹内:

FreeRTOSConfig.h目录

这个头文件随便添加在哪都行,我是放置在了startup 组内了:

所有工程源码添加情况如下所示:

 魔棒添加各个头文件路径:

 FreeRTOS/includes:

这我额外新增一个组FreeRTOS/includes并将FreeRTOS\include文件夹中的内容都放进了:

工程修改一些文件:

修改 FreeRTOSConfig.h :

宏定义配置功能介绍,这部分可以先跳过或者快速浏览,以后用到在仔细看:

/*设置为1,表示启用抢占式调度。这意味着当一个更高优先级的任务准备好运行时,它会立即抢占当前运行的任务的CPU。*/
#define configUSE_PREEMPTION			1
/*设置为1,表示启用空闲钩子函数。空闲钩子函数是一个可以在系统处于空闲状态时调用的函数。*/
#define configUSE_IDLE_HOOK				1
/*设置为1,表示启用滴答定时器钩子函数。这个函数在每个滴答定时器中断时都会被调用。*/
#define configUSE_TICK_HOOK				1
/*定义CPU的时钟频率。这里使用了SystemCoreClock宏,它可能是在其他地方定义的。*/
#define configCPU_CLOCK_HZ				( SystemCoreClock )
/*定义了FreeRTOS滴答定时器的频率。这里设置为1000Hz,意味着每秒有1000个滴答。*/
#define configTICK_RATE_HZ				( ( TickType_t ) 1000 )
/*定义了FreeRTOS中可以使用的最大任务优先级数量。这里设置为5。*/
#define configMAX_PRIORITIES			( 5 )
/*定义了每个任务的最小栈大小(以字节为单位)。这里设置为130字节。*/
#define configMINIMAL_STACK_SIZE		( ( unsigned short ) 130 )
/*定义了FreeRTOS可用的总堆大小(以字节为单位)。这里设置为75KB。*/	
#define configTOTAL_HEAP_SIZE			( ( size_t ) ( 75 * 1024 ) )
/*定义了任务名称的最大长度。这里设置为10个字符。*/
#define configMAX_TASK_NAME_LEN			( 10 )
/*设置为1,表示启用跟踪功能。这允许你收集有关任务执行、队列操作和其他RTOS活动的信息。*/
#define configUSE_TRACE_FACILITY		1
/*设置为0,表示使用32位滴答计数器。如果设置为1,则使用16位滴答计数器。*/
#define configUSE_16_BIT_TICKS			0
/*设置为1,表示在空闲任务中应该进行任务切换(如果有其他任务准备好运行)。*/
#define configIDLE_SHOULD_YIELD			1
/*设置为1,表示启用互斥量(mutex)功能。*/
#define configUSE_MUTEXES				1
/*定义了队列注册表的项数。这允许你跟踪队列的使用情况,并帮助调试。*/
#define configQUEUE_REGISTRY_SIZE		8
/*定义了栈溢出检查的类型。这里设置为2,可能是某种特定类型的检查(具体的检查方式可能因FreeRTOS版本而异)。*/
#define configCHECK_FOR_STACK_OVERFLOW	2
/*设置为1,表示启用递归互斥量。递归互斥量允许同一个任务多次获取同一个互斥量。*/
#define configUSE_RECURSIVE_MUTEXES		1
/*设置为1,表示启用内存分配失败钩子函数。当FreeRTOS的堆内存耗尽时,这个函数会被调用。*/
#define configUSE_MALLOC_FAILED_HOOK	1
/*设置为0,表示不启用应用程序任务标签功能。*/
#define configUSE_APPLICATION_TASK_TAG	0
/*设置为1,表示启用计数信号量。*/
#define configUSE_COUNTING_SEMAPHORES	1
/*设置为0,表示不生成运行时统计信息。如果设置为1,FreeRTOS会收集关于任务运行时间的信息。*/
#define configGENERATE_RUN_TIME_STATS	0/* Software timer definitions. */
/*设置为1,表示启用FreeRTOS的软件定时器功能。软件定时器允许你在没有硬件定时器可用或想要更复杂的定时行为时使用软件实现定时器。*/
#define configUSE_TIMERS				1
/*定义了软件定时器任务的优先级。在这里,它被设置为2,意味着软件定时器任务的优先级为2。*/
#define configTIMER_TASK_PRIORITY		( 2 )
/*定义了软件定时器队列的长度。当定时器到期时,它们会被添加到这个队列中以供软件定时器任务处理。队列长度为10表示最多可以有10个定时器等待处理。*/
#define configTIMER_QUEUE_LENGTH		10
/*定义了软件定时器任务的栈深度。这里它被设置为configMINIMAL_STACK_SIZE * 2,意味着软件定时器任务的栈大小是最小栈大小的两倍。*/
#define configTIMER_TASK_STACK_DEPTH	( configMINIMAL_STACK_SIZE * 2 )/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
/*设置为1,表示包含vTaskPrioritySet函数。这个函数用于动态地改变任务的优先级。*/
#define INCLUDE_vTaskPrioritySet		1
/*设置为1,表示包含uxTaskPriorityGet函数。这个函数用于获取任务的当前优先级。*/
#define INCLUDE_uxTaskPriorityGet		1
/*设置为1,表示包含vTaskDelete函数。这个函数用于删除一个任务,释放其占用的资源。*/
#define INCLUDE_vTaskDelete				1
/*设置为1,表示包含vTaskCleanUpResources函数。这个函数用于清理FreeRTOS内核在不再需要时占用的资源。通常,在应用程序的最后一个任务结束时调用。*/
#define INCLUDE_vTaskCleanUpResources	1
/*设置为1,表示包含vTaskSuspend函数。这个函数用于挂起一个任务,使其不再运行,直到它被恢复。*/
#define INCLUDE_vTaskSuspend			1
/*设置为1,表示包含vTaskDelayUntil函数。这个函数用于使当前任务延迟到指定的绝对时间。*/
#define INCLUDE_vTaskDelayUntil			1
/*设置为1,表示包含vTaskDelay函数。这个函数用于使当前任务延迟指定的时间片数(滴答数)。*/
#define INCLUDE_vTaskDelay				1

 在FreeRTOSConfig.h添加以下头文件:

#include "stm32f4xx.h"//

修改条件编译:

改为:

#if defined (__ICCARM__) || defined (__CC_ARM)  ||  defined (__GNUC__) #include <stdint.h>extern uint32_t SystemCoreClock;
#endif

屏蔽FreeRTOSConfig.h掉底部的#define xPortSysTickHandler SysTick_Handler

修改stm32f4xx_it.h:

注释掉几个中断服务函数 PendSV_Handler(),SVC_Handler(),SysTick_Handler()

因为已经在FreeRTOS的相关文件中需要用到,并提供定义了:

修改系统时钟初始化函数:

这部分Systick系统时钟的初始化目的是要将系统时钟的频率  与FreeRTOS的宏定义configTICK_RATE_HZ 进行联系,之后是可以通过修改 configTICK_RATE_HZ来反过来直接修改Systick系统时钟的频率的

			   
//初始化延迟函数
//SYSTICK的时钟固定为AHB时钟,基础例程里面SYSTICK时钟频率为AHB/8
//这里为了兼容FreeRTOS,所以将SYSTICK的时钟频率改为AHB的频率!
//SYSCLK:系统时钟频率
void delay_init(u8 SYSCLK)
{u32 reload;SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); fac_us=SYSCLK;							//不论是否使用OS,fac_us都需要使用reload=SYSCLK;							//每秒钟的计数次数 单位为M	   reload*=1000000/configTICK_RATE_HZ;		//根据configTICK_RATE_HZ设定溢出时间//reload为24位寄存器,最大值:16777216,在168M下,约合0.0998s左右	fac_ms=1000/configTICK_RATE_HZ;			//代表OS可以延时的最少单位	   SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;//开启SYSTICK中断SysTick->LOAD=reload; 					//每1/configTICK_RATE_HZ断一次	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK     
}								    

修改systick中断服务函数:

这个函数我添加在了#include "delay.h":

// 声明SysTick中断处理函数  
void SysTick_Handler(void)
{if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED){xPortSysTickHandler();}
}

主函数:

先添加头文件,然后删去while(1)循环之类的:

/*****************FREE RTOS头文件***************/
#include "FreeRTOS.h"
#include "task.h"

问题解决:

编译报错:FCARM - Output Name not specified, please check 'Options for Target - Utilities'

这是因为某个导入文件的格式选错了:这是个说明文件,不小心暴力导入了,直接鼠标右键Remove即可

编译报错:钩子函数未定义:

FreeRTOSConfig.h中关闭这些钩子函数,他们都是宏定义决定,这里将  configUSE_IDLE_HOOK

configUSE_TICK_HOOK

configUSE_MALLOC_FAILED_HOOK

configUSE_FOR_STACK_OVERFLOW

或者叫configCHECK_FOR_STACK_OVERFLOW

定义为0

最终实现0报错:

编写简单的FreeRTOS任务例程:

各个TASK的任务如下描述:

//TASK_1 串口报告自己执行的次数 (0.5s) 并打开LED

//TASK_2 串口报告自己执行的次数 (1.2s) 并关闭LED

//TASK_3 会每隔 5S 打印

宏定义各个任务:

任务优先级 \任务堆栈大小   \任务句柄 \任务函数
/*******开始任务的宏定义*********/
#define START_TASK_PRIO		1         //任务优先级
#define START_STK_SIZE 		128       //任务堆栈大小	
TaskHandle_t StartTask_Handler;     //任务句柄
void start_task(void *pvParameters);//任务函数/*******TASK1任务的宏定义*********/
#define TASK1_TASK_PRIO		2         //任务优先级
#define TASK1_STK_SIZE 		50        //任务堆栈大小	
TaskHandle_t Task1_Handler;         //任务句柄
void task1_task(void *pvParameters);//任务函数/*******TASK2任务的宏定义*********/
#define TASK2_TASK_PRIO		3         //任务优先级
#define TASK2_STK_SIZE 		50        //任务堆栈大小	
TaskHandle_t Task2_Handler;         //任务句柄
void task2_task(void *pvParameters);//任务函数/*******TASK3任务的宏定义*********/
#define TASK3_TASK_PRIO		3         //任务优先级
#define TASK3_STK_SIZE 		50        //任务堆栈大小	
TaskHandle_t Task3_Handler;         //任务句柄
void task3_task(void *pvParameters);//任务函数

主函数创建开始任务:

int main(void)
{	system_init_all();       //开机初始化系统所有模块//开启 FreeRTOS 操作系统,创建开始任务!//创建开始任务xTaskCreate((TaskFunction_t )start_task,            //任务函数(const char*    )"start_task",          //任务名称(uint16_t       )START_STK_SIZE,        //任务堆栈大小(void*          )NULL,                  //传递给任务函数的参数(UBaseType_t    )START_TASK_PRIO,       //任务优先级(TaskHandle_t*  )&StartTask_Handler);   //任务句柄              UsartPrintf(USART1," FreeRTOS : Hello World!\r\n");	//开机打印测试字符串 vTaskStartScheduler();          //开启任务调度	
}

编写START_TASK 开始任务函数:

 START_TASK 开始任务函数 在创建完其余任务后必须删除 START_TASK 任务

不然他也会出现在时间片轮询,造成不必要的占用!

//开始任务任务函数
void start_task(void *pvParameters)
{//创建TASK1任务xTaskCreate((TaskFunction_t )task1_task,     	(const char*    )"task1_task",   	(uint16_t       )TASK1_STK_SIZE, (void*          )NULL,				(UBaseType_t    )TASK1_TASK_PRIO,	(TaskHandle_t*  )&Task1_Handler);   //创建TASK2任务xTaskCreate((TaskFunction_t )task2_task,     	(const char*    )"task2_task",   	(uint16_t       )TASK2_STK_SIZE, (void*          )NULL,				(UBaseType_t    )TASK2_TASK_PRIO,	(TaskHandle_t*  )&Task2_Handler);  //创建TASK3任务xTaskCreate((TaskFunction_t )task3_task,     	(const char*    )"task3_task",   	(uint16_t       )TASK3_STK_SIZE, (void*          )NULL,				(UBaseType_t    )TASK3_TASK_PRIO,	(TaskHandle_t*  )&Task3_Handler);  //删除开始任务							vTaskDelete(StartTask_Handler); 
}

编写其余任务函数:

在开始任务的基础上,其他任务只需要在此基础上添加三个地方:
①声明;      ②函数编写;     ③开始任务函数调用


//TASK_1 串口报告自己执行的次数 (0.5s)
void task1_task(void *pvParameters)
{int TASK1_num=0;  //记录任务TASK_1执行次数 while(1){TASK1_num++;	//任务TASK_1执行次数加1PBout(2)=1;UsartPrintf(USART1,"TASK_1 has Carred out %d times! \r\n",TASK1_num);	//打印测试字符串(并报告TASK_1执行次数)vTaskDelay(500);//使当前任务延迟指定的时间(2s):  (让当前任务放弃CPU一段时间,CPU让给其余任务)}
}//TASK_2 串口报告自己执行的次数 (1.2s)
void task2_task(void *pvParameters)
{int TASK2_num=0;  //记录任务TASK_2执行次数while(1){TASK2_num++;PBout(2)=0;UsartPrintf(USART1,"TASK_2 has Carred out %d times! \r\n",TASK2_num);	//打印测试字符串(并报告TASK_2执行次数)vTaskDelay(1200);//使当前任务延迟指定的时间(1s):  (让当前任务放弃CPU一段时间,CPU让给其余任务)}
}//TASK_3 会每隔 5S 打印
void task3_task(void *pvParameters)
{int TASK3_num=0;  //记录任务TASK_3执行次数								 while(1){TASK3_num++;UsartPrintf(USART1,"TASK_3 has Carred out %d times! \r\n",TASK3_num);	//打印测试字符串(并报告TASK_3执行次数)							 vTaskDelay(5000); //使当前任务延迟指定的时间(17s):  (让当前任务放弃CPU一段时间,CPU让给其余任务)	}
}

测试效果图:

在串口测试可以看出三个任务各自的延时关系,以及不阻塞延时就是将延时的时间空闲留给其余任务执行:

框图关系可以看出以下几点:

1、三个任务被创建后立马执行一次

2、任务三 Task3 执行一次到下次的间隔有 5S,任务1 Task1 执行了9次(约4.5s),任务2 Task2 执行了4次(约4.8s)

3、任务二 Task2执行一次到下次的间隔有 1.2S,任务1 Task1 执行了2次(约1s)

然后还有LED会被 Task1 Task2 周期性亮灭

测试遇到的问题:

1、只有task3一个最后初始化的任务能执行:

(测试时尝试删去过task3,发现最后初始化的任务task2仍然是这个效果,也能执行,但仅仅是最后初始化的任务能执行)

解决:我是屏蔽删去了定时器的初始化,就能让三个任务都能执行了,后面应该会学到任务屏蔽块函数,能够屏蔽这些中断,防止任务被打断得连初始化进入都进不来

2、串口经常断开与PC的连接,且LED亮度闪烁不定:

这明显是供电不足导致的,我额外插个USB稳定的电源解决了

测试工程说明:

这里说明一下,因为我在初学时到处查阅资料无法理解Systick系统时钟的初始化与中断服务函数是如何与FreeRTOS的宏定义configTICK_RATE_HZ进行联系的,因此移植了正点原子的delay.h文件(初始化系统时钟的,可选OS系统),原工程的board.h被移除了 

/*NULL指向我 { FreeRTOS } 项目封装说明:1、所有头文件都引用在headfire.h中,新建.h都只需 #include "headfire.h" 即可,也方便查阅修改(1) headfire.h新增 位带操作,实现51类似的GPIO控制功能2、Timer_common_init();可以初始化任意 TIMx 为通用定时器(带溢出中断),但必须在调用前添加开启相应定时器时钟的语句    3、函数 system_init_all(void); 初始化STM32所有外设模块 移动到了 headfire.h4、 自主配置修改了 SystemTick 的配置 内核定时器SystemTick  (1) 工程文件 #include "delay.h" 内配置了 SystemTick 内核定时器(2) SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); 函数初始化了SystemTick 内核定时器 的时钟源是168M(3) 增加了 SystemTick 定时中断功能(4) 声明SysTick中断处理函数  void SysTick_Handler(void) 必须要有,否则中断无法跳出,程序会卡在 初始化 1ms (这个时间是根据说明项5得出的) 后5、 SysTick新增中断,频率 为1000Hz, 即1ms  (1) 如想更改 内核定时器 溢出频率 更改   #define configTICK_RATE_HZ (1000) 括号内的值即可:  (在FreeRTOSConfig.h中)        uint32_t reload = SystemCoreClock / 1000 - 1; // 1ms中断频率 (1000Hz)reload = configTICK_RATE_HZTips: 1、SystemCoreClock =168 000 0002、SysTick_LOAD = (SystemCoreClock / TickRate) - 13、SysTick_LOAD = reload;(2) 内核定时器 未配置 溢出中断的NVIC优先级 (如果需要配置,我觉得应该要比其余中断低 甚至于最低组4)(3)6、 #include <board.h> 新增位带操作的宏定义 ,可以实现51类似的GPIO控制功能7、 UsartPrintf (USART_TypeDef *USARTx, char *fmt,...)函数 能够做到使用任意串口打印,并且用法与Printf相同(需要多传第一个参数 USARTx)(1) 该函数定义在 : #include "Uart.h"(2) 如需别处复制使用 需包含头文件 #include "stdarg.h"*/

测试工程下载:

https://download.csdn.net/download/qq_64257614/89342421

测试工程文件注释勘误:

测试工程在学习的过程中经过多次修改,有部分注释与代码实际有出入不慎对应,这里勘误一下:

这里的延时是500ms,但注释写的是2S,注释错误

这里的延时是1200ms,但注释写的是1S,注释错误

这里的延时是5s,但注释写的是17S,注释错误

网上查阅资料贴出:

2、STM32F407移植FreeRTOS步骤_systemcoreclock 未定义-CSDN博客

FreeRTOS运行一次后卡死_freertos任务执行一次-CSDN博客

01 FreeRTOS任务实例_freertos例程-CSDN博客

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

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

相关文章

手机端如何访问本地vue+vite项目,实现实时调试?

一、应用场景 h5&#xff08;vuevite&#xff09;嵌入app后&#xff0c;出现某种问题时&#xff0c;需要每次发布坏境后&#xff0c;才能才看效果&#xff0c;这种来回很耗时间&#xff0c;本文章在于解决手机端直接访问本地启动应用项目&#xff0c;无需重复发布坏境 二、实…

春秋CVE-2022-23906

简介 CMS Made Simple v2.2.15 被发现包含通过上传图片功能的远程命令执行 (RCE) 漏洞。此漏洞通过精心制作的图像文件被利用。 正文 1.进入靶场2.进入登录界面&#xff0c;弱口令admin/123456 3.进入后台&#xff0c;文件上传点 4.上传一句话木马图片 5.复制图片&#xf…

Mysql之主从同步

1.BinLog同步机制 Mysql要去保证高可用&#xff0c;或者去分担请求压力&#xff0c;一般会去主从部署&#xff0c;读写分离。写库只负责写&#xff0c;而读库更多的去承担读的请求&#xff0c;从库不写数据&#xff0c;数据从主库同步&#xff0c;那么到底是怎么同步的呢&…

嵌入式全栈开发学习笔记---C语言笔试复习大全23

目录 联合体 联合体的定义 联合体的长度 如果来判断设备的字节序&#xff1f; 如何把大端数据转换成小端数据&#xff1f; 枚举 枚举的定义 上一篇复习了结构体&#xff0c;这一节复习联合体和枚举。 说明&#xff1a;我们学过单片机的一般都是有C语言基础的了&#xff…

VBA技术资料MF157:创建每个标题的目录

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

一步到位:用Python实现PC屏幕截图并自动发送邮件,实现屏幕监控

在当前的数字化世界中&#xff0c;自动化已经成为我们日常生活和工作中的关键部分。它不仅提高了效率&#xff0c;还节省了大量的时间和精力。在这篇文章中&#xff0c;我们将探讨如何使用Python来实现一个特定的自动化任务 - PC屏幕截图自动发送到指定的邮箱。 这个任务可能看…

pycharm配置python开发环境—miniconda+black+gitlab

下载miniconda管理python开发环境 miniconda下载地址&#xff1a;https://docs.anaconda.com/free/miniconda/ miniconda最新版本的python版本是python3.12.2&#xff0c;下载这个miniconda最新版本后&#xff0c;会导致执行conda create -n py31013 python3.10.13指令配置py…

Redis - 优惠卷秒杀

场景分析 为了避免对数据库造成压力&#xff0c;我们在新增优惠卷的时候&#xff0c;可以将优惠卷的信息储存在Redis中&#xff0c;这样用户抢购的时候访问优惠卷信息&#xff0c;通过Redis读取信息。 抢购流程&#xff1a; 业务分析 既然在新增优惠卷的时候&#xff0c;我…

蓝桥杯-班级活动

题目描述 小明的老师准备组织一次班级活动。班上一共有 ( n ) 名&#xff08;( n ) 为偶数&#xff09;同学&#xff0c;老师想把所有的同学进行分组&#xff0c;每两名同学一组。为了公平&#xff0c;老师给每名同学随机分配了一个 ( n ) 以内的正整数作为 id&#xff0c;第 …

基于Kafka的日志采集

目录 前言 架构图 资源列表 基础环境 关闭防护墙 关闭内核安全机制 修改主机名 添加hosts映射 一、部署elasticsearch 修改limit限制 部署elasticsearch 修改配置文件 启动 二、部署filebeat 部署filebeat 添加配置文件 启动 三、部署kibana 部署kibana 修…

Google Find My Device:科技守护,安心无忧

在数字化的时代&#xff0c;我们的生活与各种智能设备紧密相连。而 Google Find My Device 便是一款为我们提供安心保障的实用工具。 一、Find My Decice Netword的定义 谷歌的Find My Device Netword旨在通过利用Android设备的众包网络的力量&#xff0c;帮助用户安全的定位所…

深入编程逻辑:从分支到循环的奥秘

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、编程逻辑的基石&#xff1a;分支与循环 分支逻辑详解 代码案例&#xff1a;判断整数是…

从 0 开始本地部署大语言模型

1、准备 ● Ollama&#xff1a;ollama.com ● Docker&#xff1a;https://docs.openwebui.com/ 2、下载 Ollama 进入 Ollama 官网&#xff0c;点击 Download 。 下载完成后&#xff0c;双击安装&#xff0c;什么都不需要勾选&#xff0c;直接下一步即可。安装完成&#xf…

【Qt】Qt组件设置背景图片

1. 方法1&#xff08;paintEvent方式&#xff09; 使用paintEvent()实现 1. .h文件中添加虚函数 protected:void paintEvent(QPaintEvent *event) override;添加虚函数方法&#xff1a; 选中父类&#xff0c;点击鼠标右键点击重构点击 Insert Virtual Funtion of Base Class…

【CCIE | 网络模拟器】部署 EVE-NG

目录 1. 环境准备2. 下载 EVE-NG 镜像3. 安装 EVE-NG 虚拟机3.1 创建 eve-ng 虚拟机3.2 选择存储3.3 定义虚拟机计算资源&#xff08;1&#xff09;开启CPU虚拟化功能&#xff08;2&#xff09;精简置备磁盘 3.4 检查虚拟机设置 4. 安装系统4.1 选择系统语言4.2 选择系统键盘类…

专业渗透测试 Phpsploit-Framework(PSF)框架软件小白入门教程(十二)

本系列课程&#xff0c;将重点讲解Phpsploit-Framework框架软件的基础使用&#xff01; 本文章仅提供学习&#xff0c;切勿将其用于不法手段&#xff01; 接上一篇文章内容&#xff0c;讲述如何进行Phpsploit-Framework软件的基础使用和二次开发。 我们&#xff0c;继续讲一…

爽!AI手绘变插画,接单赚爆了!

我最近发现一款名叫Hyper-SD15-Scribble的AI项目&#xff0c;可以实现一键手绘变插画的功能&#xff0c;而且它搭载了字节出品的超快速生成图片的AI大模型Hyper-SD15&#xff0c;可以实现几乎实时生成图片&#xff0c;有了它&#xff0c;拿去接一些手绘商单分分钟出图&#xff…

数据结构(四)串

2024年5月26日一稿(王道P127) 定义和实现

Ant Design Vue中 a-table 嵌套子表格

需求&#xff1a;在父表格中嵌套子表格&#xff0c;当点击展开某一行时&#xff0c;有展开的关闭当前展开行。使用a-table中的expandedRowKeys 属性和expand 方法。链接&#xff1a;Ant Design Vue 一、属性说明&#xff1a; expandedRowKeys&#xff1a;这个主要是控制展开某行…

modbus开源库libmodbus的C语言使用记录(实现简单的modbus主机/丛机程序,解决libmodbus库安装出现的问题)

libmodbus简介 libmodbus 是一个开源的、跨平台的C库,用于实现Modbus通讯协议。它支持Modbus RTU(RS-232/485)和Modbus TCP协议,可以使开发者方便地在项目中集成Modbus通讯功能。libmodbus的设计目标是简单、灵活和高效,适用于各种大小的嵌入式和桌面应用。 编译运行测试…