STM32CUBEIDE FreeRTOS操作教程(五):mutex互斥信号量

news2024/12/27 10:30:15

STM32CUBEIDE FreeRTOS操作教程(五):mutex互斥信号量

STM32CUBE开发环境集成了STM32 HAL库进行FreeRTOS配置和开发的组件,不需要用户自己进行FreeRTOS的移植。这里介绍最简化的用户操作类应用教程。以STM32F401RCT6开发板为例,只用到USB,USART1极少的接口,体现FreeRTOS的各种操作过程。
在这里插入图片描述
操作教程(五)配置FreeRTOS及相关环境,实现LED闪灯功能及基于mutex互斥信号量的USB虚拟串口双任务打印输出。两个任务轮流获取和释放互斥信号量,在得到信号量时向外打印输出。

FreeRTOS的教程较多,推荐参考正点原子所出的《STM32F407 FreeRTOS开发手册》了解相关知识。
在这里插入图片描述
在这里插入图片描述

STM32CUBEIDE工程配置

选择TIM1(也可以是其它TIM)作为FreeRTOS操作系统占用的时钟源:
在这里插入图片描述

在这里插入图片描述

配置时钟树包括USB的48MHz时钟:
在这里插入图片描述
配置PC13为低电平点灯的管脚:
在这里插入图片描述
配置USB串口:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
配置UART1串口(但本例中不用到UART1):
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

FreeRTOS配置

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

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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

在这里插入图片描述
保存并生成初始工程代码:
在这里插入图片描述
在生成代码的这个部分可以看到FreeRTOS代码部分:
在这里插入图片描述

任务实现

基于前述的配置,main.c代码里会加载Free-RTOS的配置,并启动几个任务的调度,当然,此时的任务都是什么也不干。实现LED闪灯,就在LED闪灯任务里加入代码即可:

void StartTask_TASK_LED_FLASH(void *argument)
{
  /* USER CODE BEGIN StartTask_TASK_LED_FLASH */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1000);
    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
  }
  /* USER CODE END StartTask_TASK_LED_FLASH */
}

也就实现了LED闪灯功能,其中osDelay(1000);实现1秒时间的操作系统调度延时,也就是1秒执行一次LED灯的亮灭。osDelay(1);是最小的调度延时,为1毫秒。要实现更小的延时,则可以用微秒延时函数实现,参考《STM32 HAL us delay(微秒延时)的指令延时实现方式及优化》

main.c文件里两个任务分别通过获取互斥信号量权柄,再发送信息:

void StartTask_TASK_USB_VCOM_H(void *argument)
{
  /* USER CODE BEGIN StartTask_TASK_USB_VCOM_H */
	BaseType_t err_stu = pdFALSE;
  /* Infinite loop */
  for(;;)
  {
    osDelay(8);
    err_stu = xSemaphoreTake(USB_VCOM_Mutex01Handle, USB_VCOM_xBlockTime);
    if(err_stu==pdTRUE)
    {
        if(USB_CONN_STATUS())
        {
        	usbprintstring("Task 1 Outputting\r\n");
        }

        xSemaphoreGive(USB_VCOM_Mutex01Handle);
    }
  }
  /* USER CODE END StartTask_TASK_USB_VCOM_H */
}

void StartTask_TASK_USB_VCOM_L(void *argument)
{
  /* USER CODE BEGIN StartTask_TASK_USB_VCOM_L */
	BaseType_t err_stu = pdFALSE;
  /* Infinite loop */
  for(;;)
  {
    osDelay(5);
    err_stu = xSemaphoreTake(USB_VCOM_Mutex01Handle, USB_VCOM_xBlockTime);
    if(err_stu==pdTRUE)
    {
        if(USB_CONN_STATUS())
        {
        	usbprintstring("Task 2 Outputting\r\n");
        }

        osDelay(10);
        xSemaphoreGive(USB_VCOM_Mutex01Handle);
    }


  }
  /* USER CODE END StartTask_TASK_USB_VCOM_L */
}

完整的main.c代码:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
//Example 5: LED flash + Mutex
//Written by Pegasus Yu
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "cmsis_os.h"
#include "usb_device.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "semphr.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
__IO float usDelayBase = 7.63238716; //For STM32F401RCT6 working in 84MHz main clock

void PY_Delay_us_t(uint32_t Delay)
{
  __IO uint32_t delayReg;
  __IO uint32_t usNum = (uint32_t)(Delay*usDelayBase);

  delayReg = 0;
  while(delayReg!=usNum) delayReg++;
}
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx;

/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
  .name = "defaultTask",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityNormal,
};
/* Definitions for TASK_LED_FLASH */
osThreadId_t TASK_LED_FLASHHandle;
const osThreadAttr_t TASK_LED_FLASH_attributes = {
  .name = "TASK_LED_FLASH",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityLow,
};
/* Definitions for TASK_UART1 */
osThreadId_t TASK_UART1Handle;
const osThreadAttr_t TASK_UART1_attributes = {
  .name = "TASK_UART1",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityLow,
};
/* Definitions for TASK_USB_VCOM_H */
osThreadId_t TASK_USB_VCOM_HHandle;
const osThreadAttr_t TASK_USB_VCOM_H_attributes = {
  .name = "TASK_USB_VCOM_H",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityHigh,
};
/* Definitions for TASK_USB_VCOM_L */
osThreadId_t TASK_USB_VCOM_LHandle;
const osThreadAttr_t TASK_USB_VCOM_L_attributes = {
  .name = "TASK_USB_VCOM_L",
  .stack_size = 128 * 4,
  .priority = (osPriority_t) osPriorityLow,
};
/* Definitions for USB_VCOM_Mutex01 */
osMutexId_t USB_VCOM_Mutex01Handle;
const osMutexAttr_t USB_VCOM_Mutex01_attributes = {
  .name = "USB_VCOM_Mutex01"
};
/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART1_UART_Init(void);
void StartDefaultTask(void *argument);
void StartTask_TASK_LED_FLASH(void *argument);
void StartTask_TASK_UART1(void *argument);
void StartTask_TASK_USB_VCOM_H(void *argument);
void StartTask_TASK_USB_VCOM_L(void *argument);

/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t USB_CONN_STATUS(void);
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len);
void usbprintstring(char * data)
{
	if(CDC_Transmit_FS((uint8_t *)data, strlen(data))==USBD_BUSY)
	{
		PY_Delay_us_t(1000000);
	    CDC_Transmit_FS((uint8_t *)data, strlen(data));
	}
}

void usbprintarray(uint8_t * data, uint16_t len)
{
	if(CDC_Transmit_FS(data, len)==USBD_BUSY)
	{
		PY_Delay_us_t(1000000);
		CDC_Transmit_FS(data, len);
	}
}

BaseType_t USB_VCOM_pxHigherPriorityTaskWaken;
TickType_t USB_VCOM_xBlockTime = 0;
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Init scheduler */
  osKernelInitialize();
  /* Create the mutex(es) */
  /* creation of USB_VCOM_Mutex01 */
  USB_VCOM_Mutex01Handle = osMutexNew(&USB_VCOM_Mutex01_attributes);

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */

  /* Create the thread(s) */
  /* creation of defaultTask */
  defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);

  /* creation of TASK_LED_FLASH */
  TASK_LED_FLASHHandle = osThreadNew(StartTask_TASK_LED_FLASH, NULL, &TASK_LED_FLASH_attributes);

  /* creation of TASK_UART1 */
  TASK_UART1Handle = osThreadNew(StartTask_TASK_UART1, NULL, &TASK_UART1_attributes);

  /* creation of TASK_USB_VCOM_H */
  TASK_USB_VCOM_HHandle = osThreadNew(StartTask_TASK_USB_VCOM_H, NULL, &TASK_USB_VCOM_H_attributes);

  /* creation of TASK_USB_VCOM_L */
  TASK_USB_VCOM_LHandle = osThreadNew(StartTask_TASK_USB_VCOM_L, NULL, &TASK_USB_VCOM_L_attributes);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */

  /* USER CODE BEGIN RTOS_EVENTS */
  /* add events, ... */
  /* USER CODE END RTOS_EVENTS */

  /* Start scheduler */
  osKernelStart();

  /* We should never get here as control is now taken by the scheduler */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 25;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief USART1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

/**
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void)
{

  /* DMA controller clock enable */
  __HAL_RCC_DMA2_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA2_Stream2_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 5, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : LED_Pin */
  GPIO_InitStruct.Pin = LED_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/* USER CODE BEGIN Header_StartDefaultTask */
/**
  * @brief  Function implementing the defaultTask thread.
  * @param  argument: Not used
  * @retval None
  */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
  /* init code for USB_DEVICE */
  MX_USB_DEVICE_Init();
  /* USER CODE BEGIN 5 */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END 5 */
}

/* USER CODE BEGIN Header_StartTask_TASK_LED_FLASH */
/**
* @brief Function implementing the TASK_LED_FLASH thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask_TASK_LED_FLASH */
void StartTask_TASK_LED_FLASH(void *argument)
{
  /* USER CODE BEGIN StartTask_TASK_LED_FLASH */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1000);
    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
  }
  /* USER CODE END StartTask_TASK_LED_FLASH */
}

/* USER CODE BEGIN Header_StartTask_TASK_UART1 */
/**
* @brief Function implementing the TASK_UART1 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask_TASK_UART1 */
void StartTask_TASK_UART1(void *argument)
{
  /* USER CODE BEGIN StartTask_TASK_UART1 */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END StartTask_TASK_UART1 */
}

/* USER CODE BEGIN Header_StartTask_TASK_USB_VCOM_H */
/**
* @brief Function implementing the TASK_USB_VCOM_H thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask_TASK_USB_VCOM_H */
void StartTask_TASK_USB_VCOM_H(void *argument)
{
  /* USER CODE BEGIN StartTask_TASK_USB_VCOM_H */
	BaseType_t err_stu = pdFALSE;
  /* Infinite loop */
  for(;;)
  {
    osDelay(8);
    err_stu = xSemaphoreTake(USB_VCOM_Mutex01Handle, USB_VCOM_xBlockTime);
    if(err_stu==pdTRUE)
    {
        if(USB_CONN_STATUS())
        {
        	usbprintstring("Task 1 Outputting\r\n");
        }

        xSemaphoreGive(USB_VCOM_Mutex01Handle);
    }
  }
  /* USER CODE END StartTask_TASK_USB_VCOM_H */
}

/* USER CODE BEGIN Header_StartTask_TASK_USB_VCOM_L */
/**
* @brief Function implementing the TASK_USB_VCOM_L thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask_TASK_USB_VCOM_L */
void StartTask_TASK_USB_VCOM_L(void *argument)
{
  /* USER CODE BEGIN StartTask_TASK_USB_VCOM_L */
	BaseType_t err_stu = pdFALSE;
  /* Infinite loop */
  for(;;)
  {
    osDelay(5);
    err_stu = xSemaphoreTake(USB_VCOM_Mutex01Handle, USB_VCOM_xBlockTime);
    if(err_stu==pdTRUE)
    {
        if(USB_CONN_STATUS())
        {
        	usbprintstring("Task 2 Outputting\r\n");
        }

        osDelay(10);
        xSemaphoreGive(USB_VCOM_Mutex01Handle);
    }


  }
  /* USER CODE END StartTask_TASK_USB_VCOM_L */
}

/**
  * @brief  Period elapsed callback in non blocking mode
  * @note   This function is called  when TIM1 interrupt took place, inside
  * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
  * a global variable "uwTick" used as application time base.
  * @param  htim : TIM handle
  * @retval None
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* USER CODE BEGIN Callback 0 */

  /* USER CODE END Callback 0 */
  if (htim->Instance == TIM1) {
    HAL_IncTick();
  }
  /* USER CODE BEGIN Callback 1 */

  /* USER CODE END Callback 1 */
}

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

例程下载

STM32 STM32CUBEIDE FreeRTOS操作教程(五):mutex互斥信号量 例程

例程测试

例程测试效果如下:
在这里插入图片描述

–End–

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

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

相关文章

个人网站介绍和部署(开源)

前言: 大家好,我是神的孩子都在歌唱,这是我csdn的博客 , 这是我做的一个神唱网站项目,专门是为了满足自己的需求写的,需要什么就做什么,代码完全开源github,含有安装部署教程,此项目…

Geekbench6使用指南:Linux系统性能测试,如此简单!

在当今计算机性能日益重要的时代,Geekbench 成为了测试 CPU 性能的热门工具。本文将带你深入了解如何使用 Geekbench,让你的电脑性能一目了然。 1. 什么是 Geekbench? Geekbench 是一款跨平台的基准测试工具,能够评估单核和多核…

避免glibc版本而报错,CentOS等Linux安装node.js完美方法

概述 对于Node.js v18.x或更高,Node.js官方默认是在Ubuntu 20.04, Debian 10, RHEL 8,CentOS 8等高版操作系统上编译得到的,高版本操作系统的glibc版本≥2.28。所以,下载Node.js后,也需要glibc版本≥2.28才能使用。 而CentOS 7.x等…

【YOLOv10改进[SPPF]】使用 v9的SPPELAN替换SPPF模块 + 含全部代码和详细修改方式

本文将进行在YOLOv10中使用SPPELAN改进v10 的实践,助力YOLOv10目标检测效果,文中含全部代码、详细修改方式。助您轻松理解改进的方法。 改进前和改进后的参数对比如下: 目录 一 YOLOV9 二 使用SPPELAN改进v10的实践 1 整体修改 ① 添加SPPELAN.py文件

入选ECCV 2024!覆盖5.4w+图像,MIT提出医学图像分割通用模型ScribblePrompt,性能优于SAM

外行看热闹,内行看门道,这句话在医学影像领域可谓是绝对真理。不仅如此,即便身为内行人,要想在复杂的 X 光片、CT 光片或 MRI 等医学影像上准确看出些「门道」来,也并非易事。而医学图像分割则是通过将复杂的医学图像中…

双十一有什么推荐好物?,这些你不能错过的宝藏好物推荐

随着双十一的临近,这场盛大的购物狂欢蓄势待发!为了让大家不在琳琅满目的商品中徘徊,琪琪用心归纳了一份购物清单,分享那些我亲自使用过,觉得必须拥有的商品。 这些商品不仅价格公道,而且质量上乘&#xf…

如何在iPad上用Chrome实现无痕浏览

在数字化时代,隐私保护已成为我们日常生活中不可忽视的一部分。特别是在使用移动设备浏览网页时,如何确保个人信息的安全显得尤为重要。本文将详细介绍如何在iPad上使用Chrome浏览器实现无痕浏览,以保护您的在线隐私。 (本文由ht…

SpringBoot使用validation进行自参数校验

一:介绍 在 SpringBoot 项目开发中,很多与数据库交互的参数需要校验数据正确性。很多小伙伴会把参数判断写进代码里,但是这种写法往往会有低可读性以及多处使用的时候,需要变更验证规则时,不易于维护等缺点。今天给大家…

数据工程师岗位常见面试问题-1(附回答)

数据工程师已成为科技行业最重要的角色之一,是组织构建数据基础设施的骨干。随着企业越来越依赖数据驱动的决策,对成熟数据工程师的需求会不断上升。如果您正在准备数据工程师面试,那么应该掌握常见的数据工程师面试问题:包括工作…

怎么禁止电脑随意安装软件?

1、使用组策略编辑器(适用于Windows专业版及更高版本): 打开运行窗口(Win R),输入gpedit.msc并回车,打开组策略编辑器。 导航至“计算机配置” -> “管理模板” -> “Windows组件” -&…

Python(六)-拆包,交换变量名,lambda

目录 拆包 交换变量值 引用 lambda函数 lambda实例 字典的lambda 推导式 列表推导式 列表推导式if条件判断 for循环嵌套列表推导式 字典推导式 集合推导式 拆包 看一下在Python程序中的拆包:把组合形成的元组形式的数据,拆分出单个元素内容…

微服务SpringGateway解析部署使用全流程

官网地址: Spring Cloud Gateway 1、SpringGateway简介 核心功能有三个: 路由:用于设置转发地址的 断言:用来判断真实应该请求什么地址 过滤器:可以过滤地址和处理参数 1、什么是网关 网关是后台服务的统一入口…

如何排查 Windows 无法连接ubuntu远程服务器

当本机连接不上远程服务器,排查问题的思路是确保本机和远程的 sshd 服务都没有问题。 为什么要写这篇文章,一是记录防止忘记,另一方面是 gpt 给的方案太宽泛,需要自己逐一排查。而我们自己遇到的问题多半是有上下文的。这些上下文…

H. Sakurako‘s Test

H. Sakurakos Test 原题 本题通过前缀和和二分可以解决, 原理并不是很困难, 但是比较难想到 我们只需要对每一个 x, 二分求出中位数, 预处理好即可, 二分的检查通过求k倍的x可以在调和级数的时间内实现 代码 #include <bits/stdc.h> #define int long longusing name…

若依 Vue3 前端分离 3.8.8 版实现去除首页,登录后跳转至动态路由的第一个路由的页面

一、前言 某些项目可能并不需要首页&#xff0c;但在若依中想要实现不显示首页&#xff0c;并根据不同角色登录后跳转至该角色的第一个动态路由的页面需要自己实现&#xff0c;若依中没有实现该功能的特定代码。 二、代码 1. src\permission.js 在 src\permission.js 中添加…

无限大薄板的电场

单块无限大薄板两端的电场 单块无限大的薄板&#xff0c;如果上面带有均匀分布的电荷&#xff0c;就会在薄板的两侧产生电场&#xff0c;电场大小与距离平板的位置无关&#xff0c;方向与平板垂直&#xff0c;如果平板带正电荷&#xff0c;则电场方向向外指向两侧&#xff0c;…

spring第一个入门框架

创建一个项目文件 创建一个module 配置pom文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation&quo…

深入理解 Java 中的 Switch 语句

深入理解 Java 中的 Switch 语句 在 Java 编程中&#xff0c;switch 语句是一种强大的控制结构&#xff0c;能够根据表达式的值选择执行不同的代码块。本文将详细介绍 switch 的基本语法、使用案例、注意事项以及与 if 语句的选择。 基本语法 switch 语句的基本语法如下&#…

【漏洞复现】数字通云平台智慧政务 login 存在登录绕过漏洞

》》》产品描述《《《 数字通云平台智慧政务OA产品是基于云计算、大数据、人工智能等先进技术&#xff0c;为政府部门量身定制的智能化办公系统。该系统旨在提高政府部门的办公效率、协同能力和信息资源共享水平&#xff0c;推动电子政务向更高层次发展。 》》》漏洞描述《《《…

excel|获取一段时间内每日数据的条数

工作中经常需要统计一段时间内每日数据的条数&#xff0c;用于计算每日的销售单数或传播数等等 一、将日期列提取出来 二、在右侧一列&#xff0c;填入1&#xff0c;进行标记&#xff0c;crtld快速填充 三、创建数据透视表 选定区域 四、进行数据分析 五、得到结果