FreeRTOS任务相关API函数

1. FreeRTOS任务相关API函数介绍

函数描述
uxTaskPriorityGet()获取任务优先级
vTaskPrioritySet()设置任务优先级
uxTaskGetNumberOfTasks()获取系统中任务的数量
uxTaskGetSystemState()获取所有任务状态信息
vTaskGetInfo()获取指定单个的任务信息
xTaskGetCurrentTaskHandle()获取当前任务的任务句柄
xTaskGetHandle()根据任务名获取该任务的任务句柄
uxTaskGetStackHighWaterMark()获取任务的任务栈历史剩余最小值
eTaskGetState()获取任务状态
vTaskList()以“表格”形式获取所有任务的信息
vTaskGetRunTimeStats()获取任务的运行时间

学习资料可参考手册《FreeRTOS开发指南》第11章 —— “FreeRTOS其他任务API函数”

1.1 函数介绍

UBaseType_t  uxTaskPriorityGet(  const TaskHandle_t xTask  )

此函数用于获取指定任务的任务优先级,使用该函数需将宏 INCLUDE_uxTaskPriorityGet 置 1

形参描述
xTask要查找的任务句柄,NULL代表任务自身
返回值描述
整数任务优先级数值
void vTaskPrioritySet( TaskHandle_t xTask , UBaseType_t uxNewPriority )

此函数用于改变某个任务的任务优先级,使用该函数需将宏 INCLUDE_vTaskPrioritySet 为 1

形参描述
xTask任务句柄,NULL代表任务自身
uxNewPriority需要设置的任务优先级
UBaseType_t uxTaskGetNumberOfTasks( void )

此函数用于获取系统中任务的任务数量

返回值描述
整型系统中任务的数量
UBaseType_t  uxTaskGetSystemState(   TaskStatus_t * const pxTaskStatusArray,
                                      				const UBaseType_t uxArraySize,
                                      				configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime  )

此函数用于获取系统中所有任务的任务状态信息,使用该函数需将宏 configUSE_TRACE_FACILITY 置 1

形参描述
xTaskStatusArray指向 TaskStatus_t 结构体数组首地址
uxArraySize接收信息的数组大小
pulTotalRunTime系统总运行时间,为 NULL 则省略总运行时间值
返回值描述
整型获取信息的任务数量

TaskStatus_t 任务状态信息结构体介绍:

UBaseType_t  uxTaskGetSystemState(   TaskStatus_t * const pxTaskStatusArray,
                                      				const UBaseType_t uxArraySize,
                                      				configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime  )

typedef struct xTASK_STATUS
{
    TaskHandle_t 					xHandle;                       		/* 任务句柄 */ 
    const char *		 			pcTaskName;                     	/* 任务名 */ 
    UBaseType_t						xTaskNumber;                     	/* 任务编号(任务创建次序) */ 
    eTaskState e					CurrentState;                    	/* 任务状态 */ 
    UBaseType_t 					uxCurrentPriority;               	/* 任务优先级 */ 
    UBaseType_t 					uxBasePriority;                 	/* 任务原始优先级 */ 
    configRUN_TIME_COUNTER_TYPE 	ulRunTimeCounter; 					/* 任务运行时间*/
    StackType_t * 					pxStackBase;                    	/* 任务栈基地址 */ 
    configSTACK_DEPTH_TYPE 			usStackHighWaterMark;  				/* 任务栈历史剩余最小值 */ 
} TaskStatus_t;

为什么有原始优先级?因为互斥信号量这些是有一个优先级继承的问题,优先级是会改变的,所以这里有个变量就是保存原始的一个优先级,就这么一个作用。

void vTaskGetInfo( 	TaskHandle_t 	xTask,
					TaskStatus_t * 	pxTaskStatus,
					BaseType_t 		xGetFreeStackSpace,
					eTaskState 		eState  )

此函数用于获取指定的单个任务的状态信息,使用该函数需将宏 configUSE_TRACE_FACILITY 置 1

形参描述
xTask指定获取信息的任务的句柄
pxTaskStatus接收任务信息的变量
xGetFreeStackSpace任务栈历史剩余最小值,当为“pdFALSE” 则跳过这个步骤,当为“pdTRUE”则检查历史剩余最小堆栈
eState任务状态,可直接赋值,如想获取代入“eInvalid”

eTaskState 结构体:

typedef enum
{   
	eRunning = 0,	/* 运行态 */ 
	eReady			/* 就绪态 */ 
	eBlocked, 		/* 阻塞态 */ 
	eSuspended, 	/* 挂起态 */ 
	eDeleted, 		/* 任务被删除 */ 
	eInvalid		/* 无效 */ 
} eTaskState;

因为通过这个函数来获取任务状态的时候,它是要费时间的,所以我们一般可以直接赋值。比如说 task2 正在运行,那就给它一个运行态,eRunning 写进来;如果说无所谓,你浪费点时间就浪费点时间,那么就带入这个 eInvalid 无效态,把这个参数给些进来,那么此时呢它就会帮我们获取它此时的这个任务的任务状态。

TaskHandle_t    xTaskGetCurrentTaskHandle( void ) 

此函数用于获取当前任务的任务句柄, 使用该函数需将宏 INCLUDE_xTaskGetCurrentTaskHandle 置 1

返回值描述
TaskHandle_t当前任务的任务句柄
TaskHandle_t xTaskGetHandle(const char * pcNameToQuery); 

此函数用于通过任务名获取任务句柄 , 使用该函数需将宏 INCLUDE_xTaskGetHandle 置 1

形参描述
pcNameToQuery任务名
返回值描述
TaskHandle任务句柄
UBaseType_t    uxTaskGetStackHighWaterMark( TaskHandle_t  xTask )

此函数用于获取指定任务的任务栈历史最小剩余堆栈;那这个跟设置堆栈大小还是非常有密切联系的。如果这个值非常小,就代表堆栈可能有溢出风险,所以这个历史最小值尽量大一点,可以通过这个历史最小值来设置任务堆栈的大小。(正常大概大一倍左右)

比如说剩余的历史最小堆栈值很小,就代表要溢出了,此时可以加大一点任务堆栈;如果剩余很大,代表很多都没用到,所以可以适当减小一点。

使用该函数需将宏 INCLUDE_uxTaskGetStackHighWaterMark 置 1

形参描述
xTask任务句柄
返回值描述
UBaseType_t任务栈的历史剩余最小值
eTaskState    eTaskGetState(TaskHandle_t xTask)

此函数用于查询某个任务的运行状态(就绪态、阻塞态、挂起态等等),使用此函数需将宏 INCLUDE_eTaskGetState 置1

形参描述
xTask待获取状态任务的任务句柄
返回值描述
eTaskState任务状态
typedef enum
{   
	eRunning = 0,	/* 运行态 */ 
	eReady			/* 就绪态 */ 
	eBlocked, 		/* 阻塞态 */ 
	eSuspended, 	/* 挂起态 */ 
	eDeleted, 		/* 任务被删除 */ 
	eInvalid		/* 无效 */ 
} eTaskState;
void   vTaskList(char * pcWriteBuffer)

此函数用于以“表格”的形式获取系统中任务的信息 ;

使用此函数需将宏 configUSE_TRACE_FACILITY 和 configUSE_STATS_FORMATTING_FUNCTIONS 置 1

形参描述
pcWriteBuffer接收任务信息的缓存指针

Name : 创建任务的时候给任务分配的名字。
State : 任务的壮态信息, B 是阻塞态, R 是就绪态, S 是挂起态, D 是删除态,X 代表运行态。
Priority : 任务优先级。
Stack : 任务堆栈的“高水位线”,就是堆栈历史最小剩余大小。
Num : 任务编号,这个编号是唯一的,当多个任务使用同一个任务名的时候可以通过此编号来做区分。

  • 表格如下所示:
    在这里插入图片描述

2. 任务状态查询API函数实验

实验目的:学习 FreeRTOS 任务状态与信息的查询API函数
实验设计:将设计三个任务:start_task、task1、task2

三个任务的功能如下:
start_task:用来创建task1和task2任务
task1:LED0每500ms闪烁一次,提示程序正在运行
task2:用于展示任务状态信息查询相关 API 函数的使用

2.1 任务函数实现

task2

char task_buff[500];
/* 任务二,实现任务状态查询API函数使用 */
void task2( void * pvParameters )
{
    UBaseType_t priority_num = 0;
    UBaseType_t task_num = 0;
    UBaseType_t task_num2 = 0;
    TaskStatus_t * status_array = 0;
    TaskStatus_t * status_array2 = 0;
    TaskHandle_t task_handle = 0;
    UBaseType_t task_stack_min = 0;
    eTaskState state = 0;
    
    uint8_t i = 0;
    
    vTaskPrioritySet( task2_handler,4 );								/* 设置任务优先级 */
    priority_num = uxTaskPriorityGet( NULL );							/* 获取任务优先级 */
    printf("task2任务优先级为%ld\r\n",priority_num);
    
    task_num = uxTaskGetNumberOfTasks();								/* 获取系统中任务的数量 */
    printf("任务数量:%ld\r\n",task_num);
    
    status_array = mymalloc(SRAMIN,(sizeof(TaskStatus_t) * task_num));	/* 申请位置:SRAM */
    task_num2 = uxTaskGetSystemState( status_array,task_num,NULL);		/* 获取所有任务状态信息 */
    printf("任务名\t\t任务优先级\t任务编号\r\n");
    for(i = 0; i < task_num2; i++)
    {
        printf("%s\t\t%ld\t%ld\r\n",
                status_array[i].pcTaskName,
                status_array[i].uxCurrentPriority,
                status_array[i].xTaskNumber);
    }
    
    status_array2 = mymalloc(SRAMIN,sizeof(TaskStatus_t));
    vTaskGetInfo( task2_handler,status_array2,pdTRUE,eInvalid);			/* 获取指定单个的任务信息 */
    printf("任务名:%s\r\n",status_array2->pcTaskName);
    printf("任务优先级:%ld\r\n",status_array2->uxCurrentPriority);
    printf("任务编号:%ld\r\n",status_array2->xTaskNumber);
    printf("任务状态:%d\r\n",status_array2->eCurrentState);
    
    task_handle = xTaskGetHandle( "task1" );							/* 根据任务名获取该任务的任务句柄 */
    printf("任务句柄:%#x\r\n",(int)task_handle);
    printf("task1的任务句柄:%#x\r\n",(int)task1_handler);
    
    state = eTaskGetState( task2_handler );								/* 获取任务状态 */
    printf("当前task2的任务状态为:%d\r\n",state);
    
    vTaskList( task_buff );												/* 以“表格”形式获取所有任务的信息 */
    printf("%s\r\n",task_buff);
    while(1)
    {
//        task_stack_min = uxTaskGetStackHighWaterMark( task2_handler );
//        printf("task2历史剩余最小堆栈为%ld\r\n",task_stack_min);
        vTaskDelay(1000);
    }
}

Tmr_Svc(软件定时器)是阻塞态,start_task(开始任务)是删除态,task2 是运行态,task1 和 IDLE(空闲任务)是就绪态。

3. 时间统计API函数介绍

void    vTaskGetRunTimeStats( char * pcWriteBuffer ) 

此函数用于统计任务的运行时间信息,使用此函数需将宏 configGENERATE_RUN_TIME_STAT、configUSE_STATS_FORMATTING_FUNCTIONS 置1

形参描述
pcWriteBuffer接收任务运行时间信息的缓存指针

Task:任务名称 Abs
Time:任务实际运行的总时间(绝对时间)。单位不是秒,而是看定时器的中断频率,然后再乘以这个数值才是真正的时间。
%Time:占总处理时间的百分比

  • 表格如下所示:
    在这里插入图片描述
    你的空闲时间越长,代表你的应用任务压力就越小,因为我们说过空闲任务它是 cpu 空闲的时候才会去执行的,如果 cpu 有很多空闲时间,就代表 cpu 压力不大;如果 cpu 这个空闲任务时间占比很小,就代表有些任务可能占用太大的时间。像这里,GenQ 也占了 24%,那我们看到这个占这么大,那我们是不是可以把它拆分一下,拆分小一点,这个就是在调试的时候用的比较多,在正式的产品,比如我们调试好了,我们就把这些功能给删掉就行了(需要)。

所以这个功能主要是在用于调试阶段,我们调试产品的时候,用了 FreeRTOS 的时候,我们这时候可以用这个函数来统计一下每个任务它们各自的一个时间占比。它就这么一个作用。

3.1 时间统计API函数使用流程

  1. 将宏 configGENERATE_RUN_TIME_STATS 置1
  2. 将宏 configUSE_STATS_FORMATTING_FUNCTIONS 置1
  3. 当将此宏 configGENERATE_RUN_TIME_STAT 置1之后,还需要实现2个宏定义:
    • portCONFIGURE_TIMER_FOR_RUNTIME_STATE() :用于初始化用于配置任务运行时间统计的时基定时器;(开启任务调度器函数中调用,自己实现)
    • portGET_RUN_TIME_COUNTER_VALUE():用于获取该功能时基硬件定时器计数的计数值,用来返回当前“时间”。

滴答定时器是来给系统提供时钟节拍的,那这个时基定时器是用来统计任务运行时间的,这两个是有区别的。

  • 注意:这个时基定时器的计时精度(分辨率)需高于系统时钟节拍精度的10至100倍!时基越快,统计的数据就越准确。那系统时钟节拍是 1ms 中断一次,那么高它 10~100 倍,也就是说是 0.1ms 到 0.01ms,也就是 10μs 到 100μs 这么一个范围,这个时基定时器的频率就在这么一个范围。那这个呢是在官网上都是可以找到它这些描述的。
  • 所以我们一会用 100 倍来统计,也就我们现在的系统时钟节拍是 1ms,那 100 倍就 0.01 ms,也就是 10μs,我们一会把时基定时器配置成 10μs 中断一次。

4. 任务时间统计API函数实验

实验目的:学习 FreeRTOS 任务运行时间统计相关 API 函数的使用
实验设计:将设计三个任务:start_task、task1、task2

三个任务的功能如下:
start_task:用来创建task1和task2任务
task1:LED0每500ms闪烁一次,提示程序正在运行
task2:用于展示任务运行时间统计相关API函数的使用

4.1 宏置 1

  1. 将宏 configGENERATE_RUN_TIME_STATS 置1
  2. 将宏 configUSE_STATS_FORMATTING_FUNCTIONS 置1

4.2 宏定义

btim.h

void ConfigureTimeForRunTimeStats(void);		/* 时基定时器初始化函数声明 */

btim.c

时基定时器初始化:

TIM_HandleTypeDef g_timx_handle;         						/* 定时器参数句柄 */

/**
 * @brief       基本定时器TIMX定时中断初始化函数
 * @note
 *              基本定时器的时钟来自APB1,当PPRE1 ≥ 2分频的时候
 *              基本定时器的时钟为APB1时钟的2倍, 而APB1为45M, 所以定时器时钟 = 90Mhz
 *              定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.
 *              Ft=定时器工作频率,单位:Mhz
 *
 * @param       arr : 自动重装值。
 * @param       psc : 时钟预分频数
 * @retval      无
 */
void btim_timx_int_init(uint16_t arr, uint16_t psc)
{
    g_timx_handle.Instance = BTIM_TIMX_INT;                     /* 定时器x */
    g_timx_handle.Init.Prescaler = psc;                         /* 分频 */
    g_timx_handle.Init.CounterMode = TIM_COUNTERMODE_UP;        /* 递增计数模式 */
    g_timx_handle.Init.Period = arr;                            /* 自动装载值 */
    HAL_TIM_Base_Init(&g_timx_handle);
    
    HAL_TIM_Base_Start_IT(&g_timx_handle);                      /* 使能定时器x和定时器更新中断 */
}


uint32_t FreeRTOSRunTimeTicks;									/* 定义计数值 */
/* 时基定时器的初始化 */
void ConfigureTimeForRunTimeStats(void)
{
    btim_timx_int_init(10-1, 90-1);  							/* 100倍的系统时钟节拍 */
    FreeRTOSRunTimeTicks = 0;									/* 初始化计数值,把它给清零 */
}

我们现在要设置 10μs,大家可以算一下,我们的基本定时器用了 TIM6 ,它的时钟是 90M(我们这里是以 429 为例,429 主频是 180M,那它是 TIM6,是它的一半,也就是 90M),所以我们这个分频值可以设置 90,90M 后面有 6 个 0,除以 90,等于 1M,1M 是不是 1μs,那我们现在要 10μs,就把这个重装载值设置成 10 就可以了,那这样我们就设置好了。

然后就在中断里面 FreeRTOSRunTimeTicks 要进行自加了,我们每进来一次中断服务函数,我去进行一次加一。

/**
 * @brief       定时器底层驱动,开启时钟,设置中断优先级。此函数会被HAL_TIM_Base_Init()函数调用
 * @param       无
 * @retval      无
 */
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == BTIM_TIMX_INT)
    {
        BTIM_TIMX_INT_CLK_ENABLE();                     		/* 使能TIMx时钟 */
        HAL_NVIC_SetPriority(BTIM_TIMX_INT_IRQn, 6, 0); 		/* 抢占6,子优先级0 */
        HAL_NVIC_EnableIRQ(BTIM_TIMX_INT_IRQn);         		/* 开启ITMx中断 */
    }
}
/**
 * @brief      	基本定时器TIMX中断服务函数
 * @param       无
 * @retval      无
 */
void BTIM_TIMX_INT_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&g_timx_handle);  						/* 定时器回调函数 */
}

/**
 * @brief       回调函数,定时器中断服务函数调用
 * @param       无
 * @retval      无
 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == BTIM_TIMX_INT)
    {
        FreeRTOSRunTimeTicks++;									/* 计数值自加 */
    }
}

我们这里初始化它是 10μs 中断一次,也就是说 10μs 会进来一次中断服务函数,把 FreeRTOSRunTimeTicks 进行一次加一。那这个就是计数值。

4.3 任务函数实现

task2

char task_buff[500];
/* 任务二,实现任务运行时间统计API函数的使用 */
void task2( void * pvParameters )
{
    uint8_t key = 0;
    while(1)
    {
        key = key_scan(0);
        if(key == KEY0_PRES)
        {
            vTaskGetRunTimeStats(task_buff);
            printf("%s\r\n",task_buff);
        }
        vTaskDelay(10);
    }
}

那这样其实就可以了。

task1 它运行时间是非常非常短的,而 task2 因为调用了 vTaskGetRunTimeStats 这个函数,所以它所用的时间就比较长了,相对于 task1 来说,所以我们在调试阶段才会去用到这个函数去检查一下我们的任务时间的一个情况。在一般的一个正式产品的话,我们就会把它给删掉了,就不会用到它了,因为它占据的时间是比较长的。

5. 总结

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解决1130-Host‘ ‘is not allowed to connect to this MySQL server,实现远程连接本地数据库

参考:https://blog.csdn.net/CoCo629vanilla/article/details/129008644 在使用Navicat远程连接本地数据库时&#xff0c;遇到了这样一个问题&#xff0c; 我使用 本地主机的地址&#xff0c;连接本地的数据库&#xff0c;报错host ‘’ is not allowed to connect to this my…

转座子插入序列分析2-自制分析流程

我们先观察一下测序的结果&#xff0c;是否有一些什么规律&#xff0c;因为使用的靶向富集法的测序&#xff0c;我们使用了特殊序列将插入了转座子的部分钓了出来&#xff0c;然后进行的测序&#xff0c;所以理论上富集到的所有序列都应该存在一段与我们钓鱼序列互补的“靶点序…

Redis实战:缓存穿透及其解决思路 实战演示

&#x1f389;&#x1f389;欢迎光临&#xff0c;终于等到你啦&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;持续更新的专栏Redis实战与进阶 本专栏讲解Redis从原理到实践 …

YOLOv5改进 | 图像去雾 | 利用图像去雾网络AOD-PONO-Net网络增改进图像物体检测(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是利用AODNet图像去雾网络结合PONO机制实现二次增强&#xff0c;我将该网络结合YOLOv5针对图像进行去雾检测&#xff08;也适用于一些模糊场景&#xff0c;图片不清晰的检测&#xff09;&#xff0c;同时本文的内容不影响其它的模块改进…

【嵌入式硬件】步进电机

1.步进电机简介 1.1步进电机基本原理 步进电机的英文是stepping motor。step的中文意思是行走、迈步。所以仅从字面上我们就可以得知,步进电机就是一步一步移动的电动机。说的官方一点儿,步进电机是一种将电脉冲信号转换成相应角位移或者线位移的电动机(直线电机)。下图为…

交通事故档案管理系统|基于JSP技术+ Mysql+Java+Tomcat的交通事故档案管理系统设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java&#xff0c;ssm&#xff0c;springboot的平台设计与实现项目系统开发资源&#xff08;可…

AI程序员的崛起还是人类程序员的消亡?

最近有个对互联网行业影响极大的爆炸新闻&#xff1a; 我们这个圈子里有了个新玩家——AI程序员。 没错&#xff0c;就是那种用人工智能技术驱动的编程助手。你可能听说过Devin&#xff0c;这家伙不是一般的程序员&#xff0c;它能迅速学习新技术&#xff0c;还能在编码、找bug…

【.net/.net core】后台生成echarts图片解决方案及.net core html转word方法

工具环境下载&#xff1a; EChartsConvert&#xff1a;https://gitee.com/saintlee/echartsconvert EChartsConvert为生成echarts图片的服务端&#xff0c;用于接收参数和生成echarts图表图片BASE64编码 PhantomJS:Download PhantomJS PhantomJS用来发布EChartsConvert服务…

媒资管理模块之文件预览

文件预览 图片和视频上传成功后&#xff0c;可以通过预览按钮查看文件内容(如图片和MP4格式视频),对于浏览器不支持查看的文件提示错误信息(如avi格式视频) 接口定义 根据上传文件的ID获取文件对应的可访问URL,对于图片或MP4格式的视频可通过浏览器直接预览,对于其他文件如.a…

WEB 表单练习题

任务如图&#xff1a; <html><head><meta charest"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head><body><table width"…

Flink GateWay、HiveServer2 和 hive on spark

Flink SQL Gateway简介 从官网的资料可以知道Flink SQL Gateway是一个服务&#xff0c;这个服务支持多个客户端并发的从远程提交任务。Flink SQL Gateway使任务的提交、元数据的查询、在线数据分析变得更简单。 Flink SQL Gateway的架构如下图&#xff0c;它由插件化的Endpoi…

将本地的项目上传到gitee,

场景&#xff1a;在本地有一个项目&#xff0c;想要把这个项目上传到gitee&#xff0c;且在gitee中已经创建好仓库 依次执行下图中的命令&#xff1a;

WebXR实践——利用aframe框架浏览器展示全景图片

一、效果 话不多说&#xff0c;先上效果 二、代码 index.html <!DOCTYPE html> <html><head><meta charset"utf-8"><title>360&deg; Image</title><meta name"description" content"360&deg; Imag…

Head First Design Patterns -适配器模式与外观模式

适配器模式 什么是适配器模式 适配器模式&#xff0c;将一个类的接口转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作。 类图 代码 利用Enumeration来适配Iterator&#xff0c;外部只需要调用这个适配器&#xff0c;即可以像调用Iterator那样&#xff0c;…

[音视频学习笔记]六、自制音视频播放器Part1 -新版本ffmpeg,Qt +VS2022,都什么年代了还在写传统播放器?

前言 参考了雷神的自制播放器项目&#xff0c;100行代码实现最简单的基于FFMPEGSDL的视频播放器&#xff08;SDL1.x&#xff09; 不过老版本的代码参考意义不大了&#xff0c;我现在准备使用Qt VS2022 FFmpeg59重写这部分代码&#xff0c;具体的代码仓库如下&#xff1a; …

市场复盘总结 20240321

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票 10%的时候可以操作&#xff0c; 90%的时间适合空仓等待 二进三&#xff1a; 进级率中 23% 最常用的…

基于python+vue银行柜台管理系统flask-django-php-nodejs

课题主要采用python开发语言、django框架和MySQL数据库开发技术以及基于Eclipse的编辑器。系统主要包括通知信息、用户信息、银行信息、卡号账户、存款信息管理、取款信息、转账信息、贷款信息、贷款申请、贷款发放、账单信息、还款信息等功能&#xff0c;从而实现智能化的管理…

中文编程入门(Lua5.4.6中文版)第十一章 Lua 模块与包 参考星争际霸游戏

在遥远的星争际霸世界中&#xff0c;代码模块就如同星际基地中的高科技仓库&#xff0c;储存着各类经过封装优化的战术指令和战略资源。自Lua 5.1版本起&#xff0c;星际编程者们引入了标准化的模块管理系统&#xff0c;使得不同战舰之间能够共享和调用核心战斗算法&#xff0c…

python智慧农业小程序flask-django-php-nodejs

当今社会已经步入了科学技术进步和经济社会快速发展的新时期&#xff0c;国际信息和学术交流也不断加强&#xff0c;计算机技术对经济社会发展和人民生活改善的影响也日益突出&#xff0c;人类的生存和思考方式也产生了变化。传统智慧农业采取了人工的管理方法&#xff0c;但这…

Golang Gorm 自动分批查询

场景&#xff1a; 目标查询全量数据&#xff0c;但需要每次Limit分批查询&#xff0c;保护数据库 文档&#xff1a; https://gorm.io/zh_CN/docs/advanced_query.html // Param: // dest 目标地址 // batchSize 大小 // fc 处理函数func (db *DB) FindInBatc…