FreeRTOS实时操作系统(2)

前言:FreeRTOS内容较多,分篇发布,较为基础,旨在梳理知识,适合入门的同学   
(基于正点原子STM32F103开发板V2)
(对于本篇,若有疑问,欢迎在评论区留言,作者将在两小时内解答)
(本篇参考B站正点原子FreeRTOS)

目录

前言:FreeRTOS内容较多,分篇发布,较为基础,旨在梳理知识,适合入门的同学   (基于正点原子STM32F103开发板V2)(对于本篇,若有疑问,欢迎在评论区留言,作者将在两小时内解答)(本篇参考B站正点原子FreeRTOS)

1.任务的挂起与恢复

​编辑1.1任务挂起函数

1.2任务恢复函数(任务中恢复)

1.3任务恢复函数(中断中恢复)

1.4任务挂起与恢复实验

1.5总结

2.中断管理

2.1什么是中断?

2.2中断优先级分组设置

2.3中断优先级配置寄存器

2.4中断屏蔽寄存器

2.5中断管理实验

3.临界段代码保护

3.1临界段

3.2临界段代码保护函数

4.任务调度器的挂起和恢复

5.总结


1.任务的挂起与恢复

挂起:挂起任务类似暂停,可恢复; 删除任务,无法恢复

恢复:恢复被挂起的任务

FromISR:带FromISR后缀是在中断函数中专用的API函数


1.1任务挂起函数

void vTaskSuspend(TaskHandle_t xTaskToSuspend)

注意:

1.此函数用于挂起任务,使用时需将宏 INCLUDE_vTaskSuspend  配置为 1

2.无论优先级如何,被挂起的任务都将不再被执行,直到任务被恢复

3.当传入的参数为NULL,则代表挂起任务自身(当前正在运行的任务)

1.2任务恢复函数(任务中恢复)

void vTaskResume(TaskHandle_t xTaskToResume)

注意:

1.使用该函数注意宏:INCLUDE_vTaskSuspend必须定义为 1

2.任务无论被 vTaskSuspend() 挂起多少次,只需在任务中调用  vTakResume() 恢复一次,就可以继续运行,且被恢复的任务会进入就绪态(不支持嵌套)

1.3任务恢复函数(中断中恢复)

BaseType_t xTaskResumeFromISR(TaskHandle_t xTaskToResume)

返回值

pdTRUE:当恢复的任务优先级大于正在执行任务的优先级时,由于抢占式调度,任务优先级高的抢占任务优先级低的,进行任务切换

pdFALSE:当恢复的任务优先级小于于正在执行任务的优先级时,不需要进行任务切换

注意:

1.使用该函数注意宏:INCLUDE_vTaskSuspend 和 INCLUDE_xTaskResumeFromISR 必须定义为 1

2.该函数专用于中断服务函数中,用于解挂被挂起任务

3.中断服务程序中要调用freeRTOS的API函数则中断优先级不能高于FreeRTOS所管理的最高优先级(特别注意)

重点说明第3点:

中断服务程序(ISR)通常在非常短的周期内运行,并且不能阻塞。如果 ISR 的优先级高于任务,那么 ISR 可能会不断打断任务的执行,导致任务无法完成,不断打断任务的执行:由于 ISR 的优先级更高,每次 ISR 被触发时,它都会抢占当前正在执行的任务。这会导致以下情况:

  • 任务无法完成:如果任务正在处理一个复杂或耗时的操作,ISR 的频繁打断会导致任务无法完成其当前的工作。
  • 上下文切换:每次 ISR 打断任务时,操作系统都需要保存任务的状态(上下文),然后切换到 ISR。ISR 完成后,再恢复任务的状态并继续执行。这种频繁的上下文切换会消耗大量的系统资源,并可能导致性能下降。
  • 系统响应性降低:如果高优先级的中断频繁发生,低优先级任务可能会长时间得不到执行,从而降低系统的响应性和实时性

1.4任务挂起与恢复实验

(基于正点原子STM32F103开发板V2)

本实验在<动态/静态创建任务实验>的基础上进行修改

动态/静态创建任务实验的start_task、task1、task2与本次实验相同,task3在本次实验进行修改

第一步:

将任务 挂起/恢复 函数宏 INCLUDE_vTaskSuspend  配置为 1(默认为1)

路径:\User\FreeRTOSConfig.h

第二步:

修改task3

/*** @brief       task3* @param       pvParameters : 传入参数(未用到)* @retval      无*/
void task3(void *pvParameters)
{uint8_t key = 0;while (1){key = key_scan(0);switch (key){case KEY0_PRES:                     /* 挂起任务1 */{vTaskSuspend(Task1Task_Handler); //调用挂起任务函数break;}case KEY1_PRES:                     /* 恢复任务1 */{vTaskResume(Task1Task_Handler);break;}default:{break;}}vTaskDelay(10);}
}

实验现象:

每500ms,两块区域颜色变化,并计数+1

按下KEY0  task1挂起(暂停变色和计数),按下KEY1task1恢复挂起(继续变色和计数)

1.5总结

2.中断管理

2.1什么是中断?

中断:让CPU打断正常运行的程序,转而去处理紧急的事件(程序)中断优先级分组设置

2.2中断优先级分组设置

ARM Cortex-M 使用了 8 位宽的寄存器来配置中断的优先等级,这个寄存器就是中断优先级配置寄存器 ,但STM32,只用了中断优先级配置寄存器的高4位 [7 : 4],所以STM32提供了最大16级的中断优先等级

STM32 的中断优先级可以分为抢占优先级和子优先级

抢占优先级: 抢占优先级高的中断可以打断正在执行但抢占优先级低的中断

子优先级:当同时发生具有相同抢占优先级的两个中断时,子优先级数值小的优先执行

特点:

中断优先级数值越小越优先

所以,我们STM32一共有五个分配方式

通过调用函数HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4)即可完成设置(在HAL_Init中设置)

FreeRTOS官网关于中断说明:https://www.freertos.org/RTOS-Cortex-M3-M4.html

注意事项:

1.低于configMAX_SYSCALL_INTERRUPT_PRIORITY优先级的中断里才允许调用FreeRTOS 的API函数(本套实验低于5优先级,即5-15中断被允许调用API函数)

2.建议将所有优先级位指定为抢占优先级位,方便FreeRTOS管理(调用函数HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4)

3.中断优先级数值越小越优先,任务优先级数值越大越优先

2.3中断优先级配置寄存器

三个系统中断优先级配置寄存器,分别为 SHPR1、 SHPR2、 SHPR3

SHPR1寄存器地址:0xE000ED18

SHPR2寄存器地址:0xE000ED1C

SHPR3寄存器地址:0xE000ED20

表出自:《Cortex M3权威指南(中文)》第286页

例如:

我们要设置PendSV的优先级,我们只要让SHPR3寄存器地址:0xE000ED20左移16位(8
+8)

我们要设置SysTick的优先级,我们只要让SHPR3寄存器地址:0xE000ED20左移24位(8
+8+8)

设置某位中断优先级路径

\Middlewares\FreeRTOS\portable\RVDS\ARM_CM3\port.c

配置FreeRTOS可管理的最高中断优先级 5-15

configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS): 

将 configLIBRARY_LOWEST_INTERRUPT_PRIORITY 的值左移 (8 - configPRIO_BITS) 位。如果 configPRIO_BITS 是 4,那么这个表达式就变成了 15 << 4

在二进制中,15 是 0000 1111。左移 4 位后,它变成了 1111 0000,这样15配置的就是寄存器的高四位了

注意:

PendSV和SysTick设置最低优先级,保证系统任务切换不会阻塞系统其他中断的响应

2.4中断屏蔽寄存器

三个中断屏蔽寄存器,分别为 PRIMASK、 FAULTMASK 和BASEPRI

FreeRTOS所使用的中断管理就是利用的BASEPRI这个寄存器

BASEPRI:屏蔽优先级低于某一个阈值的中断

FreeRTOS中的逻辑澄清
低优先级任务B执行时: 当低优先级任务B正在执行时,理想情况下,你不希望任何低优先级(数值上更大)的中断打断它,但是你希望允许高优先级(数值上更小)的中断,比如高优先级任务A的中断,能够打断B。因此,BASEPRI应该设置为一个值,该值允许高于B优先级的中断发生,而屏蔽掉低于或等于B优先级的中断。

高优先级任务A执行时: 在高优先级任务A执行时,理论上没有必要调整BASEPRI,因为A已经处于较高优先级,系统中的其他中断应该都是低于A的优先级(除了可能的系统保留中断,这些通常由操作系统管理,不受用户控制)。因此,对于A的执行,不需要通过BASEPRI来保护它免受低优先级任务的中断

例如:

BASEPRI设置为0x50(5<<4,高四位执行中断),代表中断优先级在5~15内的均被屏蔽,0~4的中断优先级正常执行

(但即使5-15优先级的中断被屏蔽,在特定状态下会被触发,一旦触发,系统就会进入相应的中断服务例程(ISR)来处理这个中断)

关中断:

中断服务函数中调度FreeRTOS的API函数需特别注意:

1.中断服务函数的优先级需在FreeRTOS所管理的范围内

2.在中断服务函数里边需调用FreeRTOS的API函数,必须使用带“FromISR”后缀的函数

开中断:

 BASEPRI:屏蔽优先级低于某一个阈值的中断,当设置为0时,则不关闭任何中断

2.5中断管理实验

(基于正点原子STM32F103开发板V2)

第一步:

定义两个定时器 TIM3、TIM5

路径:

\Drivers\BSP\TIMER\btim.h

#ifndef __BTIM_H
#define __BTIM_H#include "./SYSTEM/sys/sys.h"/******************************************************************************************/
/* 基本定时器 定义 *//* TIMX 中断定义 * 默认是针对TIM2~TIM5, TIM12~TIM17.* 注意: 通过修改这4个宏定义,可以支持TIM1~TIM17任意一个定时器.*/#define BTIM_TIM3_INT                       TIM3
#define BTIM_TIM3_INT_IRQn                  TIM3_IRQn
#define BTIM_TIM3_INT_IRQHandler            TIM3_IRQHandler
#define BTIM_TIM3_INT_CLK_ENABLE()          do{ __HAL_RCC_TIM3_CLK_ENABLE(); }while(0)  /* TIM3 时钟使能 */#define BTIM_TIM5_INT                       TIM5
#define BTIM_TIM5_INT_IRQn                  TIM5_IRQn
#define BTIM_TIM5_INT_IRQHandler            TIM5_IRQHandler
#define BTIM_TIM5_INT_CLK_ENABLE()          do{ __HAL_RCC_TIM5_CLK_ENABLE(); }while(0)  /* TIM5 时钟使能 *//******************************************************************************************/void btim_tim3_int_init(uint16_t arr, uint16_t psc);
void btim_tim5_int_init(uint16_t arr, uint16_t psc);#endif

第二步:

设置定时器优先级  TIM3 优先级为4  TIM5 优先级为6

路径:\Drivers\BSP\TIMER\btim.c

#include "./BSP/TIMER/btim.h"
#include "./SYSTEM/USART/usart.h"TIM_HandleTypeDef g_tim3_handle;        /* 定时器3句柄 */
TIM_HandleTypeDef g_tim5_handle;        /* 定时器5句柄 *//*** @brief       基本定时器TIM3定时中断初始化函数* @note*              基本定时器的时钟来自APB1,当PPRE1 ≥ 2分频的时候*              基本定时器的时钟为APB1时钟的2倍, 而APB1为36M, 所以定时器时钟 = 72Mhz*              定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.*              Ft=定时器工作频率,单位:Mhz** @param       arr: 自动重装值。* @param       psc: 时钟预分频数* @retval      无*/
void btim_tim3_int_init(uint16_t arr, uint16_t psc)
{BTIM_TIM3_INT_CLK_ENABLE();                                      /* 使能TIM3时钟 */g_tim3_handle.Instance = BTIM_TIM3_INT;                          /* 通用定时器3 */g_tim3_handle.Init.Prescaler = psc;                              /* 分频 */g_tim3_handle.Init.CounterMode = TIM_COUNTERMODE_UP;             /* 向上计数器 */g_tim3_handle.Init.Period = arr;                                 /* 自动装载值 */g_tim3_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;       /* 时钟分频因子 */HAL_TIM_Base_Init(&g_tim3_handle);HAL_NVIC_SetPriority(BTIM_TIM3_INT_IRQn, 4, 0);  /* 设置中断优先级,抢占优先级4,子优先级0 */HAL_NVIC_EnableIRQ(BTIM_TIM3_INT_IRQn);          /* 开启ITM3中断 */HAL_TIM_Base_Start_IT(&g_tim3_handle);           /* 使能定时器3和定时器3更新中断 */
}/*** @brief       基本定时器TIM5定时中断初始化函数* @note*              基本定时器的时钟来自APB1,当PPRE1 ≥ 2分频的时候*              基本定时器的时钟为APB1时钟的2倍, 而APB1为36M, 所以定时器时钟 = 72Mhz*              定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.*              Ft=定时器工作频率,单位:Mhz** @param       arr: 自动重装值。* @param       psc: 时钟预分频数* @retval      无*/
void btim_tim5_int_init(uint16_t arr, uint16_t psc)
{BTIM_TIM5_INT_CLK_ENABLE();                                      /* 使能TIM5时钟 */g_tim5_handle.Instance = BTIM_TIM5_INT;                          /* 通用定时器5 */g_tim5_handle.Init.Prescaler = psc;                              /* 分频 */g_tim5_handle.Init.CounterMode = TIM_COUNTERMODE_UP;             /* 向上计数器 */g_tim5_handle.Init.Period = arr;                                 /* 自动装载值 */g_tim5_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;       /* 时钟分频因子 */HAL_TIM_Base_Init(&g_tim5_handle);HAL_NVIC_SetPriority(BTIM_TIM5_INT_IRQn, 6, 0);  /* 设置中断优先级,抢占优先级6,子优先级0 */HAL_NVIC_EnableIRQ(BTIM_TIM5_INT_IRQn);          /* 开启ITM5中断 */HAL_TIM_Base_Start_IT(&g_tim5_handle);           /* 使能定时器5和定时器5更新中断 */
}/*** @brief       定时器中断服务函数* @param       无* @retval      无*/
void BTIM_TIM3_INT_IRQHandler(void)
{HAL_TIM_IRQHandler(&g_tim3_handle);
}/*** @brief       定时器中断服务函数* @param       无* @retval      无*/
void BTIM_TIM5_INT_IRQHandler(void)
{HAL_TIM_IRQHandler(&g_tim5_handle);
}/*** @brief       定时器更新中断回调函数
* @param        htim:定时器句柄指针* @retval      无*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) //htim 参数可以用来判断是哪个定时器触发了事件
{if (htim == (&g_tim3_handle)){printf("TIM3输出\r\n");}else if (htim == (&g_tim5_handle)){printf("TIM5输出\r\n");}
}

第三步:

配置定时器 TIM3 和 TIM5

路径:\User\freertos_demo.c

任务设置与前两个实验一样

我们主要看start_task

void start_task(void *pvParameters)
{taskENTER_CRITICAL();           /* 进入临界区 *//* 初始化TIM3、TIM5 */btim_tim3_int_init(10000-1, 7200-1);btim_tim5_int_init(10000-1, 7200-1);/* 创建任务1 */xTaskCreate((TaskFunction_t )task1,(const char*    )"task1",(uint16_t       )TASK1_STK_SIZE,(void*          )NULL,(UBaseType_t    )TASK1_PRIO,(TaskHandle_t*  )&Task1Task_Handler);vTaskDelete(StartTask_Handler); /* 删除开始任务 */taskEXIT_CRITICAL();            /* 退出临界区 */
}

重点解释   TIM3和5的配置

我们的实验基于正点原子STM32F103开发板V2,主频时钟频率为72Mhz

TIM3 和 TIM5 都通过 APB1 总线工作,APB1 的最大频率为系统时钟的 1/2,因此在 72 MHz 的情况下,APB1 的频率为 36 MHz

1. 第一个参数(10000-1

  • ARR(自动重装载寄存器)
    • 10000-1 设置了自动重装载值为 9999。这意味着定时器的计数范围是从 0 到 9999,共计 10000 个计数。当计数达到 9999 时,定时器将溢出并触发相应的中断(如果启用了中断)。

2. 第二个参数(7200-1

  • 预分频器(PSC)
    • 7200-1 设置了预分频器为 7199。预分频器的作用是将 TIM 时钟频率降低。以 36 MHz 的 TIM 时钟为例,设置预分频器为 7199 的计算方式如下:

3. 结果

  • 由于计数频率为 5 kHz,每个计数周期为 1 / 5000 秒,即 0.2 ms,所以,当计数到 9999(10000 次计数)时,实际的溢出时间为:10000×0.2 ms=2000 ms=2 s10000×0.2 ms=2000 ms=2 s
  • 计数频率:当你将定时器初始化为 9999 和 7199 时,定时器将以 5 kHz 的频率计数,并且每当计数到 9999 时,会溢出并触发中断。这将使得程序每 2秒(1 秒 / 5 kHz)执行一次相应的中断服务程序(ISR)

第四步:

编写开中断、关中断函数

路径:\User\freertos_demo.c


/*** @brief       task1* @param       pvParameters : 传入参数(未用到)* @retval      无*/
void task1(void *pvParameters)
{uint32_t task1_num = 0;while (1){if (++task1_num == 5){uint32_t task1_num = 0;printf("FreeRTOS关闭中断\r\n");portDISABLE_INTERRUPTS();       /* FreeRTOS关闭中断 */delay_ms(5000); //这里不用vTaskDelay是因为vTaskDelay会开启中断printf("FreeRTOS打开中断\r\n");portENABLE_INTERRUPTS();        /* FreeRTOS打开中断 */}vTaskDelay(1000);}
}

实验现象:

task1每执行五次,FreeRTOS打开/关闭中断

2.6总结

3.临界段代码保护

3.1临界段

临界段:临界段代码也叫做临界区,是指那些必须完整运行,不能被打断的代码段,临界区直接屏蔽了中断

使用场景

3.2临界段代码保护函数

 FreeRTOS 在进入临界段代码的时候需要关闭中断,当处理完临界段代码以后再打开中断

中断级进入临界段:

中断级临界段的主要目的是防止在中断服务程序(ISR)中被其他中断打断,确保在处理关键任务时的数据一致性和完整性

任务级临界区调用格式示例:

taskENTER_CRITICAL() ; //关中断
{… …	/* 临界区 */
}
taskEXIT_CRITICAL()	; //开中断

中断级临界区调用格式示例:

ISR{uint32_t  save_status;
save_status  = taskENTER_CRITICAL_FROM_ISR(); //备份save_status 中断屏蔽寄存器之前的值,然后关闭中断
{… …	/* 临界区 */
}
taskEXIT_CRITICAL_FROM_ISR(save_status );  //将之前save_status的值读回来}

特点:

1.成对使用

2.支持嵌套

3.尽量保持临界段耗时短

特别注意:

不允许临界区代码量太大,执行时间太长,否则会造成延时中断,中断得不到及时响应,这在FreeRTOS中是不允许的

4.任务调度器的挂起和恢复

挂起任务调度器(关闭任务切换), 调用此函数不需要关闭中断

使用格式示例:

vTaskSuspendAll() ;
{… …	/* 内容 */
}
xTaskResumeAll()	;

特点:

1.与临界区不一样的是,挂起任务调度器,未关闭中断

2.它仅仅是防止了任务之间的资源争夺,中断照样可以直接响应

3.挂起调度器的方式,适用于临界区位于任务与任务之间;既不用去延时中断,又可以做到临界区的安全

5.总结

FreeRTOS官网:https://www.freertos.org/

正点原子STM32F103开发板V2   a盘资料: https://pan.baidu.com/s/1iebOVd87jBVtoudMijboIg 提取码:1ypa

FreeRTOS内容较多,内容分篇发布,感谢大家观看

连载中...  

作者留言:本人学生,大多数为网络资源,如有侵权,及时联系,如有错误的地方,欢迎指出

创作时间:2024.10.25

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

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

相关文章

萤石设备视频接入平台EasyCVR私有化视频平台变电站如何实现远程集中监控?

一、方案背景 随着城市经济的发展和电力系统的改造&#xff0c;变电站的数量和规模逐渐增加&#xff0c;对变电站的安全管理和监控需求也越来越高。视频监控系统作为重要的安全管理手段&#xff0c;在变电站中起到了关键的作用。 目前青犀视频研发的萤石设备视频接入平台EasyC…

[网络协议篇] UDP协议

文章目录 1. 简介2. 特点3. UDP数据报结构4. 基于UDP的应用层协议5. UDP安全性问题6. 使用udp传输数据的系统就一定不可靠吗&#xff1f;7. 基于UDP的主机探活 python实现 1. 简介 User Datagram Protocol&#xff0c;用户数据报协议&#xff0c;基于IP协议提供面向无连接的网…

Spring AOP原理

&#xff08;一&#xff09;Spring AOP原理 Spring AOP是基于动态代理来实现AOP的&#xff0c;但是在讲之前我们要来先认识一下代理模式 1.代理模式 其实代理模式很好理解&#xff0c;简单来说就是&#xff0c;原本有一个对象&#xff0c;然后来了另一个对象&#xff08;我们称…

26.Redis主从架构

Redis主从架构 redis主从架构搭建&#xff0c;配置从节点步骤&#xff1a; 1、复制一份redis.conf文件 2、将相关配置修改为如下值&#xff1a; port 6380 pidfile /var/run/redis_6380.pid # 把pid进程号写入pidfile配置的文件 logfile "6380.log" dir /usr/local/…

3D-IC——超越平面 SoC 芯片的前沿技术

“3D-IC”&#xff0c;顾名思义是“立体搭建的集成电路”&#xff0c;相比于传统平面SoC&#xff0c;3D-IC引入垂直堆叠芯片裸片&#xff08;die&#xff09;和使用硅通孔&#xff08;TSV&#xff09;等先进封装技术&#xff0c;再提高性能、降低功耗和增加集成度方面展现了巨大…

同世界,共北斗|遨游通讯亮相第三届北斗规模应用国际峰会!

10月24日&#xff0c;第三届北斗规模应用国际峰会在湖南省株洲市隆重开幕&#xff0c;此次峰会以“同世界&#xff0c;共北斗”为主题&#xff0c;旨在加速北斗系统的市场化进程、促进其产业化布局及国际化拓展。全国政协副主席、农工党中央常务副主席杨震讲话并宣布开幕&#…

window7虚拟机VMware与主机共享文件

文件管理器》计算机网络右键》属性》高级共享设置——全部启用 新建文件夹》右键》属性》共享》选择可以共享的用户——我这里选的是所有用户 点击高级共享》权限》保存设置——设置文件权限 文件管理器》计算机网络》右键》属性》————查看虚拟机计算机名称 主机访问 主机…

构建安全基石:网络安全等级保护定级指南

在数字化时代&#xff0c;网络安全已成为企业与个人不可忽视的重要课题。网络安全等级保护定级指南&#xff0c;作为国家指导网络安全保护的重要文件&#xff0c;为各类机构提供了精准的安全防护蓝图。本文旨在深度解析网络安全等级保护定级指南的精髓&#xff0c;助力建构全面…

HarmonyOS 5.0应用开发——Navigation实现页面路由

【高心星出品】 文章目录 Navigation实现页面路由完整的Navigation入口页面子页面 页面跳转路由拦截其他的 Navigation实现页面路由 Navigation&#xff1a;路由导航的根视图容器&#xff0c;一般作为页面&#xff08;Entry&#xff09;的根容器去使用&#xff0c;包括单页面&…

基于FPGA的以太网设计(五)

之前简单介绍并实现了ARP协议&#xff0c;今天简单介绍一下IP协议和ICMP协议。 1.IP协议 IP协议即Internet Protocol&#xff0c;是网络层的协议。 IP协议是TCP/IP协议族的核心协议&#xff0c;其主要包含两个方面&#xff1a; IP头部信息。IP头部信息出现在每个IP数据报中…

将 el-date-picker获取的时间数据转换成时间戳

在Vue.js中使用Element UI的el-date-picker组件时&#xff0c;你可以获取用户选择的日期并将其转换为时间戳。el-date-picker通常返回的是一个Date对象或一个格式化后的字符串&#xff08;取决于你如何配置它&#xff09;。下面是一个示例&#xff0c;展示了如何将el-date-pick…

Spring Cloud OAuth认证中心

在微服务架构中&#xff0c;由于不同的业务会拆分成不同的微服务&#xff0c;传统的单体项目一般是通过过滤器进行拦截校验&#xff0c;而微服务显然不可能分发到各个服务进行用户认证&#xff0c;这就需要由一个统一的地方来管理所有服务的认证信息&#xff0c;实现只登录一次…

松脂醇-落叶松脂素还原酶(pinoresinol-lariciresinol reductase, PLR)克隆与鉴定-文献精读71

菘蓝中松脂醇-落叶松脂素还原酶编码基因IiPLR2的克隆与功能分析 摘要 松脂醇-落叶松脂素还原酶(pinoresinol-lariciresinol reductase, PLR)是植物中木脂素生物合成的关键酶&#xff0c;能连续催化两步反应分别生成落叶松脂素和开环异落叶松脂素。落叶松脂素等木脂素类成分是…

Unity SpriteEditor 中的图集处理功能

本文仅作笔记学习和分享&#xff0c;不用做任何商业用途 本文包括但不限于unity官方手册&#xff0c;unity唐老狮等教程知识&#xff0c;如有不足还请斧正 因为unity不只能做3d&#xff0c;还有2d游戏需要大量编辑处理图片素材&#xff0c;所以需要了解Sprite&#xff08;精灵&…

KPaaS 集成平台低代码在跨境电商行业的应用

在全球化的经济浪潮中&#xff0c;跨境电商行业蓬勃发展&#xff0c;机遇与挑战并存。随着业务规模的不断扩大和市场竞争的日益激烈&#xff0c;跨境电商企业面临着诸多复杂的业务管理和技术难题。KPaaS 业务集成扩展平台以其低代码的创新特性&#xff0c;为跨境电商行业带来了…

头歌——人工智能(机器学习 --- 决策树2)

文章目录 第5关&#xff1a;基尼系数代码 第6关&#xff1a;预剪枝与后剪枝代码 第7关&#xff1a;鸢尾花识别代码 第5关&#xff1a;基尼系数 基尼系数 在ID3算法中我们使用了信息增益来选择特征&#xff0c;信息增益大的优先选择。在C4.5算法中&#xff0c;采用了信息增益率…

银河麒麟相关

最近安装了银河麒麟server版本&#xff0c;整理下遇到的一些小问题 1、vmware安装Kylin-Server-V10-SP3-General-Release-2303-X86_64虚拟机完成后&#xff0c;桌面窗口很小&#xff0c;安装vmwaretools后解决&#xff0c;下载地址http://softwareupdate.vmware.com/cds/vmw-de…

leetcode-71-简化路径

题解&#xff1a; 1、以"/"作为分隔符对字符串进行分割得到数组names; 2、初始化一个栈stack&#xff08;python中的栈使用列表实现&#xff09;&#xff1b; 3、遍历数组names&#xff1b;如果当前元素为".."且栈不为空&#xff0c;则将弹出栈顶元素&a…

网络安全行业10大副业汇总,总有一个适合你

网络安全行业这10大副业汇总 总有一个适合你 引言 在当今的网络安全行业中&#xff0c;除了全职工作外&#xff0c;许多师傅还通过副业来增加收入、不断拓展自身技能&#xff0c;并积累更多实际操作经验&#xff0c;为职业发展增添了无限可能。 本文提供了10种适合各种类型…

Android13关于获取外部存储文件的相关问题及解决方案记录

Android的学习路上... 测试设备&#xff1a;vivo X90s安卓版本&#xff1a; Android13开发环境&#xff1a;AndroidStudio FlamingoSDK&#xff1a;33 最近我在Android13的环境下尝试写一个文件选择器&#xff0c;以便日后的开发使用。但是我们知道&#xff0c;从Android13 (A…