STM32第二十课:FreeRTOS任务管理和信号量

news2024/11/15 4:19:32

目录

  • 一、任务管理方式
  • 二、任务堆栈溢出检测
  • 三、二值信号量(任务同步)
  • 四、计数信号量
  • 五、互斥信号量
  • 六、队列


一、任务管理方式

在这里插入图片描述
1.任务创建成功后会添加到就绪链表中,开启调度器,此时任务调度器会去就绪链表中找优先级最高的任务执行。若优先级一样则按照创建任务的先后来执行。
2.任务被执行时就会变为运行态时,该任务就会从就绪链表删除,若此时执行到任务中的vTaskDelay等函数时,该任务就会被挪到阻塞链表中。调度器此时会去执行其他任务。
3.当阻塞解除时,该任务会从阻塞链表中删掉,移动到就绪链表中。若解除任务的优先级很高,那么此时该任务会直接打断cpu正在执行的任务,抢占位置去执行自己。

二、任务堆栈溢出检测

详情见FreeRTOS中的任务堆栈溢出检测机制
主要作用就是方便调试,工程做完之后没问题了就关掉
写检测函数之前需要更改宏定义,我们采用的是第二种堆栈检测方法。
![

void vApplicationStackOverflowHook( TaskHandle_t xTask,char *pcTaskName )
{
	printf("任务:%s->栈溢出\r\n",pcTaskName);
	printf("任务剩余空间:%d\r\n",(int)uxTaskGetStackHighWaterMark(xTask));
	while(1)//栈溢出时卡死到钩子函数中
	{}
}

本质上就是一个钩子函数,在任务上下文切换的时候做检测,具有一定的滞后性,需要在任务发生上下文切换时才会进行,任务堆栈溢出时并不能马上检测到问题。
但大多常见情况下这种检测机制依然是非常实用的功能,可以帮助用户减少代码中的错误并提高应用程序代码的质量。

三、二值信号量(任务同步)

任务同步:任务B需要等待任务A执行完再去执行。
二值信号量也一样,谁拥有谁执行,比如任务B需要获得信号量才能执行,那么他就要等待A给他一个信号量然后再去执行。

1.添加头文件

#include "semphr.h"

2.创建一个SemaphoreHandle_t 类型的二值信号量句柄

SemaphoreHandle_t Binary;

3.主函数创建二值信号量,返回值为该信号量的句柄

	//创建一个二值信号量
	Binary = xSemaphoreCreateBinary();

4.使用函数xSemaphoreGive给出二值信号量,参数为二值信号量的句柄

xSemaphoreGive(Binary)

5.使用xSemaphoreTake函数接收二值信号量,参数为句柄和超时时间(也可填写portMAX_DELAY,表示死等)
若返回值为pdTRUE,则表示获取到该信号量。

if(xSemaphoreTake(Binary,1000) == pdTRUE) 
		{
			printf("按键按下,获取到信号量\r\n");
		}

完整代码

//包含支持stm32f1系列的头文件
#include  "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "usart.h"
#include "key.h"
#include "adc.h"
#include "kqm.h"
#include "dht11.h"

//使用FreeRTOS相关头文件之前先包含FreeRTOS.h
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/********************信号量句柄***********************/
SemaphoreHandle_t Binary;

//传感器任务
TaskHandle_t Sensor_TaskHandle;
void Sensor_Task(void *p)
{
	
	while(1)
	{
		taskENTER_CRITICAL();//进入临界区
		Dht11ReadData();//DHT11读取函数不能被打断
		taskEXIT_CRITICAL();//退出临界区
		KQMDealData();//该函数的调用时间小于等于1秒
		ADC_DataFliter();//ADC均值滤波
		vTaskDelay(1000);//阻塞1秒
	}
}

//任务本体 闪灯任务
TaskHandle_t LED_TaskHandle;
void LED_Task(void *p)
{
	uint8_t i=0;
	while(1)
	{
		if(xSemaphoreTake(Binary,1000) == pdTRUE) 
		{
			printf("按键按下,获取到信号量\r\n");
		}else
		{
			printf("获取到信号量等待超时\r\n");
		}
		i++;
		printf("i=%d\r\n",i);
		Led_Toggle(1);
		//printf("LED任务剩余空间:%d\r\n",(int)uxTaskGetStackHighWaterMark(NULL));
//		Delay_nms(200);//也能延时,但是会一直占用CPU
		//也是延时200ms,但是FreeRTOS提供的函数,有阻塞机制,能够让任务从运行态变为阻塞态
		vTaskDelay(200);
	}
}
//任务本体 按键任务
TaskHandle_t KEY_TaskHandle;
void KEY_Task(void *p)
{
	while(1)
	{
		switch(key_getvalue())
		{
			case 1:vTaskSuspend(LED_TaskHandle);break;
			case 2:vTaskResume(LED_TaskHandle);break;
			case 3:xSemaphoreGive(Binary);break;
			case 4:break;
		}
		vTaskDelay(10);//MS级别的延时,带有阻塞性质,任务会从运行态变为阻塞态
	}
}	

int main()
{
	Led_Init();//初始化LED
	Key_init();//初始化按键
	Usart1_Config();//初始化串口1
	ADC_Config();//初始化ADC
	Kqm_U4Config();//初始化KQM
	DHT11_Mode();//初始化DHT11
	BaseType_t Ret = pdPASS;
	//创建一个二值信号量
	Binary = xSemaphoreCreateBinary();
	//1,如何创建一个任务?
	Ret = xTaskCreate(Sensor_Task,"Sensor_Task",200,NULL,1,&Sensor_TaskHandle);
	Ret = xTaskCreate(LED_Task, //创建任务的任务函数名
                    "LED1_Toggle",//任务名字
                    100,//任务栈深度。32位单片机*4
                    NULL,//创建任务时传递参数,没有就给NULL
                    3,//任务优先级
										&LED_TaskHandle);//任务的句柄,用于后边删除,挂起任务
	if(Ret == pdPASS){
		printf("LED_Task创建完成\r\n");
	}
	Ret = xTaskCreate(KEY_Task, //创建任务的任务函数名
                    "KEY_Task",//任务名字
                    100,//任务栈深度。32位单片机*4
                    NULL,//创建任务时传递参数,没有就给NULL
                    2,//任务优先级
										&KEY_TaskHandle);//任务的句柄,用于后边删除,挂起任务
	if(Ret == pdPASS){
		printf("KEY_Task创建完成\r\n");
	}
	printf("开启FreeRTOS调度器\r\n");
	//调度器启动完成之后,FreeRTOS会获取CPU控制权,会按照任务优先级执行创建的任务
	vTaskStartScheduler();
				
	while(1)
	{	
	}
}

void vApplicationStackOverflowHook( TaskHandle_t xTask,char *pcTaskName )
{
	printf("任务:%s->栈溢出\r\n",pcTaskName);
	printf("任务剩余空间:%d\r\n",(int)uxTaskGetStackHighWaterMark(xTask));
	while(1)//栈溢出时卡死到钩子函数中
	{}
}


四、计数信号量

一般在资源有限的情况下使用,如:停车场,坐位,传感器的访问等。
计数信号量测试:按键和灯,按键按下几次,灯翻转几次。
1.创建计数信号量的句柄

SemaphoreHandle_t Count_Handle;//计数信号量句柄

2.创建计数信号量
返回值为该信号量的句柄,参数为最大信号量为多少和初始信号量有几个。

Count_Handle = xSemaphoreCreateCounting(10,5);//创建计数信号量

3.给出信号量
参数为计数信号量的句柄

xSemaphoreGive(Count_Handle);

4.消耗信号量
参数和二值信号量一样,一个是对应的句柄,一个是超时。
成功返回pdTRUE。

if(xSemaphoreTake(Count_Handle,portMAX_DELAY) == pdTRUE) 

完整代码

#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "delay.h"
#include "string.h"
#include "pwm.h"
#include "adc.h"
#include "su03t.h"
#include "dht11.h"
#include "kqm.h"
#include "usart.h"
#include "key.h"

//使用FreeRtos相关头文件之前,一定要先包含这个#include "FreeRtos.h"
#include "FreeRtos.h"
#include "task.h"
#include "semphr.h"
#include "queue.h"

TaskHandle_t Deal_TaskHandle;//数据处理
SemaphoreHandle_t Binary;//二值信号量句柄
SemaphoreHandle_t Count_Handle;//计数信号量句柄
TaskHandle_t LED_TaskHandle;//任务本体 闪灯任务
TaskHandle_t KEY_TaskHandle;//任务本体 按键任务
void Data_Task(void *p)
{
	while(1)
	{
	Get_Smoke_Light_MidValue();
	DHT11_ReadData();
	vTaskDelay(300);
	KQM_DealData();
	Su03tDealData();
	}
}

void KEY_Task(void *p)
{
	while(1)
	{
		switch(key_getvalue())
		{
			case 1:vTaskSuspend(LED_TaskHandle);break;
			case 2:vTaskResume(LED_TaskHandle);break;
			case 3:xSemaphoreGive(Count_Handle);printf("给一个计数信号量\r\n");break;
			case 4:break;
		}
		vTaskDelay(10);//MS级别的延时,带有阻塞性质,任务会从运行态变为阻塞态
	}
}	
void LED_Task(void *p)
{
	uint8_t i=0;
	while(1)
	{
		if(xSemaphoreTake(Count_Handle,portMAX_DELAY) == pdTRUE) 
		{
			printf("消耗计数信号量\r\n");
			i++;
			printf("i=%d\r\n",i);
			Led_Toggle(1);
			vTaskDelay(1000);
		}
	}
}



int main()
{
	RGBpwm_Config();
  Kqm_U4Config();
  Su03t_U5Config();
	DHT11_Config();	 
	Adc_Config();
	Led_Init();
	key_Init();
	Usart1_Config();
	BaseType_t Ret = pdPASS;
//	Ret = xTaskCreate(Data_Task,"DealData",300,NULL,2,&Deal_TaskHandle);
//	if(Ret==pdPASS)
//	{
//		printf("数据创建成功!\r\n");
//	}
	Binary = xSemaphoreCreateBinary();
	//计数信号量最大值   初始时有多少个信号量可用
	Count_Handle = xSemaphoreCreateCounting(10,5);//创建计数信号量
		Ret = xTaskCreate(LED_Task, //创建任务的任务函数名
                    "LED1_Toggle",//任务名字
                    100,//任务栈深度。32位单片机*4
                    NULL,//创建任务时传递参数,没有就给NULL
                    3,//任务优先级
										&LED_TaskHandle);//任务的句柄,用于后边删除,挂起任务
	if(Ret == pdPASS){
		printf("LED_Task创建完成\r\n");
	}
	Ret = xTaskCreate(KEY_Task, //创建任务的任务函数名
                    "KEY_Task",//任务名字
                    100,//任务栈深度。32位单片机*4
                    NULL,//创建任务时传递参数,没有就给NULL
                    2,//任务优先级
										&KEY_TaskHandle);//任务的句柄,用于后边删除,挂起任务
	if(Ret == pdPASS){
	printf("KEY_Task创建完成\r\n");
	}
	printf("开启FreeRTOS调度器成功\r\n");
	vTaskStartScheduler();
	while(1)
	{
		
	}
}

void vApplicationStackOverflowHook( TaskHandle_t xTask,char *pcTaskName )
{
	printf("任务:%s->栈溢出\r\n",pcTaskName);
	printf("任务剩余空间:%d\r\n",(int)uxTaskGetStackHighWaterMark(xTask));
	while(1)//栈溢出时卡死到钩子函数中
	{}
}

五、互斥信号量

用于共享资源的保护
资源A是共享资源,此时如果被任务1使用,那么就不能被其他任务使用。
(任务1:小A,你让我使用了,可就不能让别人使用了哦 ~)
1.创建句柄

SemaphoreHandle_t Mutex_Handle=NULL;

2.创建互斥信号量
返回值为互斥信号量的句柄

Mutex_Handle = xSemaphoreCreateMutex();//创建互斥信号量

3.获取信号,给出信号
保护printf,使printf能够完整打印。

void MyPrintf(char *p)
{
	xSemaphoreTake(Mutex_Handle,portMAX_DELAY);//获取信号量
	printf("%s",p);
	xSemaphoreGive(Mutex_Handle);//还回去
}

完整代码:

#include "delay.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "usart.h"
#include "stdio.h"
#include "led.h"
#include "key.h"
#include "dht.h"
#include "adc.h"
#include "kqm.h"

/*******************信号量句柄*********************/
SemaphoreHandle_t Binary_Handle=NULL;
SemaphoreHandle_t Count_Handle=NULL;
SemaphoreHandle_t Mutex_Handle=NULL;
/*******************互斥信号量保护资源*********************/
void MyPrintf(char *p)
{
	xSemaphoreTake(Mutex_Handle,portMAX_DELAY);//获取信号量
	printf("%s",p);
	xSemaphoreGive(Mutex_Handle);//还回去
}

/*******************LED任务*********************/
TaskHandle_t LEDtask_Handle = NULL;
//任务函数本身
void LED_Task(void * p)
{
	MyPrintf("LED任务创建成功\r\n");
	LED_Config();
	BEEP_Config();
	while(1)
	{	
		if(xSemaphoreTake(Count_Handle,portMAX_DELAY) == pdTRUE)
		{
			MyPrintf("LED反转\r\n");
			LED1_Toggle();
		}else
		{
			MyPrintf("超时结束\r\n");
		}
		vTaskDelay(500);//控制任务的执行周期
	}
}
/*******************按键任务*********************/
TaskHandle_t KEYtask_Handle = NULL;
//任务函数本身
void KEY_Task(void * p)
{
	MyPrintf("按键任务创建成功\r\n");
	KEY_Config();
	while(1)
	{	
		switch(KEY_Scan())
		{
			case 1:BEEP_Toggle(); break;
			case 2:
//				xSemaphoreGive(Binary_Handle);//给出二值信号量
				if(xSemaphoreGive(Count_Handle) == pdTRUE)//给出计数信号量
				{
					MyPrintf("成功给出计数信号量\r\n");
				}else
				{
					MyPrintf("信号量已满\r\n");
				}
				break;
			case 3: break;
			case 4:vTaskDelete(LEDtask_Handle);break;
		}
		vTaskDelay(10);
	}
}
/*******************传感器任务*********************/
TaskHandle_t Senortask_Handle = NULL;
//任务函数本身
void Senor_Task(void * p)
{
	MyPrintf("传感器任务创建成功\r\n");
	uint8_t cnt = 0;
	ADC_Config();//初始化ADC
	UART4_Config();//初始化KQM传感器
	while(1)
	{	
		cnt++;
		if(KQM_Anlyze() == 0)
		{
			printf("CO2:%d\r\n",kqmdata.CO2);
		}else
		{
			MyPrintf("KQM数据错误\r\n");
		}
		if(cnt>=3)
		{
			cnt = 0;
			taskENTER_CRITICAL();//进入临界区
			if(DHT11_ReadData()== 0)
			{
				printf("温度数据:%.2f 湿度数据:%d\r\n",TEM,HUM);
			}else
			{
				MyPrintf("温湿度数据获取失败\r\n");
			}
			taskEXIT_CRITICAL();//退出临界区			
		}
		vTaskDelay(1000);
	}
}
int main(void)
{
	USART_Config();
	BaseType_t Ret = pdPASS;
	Binary_Handle = xSemaphoreCreateBinary();//创建二值信号量
	//                       计数信号量最大值   初始时有多少个信号量可用
	Count_Handle = xSemaphoreCreateCounting(10,5);//创建计数信号量
	Mutex_Handle = xSemaphoreCreateMutex();//创建互斥信号量
	//动态创建任务
	Ret =  xTaskCreate(LED_Task,//任务函数的入口,也就是函数名
                     "LED_Task",//任务别名,方便FreeRTOS管理
                     100,//任务分配的堆栈空间 32单片机就是50*4 = 200字节
                     NULL,//任务函数的参数,无参数就写NULL
                     1,//任务优先级
                     &LEDtask_Handle);//任务的句柄(指针),可以用来管理任务
	if(Ret == pdPASS)
	{
		printf("LED任务创建成功\r\n");
	}
	//动态创建任务
	Ret =  xTaskCreate(KEY_Task,//任务函数的入口,也就是函数名
                     "KEY_Task",//任务别名,方便FreeRTOS管理
											100,//任务分配的堆栈空间 32单片机就是50*4 = 200字节
                     NULL,//任务函数的参数,无参数就写NULL
                     1,//任务优先级
                     &KEYtask_Handle);//任务的句柄(指针),可以用来管理任务
	if(Ret == pdPASS)
	{
		printf("按键任务创建成功\r\n");
	}
	Ret =  xTaskCreate(Senor_Task,//任务函数的入口,也就是函数名
                     "Senor_Task",//任务别名,方便FreeRTOS管理
                     100,//任务分配的堆栈空间 32单片机就是50*4 = 200字节
                     NULL,//任务函数的参数,无参数就写NULL
                     2,//任务优先级
                     &Senortask_Handle);//任务的句柄(指针),可以用来管理任务
	if(Ret == pdPASS)
	{
		printf("传感器任务创建成功\r\n");
	}
	vTaskStartScheduler();//启动调度器
	printf("调度器启动失败\r\n");
  while (1)
  {

	}
}

//函 数 功 能:任务栈溢出钩子函数,调试阶段用
void vApplicationStackOverflowHook(TaskHandle_t xTask,signed char *pcTaskName)
{
	printf("任务:#%s #栈溢出\r\n",pcTaskName);
	printf("任务栈空间剩余:%d\r\n",uxTaskGetStackHighWaterMark(xTask));
	while(1)
	{
	}
}

六、队列

  主要用于任务间数据传输,采用FIFO(先进先出)模式,新数据通常发到队列后面,但也可以发到队列前面。
1.创建句柄

QueueHandle_t Queue;

2.创建队列

//创建队列 长度为10 ,队列中每个数据的大小2字节
	Queue = xQueueCreate(10,2);

3.接收数据
参数1:要发送数据的目标队列的句柄。
参数2:指向要发送数据的指针。
参数3:发送数据时等待的最长时间
返回值:
pdPASS:数据成功发送到队列。
errQUEUE_FULL:队列已满,无法发送数据。

if(xQueueReceive(Queue,buff2,100)==pdTRUE)

4.发送数据

if(xQueueSend(Queue,buff,100) == pdTRUE)

完整代码:

//包含支持stm32f1系列的头文件
#include  "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "usart.h"
#include "key.h"
#include "adc.h"
#include "kqm.h"
#include "dht11.h"

//使用FreeRTOS相关头文件之前先包含FreeRTOS.h
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/********************信号量句柄***********************/
SemaphoreHandle_t Binary;
SemaphoreHandle_t Count;
SemaphoreHandle_t Mutex;
/********************队列句柄***********************/
QueueHandle_t Queue;
QueueHandle_t KqmQueue;
/*********************互斥锁保护Printf****************/
void MyPrintf(char *p)
{
	xSemaphoreTake(Mutex,portMAX_DELAY);
	printf("%s",p);
	xSemaphoreGive(Mutex);
}

//传感器任务
TaskHandle_t Sensor_TaskHandle;
void Sensor_Task(void *p)
{
	uint8_t recv[8] = {0};
	MyPrintf("Sensor Task Begin\r\n");
	while(1)
	{
		if(xQueueReceive(KqmQueue,recv,100)==pdTRUE)
		{
			printf("接受数据:%x %x %x %x %x %x %x %x\r\n",recv[0],recv[1],\
			recv[2],recv[3],recv[4],recv[5],recv[6],recv[7]);
		}else
		{
			printf("队列为空,接收失败\r\n");
		}
		taskENTER_CRITICAL();//进入临界区
		Dht11ReadData();//DHT11读取函数不能被打断
		ADC_DataFliter();//ADC均值滤波
		taskEXIT_CRITICAL();//退出临界区
		vTaskDelay(1000);//阻塞1秒
	}
}

//任务本体 闪灯任务
TaskHandle_t LED_TaskHandle;
void LED_Task(void *p)
{
	uint8_t i=0;
	MyPrintf("LED_Task Begin\r\n");
	while(1)
	{
		if(xSemaphoreTake(Count,portMAX_DELAY) == pdTRUE) 
		{
			MyPrintf("按键按下,获取到信号量\r\n");
		}else
		{
			MyPrintf("获取到信号量等待超时\r\n");
		}
		printf("i=%d\r\n",i++);
		Led_Toggle(1);
		//printf("LED任务剩余空间:%d\r\n",(int)uxTaskGetStackHighWaterMark(NULL));
//	Delay_nms(200);//也能延时,但是会一直占用CPU
		//也是延时200ms,但是FreeRTOS提供的函数,有阻塞机制,能够让任务从运行态变为阻塞态
		vTaskDelay(1000);
	}
}
//任务本体 按键任务
TaskHandle_t KEY_TaskHandle;
void KEY_Task(void *p)
{
	uint8_t buff[2] = {0xAA,0x55};
	uint8_t buff2[2] = {0};
	MyPrintf("KEY_Task Begin\r\n");
	while(1)
	{
		switch(key_getvalue())
		{
			case 1:
				if(xQueueSend(Queue,buff,100) == pdTRUE)
				{
					printf("发送成功\r\n");
				}else
				{
					printf("队列已满,发送失败\r\n");
				}
				break;
			case 2:
				if(xQueueReceive(Queue,buff2,100)==pdTRUE)
				{
					printf("接受数据:%x %x\r\n",buff2[0],buff2[1]);
				}else
				{
					printf("队列为空,接收失败\r\n");
				}
				break;
			case 3:xSemaphoreGive(Count);break;
			case 4: break;
		}
		vTaskDelay(10);//MS级别的延时,带有阻塞性质,任务会从运行态变为阻塞态
	}
}	

int main()
{
	Led_Init();//初始化LED
	Key_init();//初始化按键
	Usart1_Config();//初始化串口1
	ADC_Config();//初始化ADC
	Kqm_U4Config();//初始化KQM
	DHT11_Mode();//初始化DHT11
	BaseType_t Ret = pdPASS;
	//创建一个二值信号量
	Binary = xSemaphoreCreateBinary();
	//创建一个计数信号量
	Count = xSemaphoreCreateCounting(10,5);
	//创建互斥锁
	Mutex = xSemaphoreCreateMutex();
	//创建队列 长度为10 ,队列中每个数据的大小2字节
	Queue = xQueueCreate(10,2);
	KqmQueue = xQueueCreate(1,8);
	//1,如何创建一个任务?
	Ret = xTaskCreate(Sensor_Task,"Sensor_Task",200,NULL,1,&Sensor_TaskHandle);
//	Ret = xTaskCreate(LED_Task, //创建任务的任务函数名
//                    "LED1_Toggle",//任务名字
//                    100,//任务栈深度。32位单片机*4
//                    NULL,//创建任务时传递参数,没有就给NULL
//                    1,//任务优先级
//										&LED_TaskHandle);//任务的句柄,用于后边删除,挂起任务
//	if(Ret == pdPASS){
//		printf("LED_Task创建完成\r\n");
//	}
	Ret = xTaskCreate(KEY_Task, //创建任务的任务函数名
                    "KEY_Task",//任务名字
                    100,//任务栈深度。32位单片机*4
                    NULL,//创建任务时传递参数,没有就给NULL
                    1,//任务优先级
										&KEY_TaskHandle);//任务的句柄,用于后边删除,挂起任务
	if(Ret == pdPASS){
		printf("KEY_Task创建完成\r\n");
	}
	printf("开启FreeRTOS调度器\r\n");
	//调度器启动完成之后,FreeRTOS会获取CPU控制权,会按照任务优先级执行创建的任务
	vTaskStartScheduler();
	printf("开启FreeRTOS调度器成功\r\n");
	while(1)
	{	
	}
}

void vApplicationStackOverflowHook( TaskHandle_t xTask,char *pcTaskName )
{
	printf("任务:%s->栈溢出\r\n",pcTaskName);
	printf("任务剩余空间:%d\r\n",(int)uxTaskGetStackHighWaterMark(xTask));
	while(1)//栈溢出时卡死到钩子函数中
	{}
}

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

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

相关文章

数据增强新方法SUMix:解决Mixup混合后的图像的内容与其标签不匹配问题

数据增强新方法SUMix:解决Mixup混合后的图像的内容与其标签不匹配问题 提出背景当前混合方法的问题MixUp 操作标签混合混合交叉熵(MCE)混合交叉熵(MCE)的核心作用混合交叉熵(MCE)的功能 CutMix原…

$accumulator(聚合)

$accumulator 是 MongoDB 聚合管道中用于自定义数据处理逻辑的一个算子,它允许用户使用 JavaScript 编写代码来控制数据的初始化、累积、合并和最终输出。下面是对 $accumulator 各个部分的详细解释: init: 这是一个 JavaScript 函数,用于初…

数据结构回顾(Java)

1.数组 线性表 定义的方式 int[] anew int[10] 为什么查询快? 1.可以借助O(1)时间复杂度访问某一元素, 2.地址连续,逻辑连续 3.数组长度一旦确定就不可以被修改 当需要扩容的时候需要将老数组的内容复制过来 在Java中数组是一个对象 Ar…

多样化数据可视化方法的全面示例:基于Python的多样化数据可视化

文章目录 前言代码效果展示 前言 本文演示了使用Python进行温度数据的多样化可视化方法。通过导入、处理和分析气象数据,我们生成了多种图表,包括直方图、核密度估计图、箱型图、小提琴图、条形图、山脊图、经验累积分布函数图和折线图。这些图表帮助我…

国内体外诊断行业翘楚『迈克生物』SRM项目启动,企企通赋能IVD产业打造高效采购供应链体系

IVD行业(体外诊断行业)在医疗领域被誉为“医生的眼睛”,是现代检验医学的重要构成部分,在临床应用中贯穿了疾病预防、初步诊断、治疗方案选择、疗效评价等疾病治疗的全过程,在现代医学疾病诊断中发挥着重要作用。 随着…

springboot1——快速构建项目

需求 第一步:创建maven工程(非web项目) 第二步:导入起步依赖 点击: 下拉复制: 粘贴:!!这是springboot工程需要继承的父工程 下拉复制: 粘贴:!&#xf…

JAVA:常用的链表指南

请关注微信公众号:拾荒的小海螺 博客地址:http://lsk-ww.cn/ 1、简述 链表是一种常见的数据结构,它通过一系列节点(Node)来表示一个序列。每个节点包含数据和指向下一个节点的引用。链表的种类有很多,包括…

网络文件系统—NFS

目录 一、概述 二、NFS挂载原理 三、NFS相关协议及软件安装管理 1.协议: 2.软件: 四、NFS系统守护进程 五、NFS服务器的配置 六、NFS服务器的启动与停止 1. 启动NFS服务器 2.查询NFS服务器状态 3.停止NFS服务器 4.设置NFS服务器的自动启动状…

games103作业2(未完)

PBD方法 首先是每个质点的力的分析,不考虑碰撞和弹簧弹力的情况下,每个质点受重力的影响,所以需要对每个质点进行速度和位置的重力影响更新。 float t 0.0333f; float damping 0.99f; int[] E; float[] L; Vector3[] V; Vector3 gra…

【数学建模】——数学规划模型

目录 一、线性规划(Linear Programming) 1.1 线性规划的基本概念 1.2 线性规划的图解法 模型建立: 二、整数规划(Integer Programming) 2.1 整数规划的基本概念 2.2 整数规划的求解方法 三、非线性规划&#x…

<数据集>绝缘子缺陷检测数据集<目标检测>

数据集格式:VOCYOLO格式 图片数量:2139张 标注数量(xml文件个数):2139 标注数量(txt文件个数):2139 标注类别数:8 标注类别名称:[insulator, broken disc, pollution-flashover, Two glass, Glassdirt…

220V降压5ⅤIC-AH8652

220V降压至5V的IC - AH8652 在电子设计中,电压转换是一个常见的需求,尤其是在需要将高电压转换为低电压以供电给微电子设备时。AH8652是一款专为降压转换设计的集成电路,它能够将220V的交流输入电压转换为稳定的5V直流输出,非常适…

Camunda如何通过外部任务与其他系统自动交互

文章目录 简介流程图外部系统pom.xmllogback.xml监听类 启动流程实例常见问题Public Key Retrieval is not allowed的解决方法java.lang.reflect.InaccessibleObjectException 流程图xml 简介 前面我们已经介绍了Camunda的基本操作、任务、表: Camunda组件与服务与…

spring6之容器:IOC

容器:IOC 控制反转(Ioc) IoC容器在Spring的实现 Spring 的 IoC 容器就是 IoC思想的一个落地的产品实现。IoC容器中管理的组件也叫做 bean。在创建 bean 之前,首先需要创建IoC 容器。Spring 提供了IoC 容器的两种实现方式&#xf…

华为HCIP Datacom H12-821 卷39

1.填空题 请2001 :0DB8:0000:C030:0000: 000: 09A0:CDEF地址进行压缩。() (若答案中存在字母,请采用大写格式) 参考答案:2001 :DB8:0:C030: :9A0:CDEF 解析: IPv6地址的表示方法 IPv6地址总长度为128比特,通常分为8组&#xff0c…

防御综合实验作业2

办公区设备可以通过电信链路和移动链路上网(多对多的NAT,并且需要保留一个公网IP NAT策略: 安全策略: 测试: 分公司设备可以通过总公司的移动链路和电信链路访问到Dmz区的http服务器 是怎么转换的,首先分公司的用户需…

温度如何影响输入失调电压

目录 一、概念理解 二、仿真理解 一、概念理解 在手册中有这样一个参数:输入失调电压漂移(input offset voltage drift / offset drift) 以上图为例,这个参数理解为:常温下(25℃)每增减1摄氏度…

【STM32开发笔记】搭建VSCode+PyOCD的STM32开发环境

【STM32开发笔记】搭建VSCodePyOCD的STM32开发环境 一、安装软件1.1 安装STM32CubeMX1.2 安装VSCode1.3 安装Arm GNU Toolchain1.4 安装Make for Windows1.5 安装Python1.6 安装PyOCD 二、安装插件2.1 VSCode插件2.2 PyOCD支持包 三、创建项目3.1 创建STM32CubeMX项目3.2 查阅原…

PostgreSQL 中如何处理数据的并发读写和锁等待超时?

🍅关注博主🎗️ 带你畅游技术世界,不错过每一次成长机会!📚领书:PostgreSQL 入门到精通.pdf 文章目录 PostgreSQL 中如何处理数据的并发读写和锁等待超时一、并发读写的基本概念(一)…

org/openxmlformats/schemas/spreadsheetml/x2006/main/CTWorkbook$Factory

org/openxmlformats/schemas/spreadsheetml/x2006/main/CTWorkbook$Factory POI的问题 在操作Excel时,出现这个问题是因为缺少了poi-ooxml-schema jar包,并且与poi的jar包版本一致