嵌入式实时操作系统笔记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.mzph.cn/diannao/15811.shtml

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

相关文章

QTextCodec NO such file or directory让qt6兼容qt5

首先在.pro 文件中新加 QT core5compat这时会报错 链接 报错之后修复qt&#xff0c;新加兼容模块&#xff0c;见链接。

电脑怎么录屏?电脑录屏的7个方法,仅3%的人知道!

你知道电脑怎么录屏吗&#xff1f;在电脑上录屏是向朋友展示炫酷游戏技巧、制作软件教程视频和展示数字艺术技巧的好方法。遗憾的是&#xff0c;屏幕录制并不像截屏那么简单。然而&#xff0c;无论你是在寻找在电脑上录制屏幕&#xff0c;亦或是录制音频的方法&#xff0c;还是…

【代码随想录】二分查找算法总结篇

目录 前言二分查找例题一例题二例题三例题四 前言 本篇文章记录了代码随想录二分查找算法的总结笔记&#xff0c;下面我们一起来学习吧&#xff01;&#xff01; 二分查找 关于二分查找算法&#xff0c;我在之前的这篇博客里面做了非常多的分析&#xff0c;但是后面做题做着…

List Control控件绑定变量

创建基于对话框的mfc项目 添加 List Control控件 右击控件&#xff0c;选择“添加变量” 在初始化对话框代码中增加一些代码 BOOL CMFCApplication3Dlg::OnInitDialog() { //...// TODO: 在此添加额外的初始化代码DWORD dwStyle m_programLangList.GetExtendedStyle(); …

初识Spring Boot

初识Spring Boot SpringBoot是建立在Spring框架之上的一个项目,它的目标是简化Spring应用程序的初始搭建以及开发过程。 对比Spring Spring Boot作为Spring框架的一个模块&#xff0c;旨在简化Spring应用程序的初始搭建和开发过程&#xff0c;以下是Spring Boot相对于传统Spri…

AI视频教程下载:用提示工程在GPT商店构建10个GPTs

你将学到什么&#xff1f; 深入了解ChatGPT平台和GPT商店的生态系统。 开发为多样化应用定制GPT模型的专业知识。 掌握高效内容生成的AI自动化技术。 学习高级提示工程以优化ChatGPT输出。 获取构建AI驱动的数字营销和广告解决方案的技能。 了解如何为SEO写作和优化创建专…

Redis篇 redis基本命令和定时器原理

基本命令和定时器原理 一. exists命令二. del命令三. Expire命令四. ttl命令五. redis的过期策略六. 定时器的两种设计方式七. type命令 一. exists命令 用来判断key的值是否存在 返回值是key的个数 这样写的话&#xff0c;有没有什么区别呢&#xff1f; 效率变低&#xff0c;消…

AI办公自动化:用kimi将子文件夹里面的文件批量重命名

工作任务和目标&#xff1a;一个文件夹下有多个子文件夹 子文件夹中有多个srt文件&#xff0c;需要删除文件名中的english和空格 第一步&#xff0c;在kimi中输入如下提示词&#xff1a; 你是一个Python编程高手&#xff0c;一步步的思考&#xff0c;来编写下面任务的Python脚…

概率论统计——大数定律

大数定律 弱大数定律&#xff08;辛钦大数定律&#xff09; 利用切比雪夫不等式&#xff0c;证明弱大数定律 应用 伯努利大数定理&#xff0c;&#xff08;辛钦大数定理的推论&#xff09; 证明伯努利大数定理 注意&#xff1a;这里将二项分布转化成0,1分布来表示&#xff0c;…

按月爬取天气数据可视化展示

从天气网分析,可以查询每个月的天气情况,这里按照url规则,传入年月,获取数据,最后进行可视化展示,最终效果: 下面是获取过程: 第一步: import requestsdef get_weather(month):url = f"https://lishi.tianqi.com/nanning/{month}.html"response = reques…

从0开始学统计-多个婴儿连续夭折是谋杀吗?

1.什么是小概率事件&#xff1f; 小概率事件是指在一次随机试验中发生概率非常低的事件。一般来说&#xff0c;小概率事件的发生概率远低于一定的阈值&#xff0c;通常取0.05或0.01。在统计学中&#xff0c;这些阈值被称为显著性水平&#xff08;significance level&#xff0…

题解:CF1016E Rest In The Shades

题意 平面上有一个点光源 s s s 并以每秒 1 1 1 单位长度的速度从点 ( a , s y ) (a,sy) (a,sy) 移动到点 ( b , s y ) (b,sy) (b,sy)&#xff0c;其中 s y < 0 sy<0 sy<0&#xff1b;在 x x x 轴正方向上有 n n n 不相交、不接触的挡板&#xff0c;第 i i i …

【Spring Boot】响应式编程

响应式编程 1.WebFlux2.比较 MVC 和 WebFlux2.1 工作方式2.2 Spring MVC 与 Spring WebFlux 的区别2.3 使用 WebFlux 的好处 3.Mono 和 Flux3.1 Mono 和 Flux 是什么3.2 Mono 和 Flux 的区别 4.开发 WebFlux 的流程4.1 注解式开发流程4.2 响应式开发流程 5.用注解式开发实现 He…

基于开源ATmega8 无感BLDC程序移植到ATmega328PB

基于开源ATmega8 无感BLDC程序移植到ATmega328PB &#x1f516;基于Atmel Studio 7.0开发环境。&#x1f955;开源原项目资源地址&#xff1a;https://svn.mikrokopter.de/websvn/listing.php?repnameBL-Ctrl&path%2F&&#x1f4cd;原理图和PCB资源 BL-Ctrl v2.0 in E…

Win32 API

个人主页&#xff1a;星纭-CSDN博客 系列文章专栏 : C语言 踏上取经路&#xff0c;比抵达灵山更重要&#xff01;一起努力一起进步&#xff01; 一.Win32 API 1.Win32 API介绍 Windows这个多作业系统除了协调应⽤程序的执⾏、分配内存、管理资源之外&#xff0c;它同时也是…

Redis内存回收-内存淘汰策略

LFU的访问次数之所以叫做逻辑访问次数&#xff0c;是因为并不是每次key被访问都计数&#xff0c;而是通过运算&#xff1a; 生成0~1之间的随机数R计算 (旧次数 * lfu_log_factor 1)&#xff0c;记录为P如果 R < P &#xff0c;则计数器 1&#xff0c;且最大不超过255访问…

9.任务调度

一、开启任务调度器 1.函数 vTaskStartScheduler() 函数 vTaskStartScheduler()用于启动任务调度器&#xff0c;任务调度器启动后&#xff0c;FreeRTOS 便会开始 进行任务调度&#xff0c;除非调用函数 xTaskEndScheduler()停止任务调度器&#xff0c;否则不会再返回。函数 vTa…

Centos修改系統語言

一、使用命令行修系统语言 1、显示系统当前语言环 [rootkvm-suma ~]# localectl System Locale: LANGen_US.utf8 VC Keymap: cn X11 Layout: cn 2、查看系统支持字符集 [rootkvm-suma ~]# locale -a 2、设置系统语言环境 [rootkvm-suma ~]# localectl set-locale LANGz…

【GESP试卷】2024年03月Scratch四级试卷

2024年GESP03月认证Scratch四级试卷 分数&#xff1a;100 题数&#xff1a;27 一、单选题(共15题&#xff0c;每题2分&#xff0c;共30分) 010203040506070809101112131415CDBBACBCDCDADBA 1、小杨的父母最近刚刚给他买了一块华为手表&#xff0c;他说手表上跑的是鸿蒙&…

【雷丰阳-谷粒商城 】【分布式基础篇-全栈开发篇】【00】补充

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式基础篇-全栈开发篇】【00】补充 插件IDEAVsCode MavenvagrantDocker解决MySQL连接慢问题启动&#xff08;自动&#xff09;Docker注意切换到root用户远程访问MySQL MyBatisPlus代码地址参考 插件 IDEA Mybati…