STM32CUBEIDE FreeRTOS操作教程(六):recursive mutexes递归互斥信号量

news2024/10/12 14:52:30

STM32CUBEIDE FreeRTOS操作教程(六):recursive mutexes互斥信号量

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

递归互斥信号量是可以对单个信号量进行多次获取和释放的信号量,对于一个任务而言当然获取了多少次后就应该释放多少次,然后其它任务才能去获取改信号量。因为中断服务程序中不能应用阻塞时间,所以递归信号量不能用在中断服务程序中,也就是主要用在任务过程中。

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

STM32CUBEIDE工程配置

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

在这里插入图片描述

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

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

在这里插入图片描述

在这里插入图片描述

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_RcsMutex01Handle, USB_VCOM_xBlockTime);
    if(err_stu==pdTRUE)
    {
        if(USB_CONN_STATUS())
        {
        	usbprintstring("High Priority Task Outputting\r\n");
        }

        xSemaphoreGive(USB_VCOM_RcsMutex01Handle);
    }
  }
  /* 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_RcsMutex01Handle, USB_VCOM_xBlockTime); //First get

    if(err_stu==pdTRUE)
    {
    	xSemaphoreTakeRecursive(USB_VCOM_RcsMutex01Handle, USB_VCOM_xBlockTime);//Second get

        if(USB_CONN_STATUS())
        {
        	usbprintstring("Low Priority Task Outputting\r\n");
        }

        xSemaphoreGive(USB_VCOM_RcsMutex01Handle); //First release
        xSemaphoreGiveRecursive(USB_VCOM_RcsMutex01Handle); //Second release
        osDelay(10);

    }


  }
  /* 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 6: LED flash + Recursive 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_RcsMutex01 */
osMutexId_t USB_VCOM_RcsMutex01Handle;
const osMutexAttr_t USB_VCOM_RcsMutex01_attributes = {
  .name = "USB_VCOM_RcsMutex01",
  .attr_bits = osMutexRecursive,
};
/* 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 */
  PY_Delay_us_t(1000000);
  /* USER CODE END 2 */

  /* Init scheduler */
  osKernelInitialize();

  /* Create the recursive mutex(es) */
  /* creation of USB_VCOM_RcsMutex01 */
  USB_VCOM_RcsMutex01Handle = osMutexNew(&USB_VCOM_RcsMutex01_attributes);


  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  USB_VCOM_RcsMutex01Handle = xSemaphoreCreateRecursiveMutex(); //"USB_VCOM_RcsMutex01Handle = osMutexNew(&USB_VCOM_RcsMutex01_attributes);" is bad code. Redefine here.
  /* 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_RcsMutex01Handle, USB_VCOM_xBlockTime);
    if(err_stu==pdTRUE)
    {
        if(USB_CONN_STATUS())
        {
        	usbprintstring("Task 1 Outputting\r\n");
        }

        xSemaphoreGive(USB_VCOM_RcsMutex01Handle);
    }
  }
  /* 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_RcsMutex01Handle, USB_VCOM_xBlockTime); //First get

    if(err_stu==pdTRUE)
    {
    	xSemaphoreTakeRecursive(USB_VCOM_RcsMutex01Handle, USB_VCOM_xBlockTime);//Second get

        if(USB_CONN_STATUS())
        {
        	usbprintstring("Task 2 Outputting\r\n");
        }

        xSemaphoreGive(USB_VCOM_RcsMutex01Handle); //First release
        xSemaphoreGiveRecursive(USB_VCOM_RcsMutex01Handle); //Second release
        osDelay(10);

    }


  }
  /* 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操作教程(六):recursive mutexes递归互斥信号量 例程

例程测试

例程测试效果如下:

在这里插入图片描述

–End–

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

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

相关文章

【devops】x-ui 实现一键安装 x-ray 打造高速国际冲浪 | xray管理平台

一、部署X-UI篇 1、Github 地址&说明 github地址如下: https://github.com/FranzKafkaYu/x-ui?tabreadme-ov-file 2、一键部署 2.1、更新并安装curl #Ubuntu、Deibian系统 apt update && apt upgrade -y apt install curl -y #CentOS7 系统 yum…

深度解读企业数字化转型中的关键问题与解决方案

1. 数字优先的力量:如何通过文化变革推动企业迈向数字化未来 数字化转型的核心驱动力 数字优先策略是现代企业应对数字化转型挑战的关键,但其复杂性远超一般技术策略。企业通过将数字优先文化嵌入业务模型,可以在跨部门合作、运营优化和创新…

锐捷园区交换、无线领跑教育行业,以太彩光助力教育网络革新

IDC报告显示,2024年上半年,锐捷园区交换和无线在教育行业市场份额获双第一。 锐捷极简以太彩光:教育网络革新方案 以太彩光的技术创新,为教育数字化承载网络提供了更高效、稳定、简运维的前瞻性网络解决方案。2024年,锐捷极简以太全光3.X方案再次升级,同时支持光改、光混、彩光…

基于VHDL语言的乒乓游戏机电路的设计(毕业论文)

目录 1绪论 1 1.1课题的背景和目的意义 1 1.2国内外研究现状 2 1.3课题研究的内容和创新点 3 1.3.1 研究内容 3 1.3.2研究创新点 3 2开发工具简介 4 2.1 EDA技术概述 4 2.1.1 EDA技术及其发展 4 2.1.2 EDA技术的优势 4 2.1.3 EDA设计流程 5 2.1.4 EDA工具 5 2.1.5 EDA的发展趋势…

固体废物处理(一)——MDPI特刊推荐

特刊征稿 01 期刊名称: Advances in Organic Solid Waste and Wastewater Management 截止时间: 投稿截止日期:11月30日2024 目标及范围: 本主题旨在收集有关有机固体废物和废水管理最新进展的贡献。感兴趣的主题包括与废水…

专线监控方案:运维团队的实战指南

在当前的数字化时代,专线网络已成为企业连接各地分支机构、实现业务协同与数据共享的重要桥梁。然而,随着业务的不断扩展和网络环境的日益复杂,专线网络的稳定性和可靠性面临着前所未有的挑战。为了保障专线网络的顺畅运行,减少潜…

Ivanti Connect Secure SSRF to RCE复现(CVE-2024-21893)

0x01 产品描述: Ivanti Connect Secure是一款企业级远程访问解决方案,提供安全远程访问(VPN)、多因素认证等功能。Ivanti Connect Secure具备先进的零信任访问能力,包括验证用户、验证设备、控制访问和保护数据。它适用…

jupyterlab的安装与使用攻略/包括汉化方法

官网链接 Project Jupyter | Home 1.第一步安装 打开控制台 使用pip工具安装 pip install jupyterlab 如图 2.安装成功后启动 jupyter lab 会自动启动它的web页面 然后就可以正常使用咯!! 如果需要更换浏览器访问 新开控制台执行下面命令 jupy…

图论day59|并查集理论基础、107.寻找存在的路径(卡码网)

图论day59|并查集理论基础、107.寻找存在的路径(卡码网) 并查集理论基础107.寻找存在的路径(卡码网) 并查集理论基础 使用场景: 当需要判断两个元素是否在同一个集合里的时候,我们就要想到用并查集 主要功…

到 2029 年,人工智能驱动的电子商务欺诈将超过 1070 亿美元

随着人工智能生成的深度伪造产品的使用日益增多,电子商务欺诈行为急剧增加,给在线商家带来了前所未有的安全挑战。 研究公司 Juniper 的一份报告预测,全球损失将增加 141%,从 2024 年的 440 亿美元增至 2029 年的惊人的 1070 亿美…

Ubuntu安装Mysql并实现远程登录【ubuntu 24.04/mysql 8.0.39】

一、安装MySQL sudo apt update # 更新软件源 sudo apt install mysql-server -y # 安装 mysql --version # 查看版本 sudo systemctl status mysql # 查看运行状态 netstat -tln # 以数字ip形式显示mysql的tcp监听状态二、设置MySQL的root密码 sudo mysql -u root # 使…

【北京迅为】《STM32MP157开发板嵌入式开发指南》- 第176章 通过逻辑分析仪认识I2C波形

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7单核cortex-M4异构处理器,既可用Linux、又可以用于STM32单片机开发。开发板采用核心板底板结构,主频650M、1G内存、8G存储,核心板采用工业级板对板连接器,高可靠,牢固耐…

Win + R 快捷键

页面如下: 连接远程桌面(服务器) mstsc 打开计算机 calc 新建文本文档 notepad 设备管理器 wifi拉闸调驱动等 devmgmt.msc 计算机管理 调mysql服务等 compmgmt.msc 应用和程序 已安装应用查看、卸载 appwiz.cpl 注册表编辑器 鼠标右键菜单…

腾讯云SDK点播播放数据

点播播放质量监控提供点播播放全链路的数据统计、质量监控及可视化分析服务。支持实时数据上报、数据聚合、多维筛选和精细化定向分析,可帮助企业实时掌控大盘运营状况、了解用户习惯和行为特征,有效指导运营决策、驱动业务增长。 注意事项 点播播放质…

小红书日常实习一面凉经

小红书日常实习一面凉经 发面经,攒人品。 项目拷打: 1.实习中有没有对数据库表做强管控,听没听说过json schema。 2.Reactor响应式编程的基本原理。 3.黑名单功能为什么不用es去实现?你是基于怎样的考虑? 场景八股&am…

在使用商品详情 API 接口时需要注意什么?

在使用商品详情 API 接口时,需要注意以下几个方面: 一、API 使用规范方面 使用频率限制 许多 API 服务提供商都会对 API 的使用频率有所限制。这是为了防止某个用户过度使用 API 资源,影响其他用户的正常使用或者对服务器造成过大压力。例如…

移远通信受邀参展2024中国移动全球合作伙伴大会,以深厚实力全力迎接AI+时代

在中国科技迅速发展的今天,人工智能(AI)与物联网正在成为推动数字经济变革的重要力量。 为进一步推进AI技术与各领域的融合发展,10月11日至13日,第12届中国移动全球合作伙伴大会在广州市隆重举行,本次大会以…

merlion的dashboard打开方法

安装好merlion包后,在anaconda prompt中进行如下图操作: 先进入创建好的虚拟环境:conda activate merlion再执行命令:python -m merlion.dashboard在浏览器中手动打开图中的地址: http://127.0.0.1:8050 打开后的界面…

云手机与传统手机的区别是什么?

随着科技的快速进步,云手机逐渐成为手机市场的热门选择。与传统的智能手机相比,云手机具有许多独特的功能和优势,尤其在多账号管理和高效操作方面备受关注。那么,云手机究竟与普通手机有哪些区别呢? 1. 更灵活的操作与…

图片怎么转为pdf?1分钟学会图片转为pdf!

图片怎么转为pdf?在现今这个以视觉元素为核心的信息时代,图像已无缝嵌入我们的日常之中,从轻巧的智能手机显示屏到画质超清的大屏电视,各类图像素材犹如万花筒般绚烂多彩,广泛涉及摄影美学、创新设计、知识传播以及科研…