利用STM32CubeMX和Keil模拟器,3天入门FreeRTOS(4.2) —— 中断函数中使用队列

news2024/11/15 12:36:58

前言

(1)FreeRTOS是我一天过完的,由此回忆并且记录一下。个人认为,如果只是入门,利用STM32CubeMX是一个非常好的选择。学习完本系列课程之后,再去学习网上的一些其他课程也许会简单很多。
(2)本系列课程是使用的keil软件仿真平台,所以对于没有开发板的同学也可也进行学习。
(3)叠甲,再次强调,本系列课程仅仅用于入门。学习完之后建议还要再去寻找其他课程加深理解。
(4)本系列博客对应代码仓库:gitee仓库

前期准备

(1)首先将上一篇博客的代码复制一遍下来。

在这里插入图片描述

(2)将两个按键设置为双边沿触发,默认弱下拉。

在这里插入图片描述

(3)打开使能两个引脚中断

在这里插入图片描述

(4)因为我们使用的是外部中断0和外部中断1,所以这里需要使用HAL_GPIO_EXTI_Callback()进行重定义。

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	switch (GPIO_Pin)
	{
		case GPIO_PIN_0:
		{		
			break;
		}
		case GPIO_PIN_1:
		{
			break;
		}
	}
}
/* USER CODE END Application */

实战

补充细节

(1)我们按Ctrl+F搜索Header_StartCubemxTask ,然后直接进行如下函数补充即可。

/* USER CODE END Header_StartCubemxTask */
void StartCubemxTask(void *argument)
{
  /* USER CODE BEGIN StartCubemxTask */
	char *CubemxTaskPrintf = (char *)argument;
  /* Infinite loop */
  for(;;);
  /* USER CODE END StartCubemxTask */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
int fputc(int ch, FILE *f)
{
	unsigned char temp[1]={ch};
	HAL_UART_Transmit(&huart1,temp,1,0xffff);
	return ch;
}
void StartKeilTask(void *argument)
{
	while(1);
}

/* --- 写实验 ---*/
#define Test_xQueueSendToFrontFromISR   1
#define Test_xQueueSendToBackFromISR    0
#define Test_xQueueOverwriteFromISR     0
/* --- 读实验 ---*/
#define Test_xQueueReceiveFromISR       0
#define Test_xQueuePeekFromISR          1
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	static uint16_t Buf = 0;
	BaseType_t status;
	switch (GPIO_Pin)
	{
		case GPIO_PIN_0:
		{		
			if (HAL_GPIO_ReadPin(Key_0_GPIO_Port, Key_0_Pin) == GPIO_PIN_SET)
			{
				Buf++;
#if Test_xQueueSendToFrontFromISR
				// 写实验1:测试头插xQueueSendToFrontFromISR()函数
				status = xQueueSendToFrontFromISR(KeilQueueHandle, &Buf, 0);
				if (status == pdTRUE)
				{
					printf("xQueueSendToFrontFromISR writes data successfully : %d\r\n", Buf);
				}
				else
				{
					printf("xQueueSendToFrontFromISR failed to write data\r\n");
				}
#elif Test_xQueueSendToBackFromISR
				// 写实验2:测试尾插xQueueSendToBackFromISR()函数
				status = xQueueSendToBackFromISR(KeilQueueHandle, &Buf, 0);
				if (status == pdTRUE)
				{
					printf("xQueueSendToBackFromISR writes data successfully : %d\r\n", Buf);
				}
				else
				{
					printf("xQueueSendToBackFromISR failed to write data\r\n");
				}
#elif Test_xQueueOverwriteFromISR
				// 写实验3:测试xQueueOverwrite()函数,这个只能用于队列大小为1的情况。不为1的队列使用这个,程序会崩溃
				xQueueOverwriteFromISR(KeilQueueHandle, &Buf);
				printf("xQueueOverwriteFromISR writes data successfully : %d\r\n", Buf);
#endif
				//查询队列中存储的消息数
				status = uxQueueMessagesWaitingFromISR(KeilQueueHandle);
				printf("The number of data stored in the queue : %d\r\n",status);
			}
			break;
		}
		case GPIO_PIN_1:
		{
			// 按下K1读取数据
			if (HAL_GPIO_ReadPin(Key_1_GPIO_Port, Key_1_Pin) == GPIO_PIN_SET )
			{
#if Test_xQueueReceiveFromISR
				// 读实验1:从队列头部读取消息,并删除消息
				status = xQueueReceiveFromISR(KeilQueueHandle, &Buf, 0);
				if (status == pdTRUE)
				{
					printf("xQueueReceiveFromISR data read successfully :%d\r\n", Buf);
				}
				else
				{
					printf("xQueueReceiveFromISR data read failed\r\n");
				}
#elif Test_xQueuePeekFromISR
				// 读实验2:从队列头部读取消息,但是不删除消息
				status = xQueuePeekFromISR(KeilQueueHandle, &Buf);
				if (status == pdTRUE)
				{
					printf("xQueuePeekFromISR data read successfully :%d\r\n", Buf);
				}
				else
				{
					printf("xQueuePeekFromISR data read failed\r\n");
				}
#endif
				//查询队列中的可用空间数,这个没有提供中断适配函数
//				status = uxQueueSpacesAvailable(KeilQueueHandle);
//				printf("There is space left in the queue : %d\r\n",status);
			}
			break;
		}
	}
}
/* USER CODE END Application */


测试结果

(1)测试结果与前文一致。

理论

中断和任务关系

(1)不管中断的优先级是多少,中断的优先级永远高任何任务的优先级。即在执行的过程中,中断来了就开始执行中断服务程序,即使是拥有最小优先级的中断也会打断拥有最高优先级的任务
(2)中断是由硬件层面决定的,而任务只是一个软件的概念。RTOS本质上就是滴答定时器中断提供时间基准,之后判断是否有任务需要进行调度。如果需要任务调度,那么就会触发PendSV_Handler中断,进行任务调度。

滴答定时器中断简单介绍

(1)在FreeRTOS中,滴答定时器中断函数进行了一次宏定义。个人感觉应该是为了做其他内核的兼容,加上宏定义之后,可移植性增强。
(2)vPortRaiseBASEPRI();这个函数就是进行关中断,因为滴答定时器在增加时基的时候,可能会收到其他中断影响而导致增加时基出现错误。为了防止出现这样的情况,因此需要调用vPortRaiseBASEPRI();将这些中断进行屏蔽。程序执行完成之后,调用vPortClearBASEPRIFromISR();解除中断屏蔽。而这段代码区域,称为临界区
(3)在临界区中,我们会增加RTOS的时基,同时判断是否需要进行上下文切换。如果需要进行上下文切换,那么就触发PendSV中断。

#define xPortSysTickHandler SysTick_Handler
void xPortSysTickHandler( void )
{
	/* SysTick运行在最低的中断优先级上,因此当这个中断执行时,
	所有中断都必须处于未屏蔽状态。
	因此,无需保存和恢复中断屏蔽值,因为其值已经是已知的。
	因此,vPortRaiseBASEPRI() 函数被用作替代 
	portSET_INTERRUPT_MASK_FROM_ISR() 函数,因为它速度略快。*/
	vPortRaiseBASEPRI();
	{
		/* 增加RTOS时钟 */
		if( xTaskIncrementTick() != pdFALSE )
		{
			/* 如果需要进行上下文切换,就触发PendSV中断 */
			portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
		}
	}
	/* 解除中断屏蔽 */
	vPortClearBASEPRIFromISR();
}

(4)使用临界区,很好的保护了滴答定时器中断程序不会被干扰。但是这样就会导致一个问题,当滴答定时器中断正在执行的时候,优先级更高的中断触发,就会需要等待滴答定时器中断执行完成才能够执行。执行流程如下图:

在这里插入图片描述

(5)可能有朋友就会问了,如果我的中断,就是要立刻执行,怎么办呢?首先,我先需要先确认一下,这个中断立刻执行的这个立刻到底是多长时间?
<1>从FreeRTOS的官网中我们可以知道,上下文切换时间为 84 个 CPU 周期。以STM32F103为例,当我们设置系统时钟为72MHZ的时候,一次上下文切换时间大概是1.2us。
<2>也就是说,除非你的中断的实时性要求苛刻到比1.2us还要高,否则这个临界区是可接受的。
<3>但是,因为有朋友肯定要说了,我实时性要求就是极端的变态,怎么办呢?很简单,你将ISR优先级设置比configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY高即可。(这个后面会细说)

PendSV中断简单介绍

(1)首先,我们需要知道为什么需要PendSV中断。我个人建议各位看看这篇博客,讲解的非常清晰,我在这里不进行赘述:PendSV功能,为什么需要PendSV
(2)如果不打算看上面这篇博客的,我就简单总结一下。因为我们知道,滴答定时器中断临界区会导致ISR的延迟处理,我们是否能够将任务切换分成两部分,一个是滴答定时器判断是否需要任务切换,一个是PendSV中断进行实际的任务切换。如果在判断过程中,来了ISR,那么我判断完成就可以马上进行ISR,然后再进行任务切换。那样就能够一定程度上提高ISR的响应速度。

在这里插入图片描述

什么时候不能使用ISR后缀的函数

(1)前面不是埋了一个坑麻,说如果ISR想要实时响应,能够打断滴答定时器的临界区如何处理。这个时候就需要请到一个宏了,在FreeRTOSConfig.h文件中,有configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 宏,负责定义FreeRTOS临界区可屏蔽的中断。例如现在这个宏设置为5,那么如果ISR的优先级在0-4之间,即使现在现在滴答定时器在临界区中执行程序,ISR也能够成功的打断滴答定时器,立即进入中断函数。执行流程如下图:

#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

(2)在上图我们看到,如果是FreeRTOS不可屏蔽中断不能使用以FromISR结尾的API函数。

在这里插入图片描述

为什么启动FreeRTOS后,必须是中断分组4

(1)在CM3CM4内核中的NVIC控制器可以规定5中中断分组,在学习STM32裸机教程的时候,我们会调用NVIC_PriorityGroupConfig()函数设置中断分组。或者是在STM32CubeMX中设置中断分组。

在这里插入图片描述
在这里插入图片描述

(2)但是,如果有细心的朋友会发现一个问题。在STM32CubeMX中无法设置成其他中断分组,只有中断分组4一个选项。这个是为什么呢?
因为FreeRTOS 的中断配置没有处理亚优先级这种情况,所以我们只能配置中断优先级分组为 4,直接就 16 个主优先级,使用起来也简单!

xHigherPriorityTaskWoken参数理解

(1)中断函数要求快速执行,因此,中断中执行的函数都是立即返回的,没有等待时间。那么,我们能够发现,原来的等待时间的参数变成的xHigherPriorityTaskWoken。我们将如何理解xHigherPriorityTaskWoken这个参数呢?
(2)还是回到上面关于中断和任务关系的介绍中,我们知道,滴答定时器是负责增加RTOS时基和任务切换判断,PendSV才是真正进行任务切换的中断函数。如果我们在ISR中执行类似队列操作,成功唤醒了任务优先级更高的Task2ISR结束之后,我们如果想要让Task2马上开始执行,就需要利用上xHigherPriorityTaskWoken这个参数。
(3)xHigherPriorityTaskWoken表示是否成功唤醒了一个更高优先级的任务Task2。如果成功唤醒了,那么xHigherPriorityTaskWoken会被标记为pdTRUE,那么我们就可以执行portYIELD_FROM_ISR()函数触发PendSV进行任务切换。
(4)ISR中的队列操作成功唤醒了一个更高优先级的Task2,利用xHigherPriorityTaskWoken参数的程序的执行流程和代码如下:

BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xQueueSendToFrontFromISR(KeilQueueHandle, &Buf, &xHigherPriorityTaskWoken);
if( xHigherPriorityTaskWoken )
{
	// 如果发送成功且唤醒了一个更高优先级的任务,则进行上下文切换
	portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

在这里插入图片描述

(5)但是,如果我们不利用xHigherPriorityTaskWoken这个参数,这个参数直接传入一个NULLISR中的队列操作成功唤醒了一个更高优先级的Task2,程序的执行流程和代码如下:

xQueueSendToFrontFromISR(KeilQueueHandle, &Buf, NULL);

在这里插入图片描述

API函数介绍

中断函数中向队列写数据

xQueueSendFromISR()和xQueueSendToBackFromISR()函数介绍

(1)xQueueSendFromISR()xQueueSendToFrontFromISR()作用一致。
(2)xQueueSendFromISR()xQueueSend()使用基本一样,除了第三个参数不同。具体细节看上面的xHigherPriorityTaskWoken参数理解
(3)使用场景不同,xQueueSend()是在任务中调用,而xQueueSendFromISR()是在FreeRTOS可屏蔽中断中调用。

/**
 * @brief  中断函数队列数据尾插
 *
 * @param  xQueue         队列的句柄
 *        -pvItemToQueue  指向待入队数据项的指针,每次只能插入一个数据
 *        -pxHigherPriorityTaskWoken 是否成功唤醒了一个更高优先级的任务,成功唤醒该值为pdTRUE,否则为pdFALSE
 *
 * @return  如果数据尾插成功,返回 pdTRUE,否则返回 errQUEUE_FULL。
 */
 BaseType_t xQueueSendToBackFromISR(QueueHandle_t xQueue,const void *pvItemToQueue,BaseType_t *pxHigherPriorityTaskWoken);

xQueueSendToFrontFromISR()函数介绍

(1)和上面使用方法一致,只不过一个是尾插一个是头插。

/**
 * @brief  中断函数队列数据头插
 *
 * @param  xQueue         队列的句柄
 *        -pvItemToQueue  指向待入队数据项的指针,每次只能插入一个数据
 *        -pxHigherPriorityTaskWoken 是否成功唤醒了一个更高优先级的任务,成功唤醒该值为pdTRUE,否则为pdFALSE
 *
 * @return  如果数据头插成功,返回 pdTRUE,否则返回 errQUEUE_FULL。
 */
 BaseType_t xQueueSendToFrontFromISR(QueueHandle_t xQueue,const void *pvItemToQueue,BaseType_t *pxHigherPriorityTaskWoken);

xQueueOverwriteFromISR()函数介绍

(1)覆盖队列中已经存在的数据,旨在用于长度为1的队列,队列要么为空,要么为满。

/**
 * @brief  覆盖队列中已经存在的数据(旨在用于长度为1的队列,队列要么为空,要么为满)
 *
 * @param  xQueue         队列的句柄
 *        -pvItemToQueue  指向待入队数据项的指针,每次只能插入一个数据
 *        -pxHigherPriorityTaskWoken 是否成功唤醒了一个更高优先级的任务,成功唤醒该值为pdTRUE,否则为pdFALSE
 *
 * @return  pdPASS是唯一可以返回的值
 */
 BaseType_t xQueueOverwriteFromISR(QueueHandle_t xQueue,const void *pvItemToQueue,BaseType_t *pxHigherPriorityTaskWoken);

中断函数中向队列读数据

xQueueReceiveFromISR()函数介绍

(1)中断函数中,从队列头部读取消息,并删除消息。

/**
 * @brief  中断函数中,从队列头部读取消息,并删除消息
 *
 * @param  xQueue         队列的句柄
 *        -pvBuffer       指向缓冲区的指针,接收到的项目将被复制到这个缓冲区,每次只能读取一个数据
 *        -pxHigherPriorityTaskWoken 是否成功唤醒了一个更高优先级的任务,成功唤醒该值为pdTRUE,否则为pdFALSE
 *
 * @return  如果从队列成功接收到项目,返回 pdTRUE,否则返回 pdFALSE。
 */
 BaseType_t xQueueReceiveFromISR(QueueHandle_t xQueue,void *pvBuffer,BaseType_t *pxHigherPriorityTaskWoken);

xQueuePeekFromISR()函数介绍

(1)中断函数中,从队列头部读取消息,但是不删除消息。

/**
 * @brief  中断函数中,从队列头部读取消息,但是不删除消息
 *
 * @param  xQueue         队列的句柄
 *        -pvBuffer       指向缓冲区的指针,接收到的项目将被复制到这个缓冲区,每次只能读取一个数据
 *
 * @return  如果从队列成功接收到项目,返回 pdTRUE,否则返回 pdFALSE。
 */
BaseType_t xQueuePeekFromISR(QueueHandle_t xQueue,void *pvBuffer);

中断函数中获取队列数据数量信息

uxQueueMessagesWaitingFromISR()函数介绍

(1)中断函数中,查询队列中存储的消息数。

/**
 * @brief  中断函数中,查询队列中存储的消息数
 *
 * @param  xQueue  队列的句柄
 *
 * @return  队列中可用的消息数
 */
UBaseType_t uxQueueMessagesWaitingFromISR( QueueHandle_t xQueue );

参考

(1)C站:freertos—中断管理(二)
(2)博客园:STM32 中断应用概览
(3)博客园:FreeRTOS 中断优先级配置(重要)
(4)知乎:FreeRTOS的中断管理
(5)韦东山freeRTOS快速入门:14_中断管理
(6)ST中文论坛:【经验分享】STM32之FreeRTOS:(一) 中断配置和临界段的使用
(7)Youtube:FreeRTOS on STM32 v2 - 11a Context switching
(8)C站:FreeRTOS记录(三、RTOS任务调度原理解析_Systick、PendSV、SVC)
(9)知乎:一文读懂->FreeRTOS任务调度(PendSV)
(10)微信公众号:RTOS内功修炼之FreeRTOS为何中断中只能用ISR结尾函数
(11)FreeRTOS官方文档:FreeRTOS 常见问题 -内存使用情况、启动时间&上下文切换时间
(12)C站:RTOS系列文章(2):PendSV功能,为什么需要PendSV

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

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

相关文章

Android HIDL概述与绑定模式的实现

一、前言 Android O(8.0) 版本之后&#xff0c;底层实现有了比较大的变化&#xff0c;最显著的一个方面就是 HIDL 机制的全面实施。本文对于理解系统源码中 Gnss、Usb、Camera 等模块的工作原理有极大帮助。 二、HIDL 设计目的 在 Android O(8.0) 之前系统的升级牵扯多方协作…

安全用电管理平台方案介绍——Acrelcloud-6000

安全用电管理平台是一个针对电力系统安全管理的平台&#xff0c;旨在提供对电力设备和用电行为进行监控、分析和管理的解决方案。该平台结合了物联网技术、数据分析和远程监控等技术手段&#xff0c;能够实时监测、分析和预警电力系统的安全状况&#xff0c;以便及时采取措施防…

再谈Android View绘制流程

一&#xff0c;先思考何时开始绘制 笔者在这里提醒读者&#xff0c;Android的View是UI的高级抽象&#xff0c;我们平时使用的XML文件也好&#xff0c;本质是设计模式中的一种策略模式&#xff0c;其View可以理解为一种底层UI显示的Request。各种VIew的排布&#xff0c;来自于开…

KernelGPT: LLM for Kernel Fuzzing

KernelGPT: Enhanced Kernel Fuzzing via Large Language Models 1.Introduction2.Background2.1.Kernel and Device Drivers2.2.Kernel Fuzzing2.2.1.Syzkaller规约2.2.2.规约生成 3.Approach3.1.Driver Detection3.2.Specification Generation3.2.1.Command Value3.2.2.Argum…

Vue2学习之第六、七章——vue-router与ElementUI组件库

路由 理解&#xff1a; 一个路由&#xff08;route&#xff09;就是一组映射关系&#xff08;key - value&#xff09;&#xff0c;多个路由需要路由器&#xff08;router&#xff09;进行管理。前端路由&#xff1a;key是路径&#xff0c;value是组件。 1.基本使用 安装vue-…

springboot快速写接口

1. 建proj形式 name会变成文件夹的名字&#xff0c;相当于你的项目名称 基础包 2. 基础依赖 3. 配置数据库 这里要打开mysql&#xff0c;并且创建数据库 方法&#xff1a; 安装好数据库&#xff0c;改好账号密码用navicat来建表和账号配置properties.yml文件即可 4.用res…

读AI3.0笔记07_游戏与推理

1. 始于游戏&#xff0c;不止于游戏 1.1. 开发超人类的游戏程序并不是人工智能的最终目的 1.2. AlphaGo所有的版本除了下围棋&#xff0c;其他什么也不会 1.2.1. 其最通用的版本AlphaGo Zero也一样 1.3. 这些游戏程序中没有一个能够将其在一款游戏中学到的知识迁移到其他游…

引领未来:云原生在产品、架构与商业模式中的创新与应用

文章目录 一、云原生产品创新二、云原生架构设计三、云原生商业模式变革《云原生落地 产品、架构与商业模式》适读人群编辑推荐内容简介目录 随着云计算技术的不断发展&#xff0c;云原生已经成为企业数字化转型的重要方向。接下来将从产品、架构和商业模式三个方面&#xff0c…

融合创新:传统企业数字化转型的业务、战略、操作和文化变革

引言 随着科技的不断演进&#xff0c;传统企业正站在数字化转型的前沿&#xff0c;这是一场前所未有的全面变革之旅。数字化已经超越了单纯的技术升级&#xff0c;成为企业保持竞争力、开创未来的必然选择。本文将引领您探讨&#xff0c;迈向数字化未来的传统企业全面数字化转…

回归预测 | Matlab基于SSA-SVR麻雀算法优化支持向量机的数据多输入单输出回归预测

回归预测 | Matlab基于SSA-SVR麻雀算法优化支持向量机的数据多输入单输出回归预测 目录 回归预测 | Matlab基于SSA-SVR麻雀算法优化支持向量机的数据多输入单输出回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab基于SSA-SVR麻雀算法优化支持向量机的数据…

解密:消息中间件的选择与使用:打造高效通信枢纽

目录 第一章&#xff1a;消息中间件介绍 1.1 什么是消息中间件 1.2 消息中间件的作用 1.3 消息中间件的分类 第二章&#xff1a;消息中间件的选择标准 2.1 性能 2.2 可靠性 2.3 可扩展性 2.4 易用性 2.5 社区支持 2.6 成本 第三章&#xff1a;常见的消息中间件对比…

docker 网络及如何资源(CPU/内存/磁盘)控制

安装Docker时&#xff0c;它会自动创建三个网络&#xff0c;bridge&#xff08;创建容器默认连接到此网络&#xff09;、 none 、host docker网络模式 Host 容器与宿主机共享网络namespace&#xff0c;即容器和宿主机使用同一个IP、端口范围&#xff08;容器与宿主机或其他使…

[ACM学习] 进制转换

进制的本质 本质是每一位的数位上的数字乘上这一位的权重 将任意进制转换为十进制 原来还很疑惑为什么从高位开始&#xff0c;原来从高位开始的&#xff0c;可以被滚动地乘很多遍。 将十进制转换为任意进制

VsCode提高生产力的插件推荐-持续更新中

别名路径跳转 自定义配置// 文件名别名跳转 "alias-skip.mappings": { "~/": "/src", "views": "/src/views", "assets": "/src/assets", "network": "/src/network", "comm…

CNN卷积理解

1 卷积的步骤 1 过滤器&#xff08;卷积核&#xff09;&#xff08;Filter或Kernel&#xff09;&#xff1a; 卷积层使用一组可学习的过滤器来扫描输入数据&#xff08;通常是图像&#xff09;。每个过滤器都是一个小的窗口&#xff0c;包含一些权重&#xff0c;这些权重通过训…

Supervised Contrastive 损失函数详解

有什么不对的及时指出&#xff0c;共同学习进步。(●’◡’●) 有监督对比学习将自监督批量对比方法扩展到完全监督设置&#xff0c;能够有效地利用标签信息。属于同一类的点簇在嵌入空间中被拉到一起&#xff0c;同时将来自不同类的样本簇推开。这种损失显示出对自然损坏很稳…

支付宝AES如何加密

继之前给大家介绍了 V3 加密解密的方法之后&#xff0c;今天给大家介绍下支付宝的 AES 加密。 注意&#xff1a;以下说明均在使用支付宝 SDK 集成的基础上&#xff0c;未使用支付宝 SDK 的小伙伴要使用的话老老实实从 AES 加密原理开始研究吧。 什么是AES密钥 AES 是一种高级加…

k8s实例

k8s实例举例 &#xff08;1&#xff09;Kubernetes 区域可采用 Kubeadm 方式进行安装。 &#xff08;2&#xff09;要求在 Kubernetes 环境中&#xff0c;通过yaml文件的方式&#xff0c;创建2个Nginx Pod分别放置在两个不同的节点上&#xff0c;Pod使用动态PV类型的存储卷挂载…

虚幻UE 插件-像素流送实现和优化

本笔记记录了像素流送插件的实现和优化过程。 UE version&#xff1a;5.3 文章目录 一、像素流送二、实现步骤1、开启像素流送插件2、设置参数3、打包程序4、打包后的程序进行像素流参数设置5、下载NodeJS6、下载信令服务器7、对信令服务器进行设置8、启动像素流送 三、优化1、…

路飞项目--03

总页面 二次封装Response模块 # drf提供的Response&#xff0c;前端想接收到的格式 {code:xx,msg:xx} 后端返回&#xff0c;前端收到&#xff1a; APIResponse(tokneasdfa.asdfas.asdf)---->{code:100,msg:成功,token:asdfa.asdfas.asdf} APIResponse(code101,msg用户不存…