当前位置: 首页 > news >正文

02.FreeRTOS的移植

文章目录

  • FreeRTOS移植到STM32F103ZET6上的详细步骤
    • 1. 移植前的准备工作
    • 2. 添加FreeRTOS文件
    • 3. 修改SYSTEM文件
    • 4. 修改中断相关文件
    • 5. 修改FreeRTOSConfig.h文件
    • 6. 可选步骤

FreeRTOS移植到STM32F103ZET6上的详细步骤

1. 移植前的准备工作

  • **基础工程:**内存管理部分的例程源码和基本定时器的例程源码
    在这里插入图片描述

    使用实验8 基本定时器和实验36 内存管理两个实验,内存管理实验做为移植的目标文件,为了获得定时器的功能,需要把基本定时器实验部分的TIMER文件夹拷贝到内存管理实验的BSP文件夹里面。

  • FreeRTOS源码:

    本例程使用的是FreeRTOS内核源码的版本V10.4.6,即FreeRTOS v2021.00。获取路径:软件资料→FreeRTOS学习资料→FreeRTOSv2202112.00.zip。
    在这里插入图片描述

2. 添加FreeRTOS文件

  1. 添加FreeRTOS源码,在基础工程的Middlewares文件夹中新建一个FreeRTOS子文件夹:
    在这里插入图片描述

    将FreeRTOS内核源码的 Source 文件夹下的所有文件添加到工程的 FreeRTOS 文件夹中:
    在这里插入图片描述

  2. 将文件添加到工程

    打开基础工程,新建两个文件分组,分别为Middlewares/FreeRTOS_COREMiddlewares/FreeRTOS_PORT

    Middlewares/FreeRTOS_CORE:存放FreeRTOS内核C源码文件

    Middlewares/FreeRTOS_PORT:存放FreeRTOS内核的移植文件,分别添加heap_x.cport.c
    在这里插入图片描述

    然后把相关文件拷贝到这两个路径下:
    在这里插入图片描述

    1. 添加头文件路径

      一个是FreeRTOS/include,另一个是port.c的路径

      在这里插入图片描述

    2. 添加FreeRTOSConfig.h文件

      因为需要对配置文件进行裁剪并且要结合STM32单片机,我们直接从移植好的例程里面拷贝即可

      在这里插入图片描述

3. 修改SYSTEM文件

  1. sys.h文件

    sys.h文件的修改很简单,在sys.h文件中使用了宏SYS SUPPORT_OS来定义是否支持OS,因为要支持FreeRTOS,因此应当将宏SYS SUPPORT_OS定义为1,具体修改如下所示:

    修改前:

    /*** SYS_SUPPORT_OS用于定义系统文件夹是否支持OS* 0,不支持OS* 1,支持OS*/
    #define SYS_SUPPORT_OS          0
    

    修改后:

    /*** SYS_SUPPORT_OS用于定义系统文件夹是否支持OS* 0,不支持OS* 1,支持OS*/
    #define SYS_SUPPORT_OS          1
  2. usart.c文件

    usart.c文件的修改也很简单,一共有两个地方需要修改,首先就是串口的中断服务函数,原本在使用uCOS的时候,进入和退出中断需要添加OSIntEnter()和OSIntExit()两个函数,这是uCOS对于中断的相关处理机制,而FreeRTOS中并没有这种机制,因此将这两行代码删除,修改后串口的中断服务函数如下所示:

    修改前:

    void USART_UX_IRQHandler(void)
    {
    #if SYS_SUPPORT_OS                          /* 使用OS */OSIntEnter();    
    #endifHAL_UART_IRQHandler(&g_uart1_handle);   /* 调用HAL库中断处理公用函数 */#if SYS_SUPPORT_OS                          /* 使用OS */OSIntExit();
    #endif}
    

    修改后:

    void USART_UX_IRQHandler(void)
    {HAL_UART_IRQHandler(&g_uart1_handle);   /* 调用HAL库中断处理公用函数 */while (HAL_UART_Receive_IT( &g_uart1_handle,(uint8_t *)g_rx_buffer,RXBUFFERSIZE) != HAL_OK)/* 重新开启中断并接收数据 */{/* 如果出错会卡死在这里 */}}
    

    接下来usart.c要修改的第二个地方就是导入的头文件,因为在串口的中断服务函数当中已经删除了uCOS的相关代码,并且也没有使用到FreeRTOS的相关代码,因此将usart.c中包含的关于OS的头文件删除,要删除的代码如下所示:

    /* 如果使用 os,则包括下面的头文件即可. */
    #if SYS_SUPPORT_OS
    #include "includes.h" /* os 使用 */
    #endif
    
  3. delay.c文件

    (1)删除适用于 µC/OS 但不适用于 FreeRTOS 的相关代码

    /* 定义 g_fac_ms 变量, 表示 ms 延时的倍乘数,
    * 代表每个节拍的 ms 数, (仅在使能 os 的时候,需要用到)
    */
    static uint16_t g_fac_ms = 0;
    /*
    * 当 delay_us/delay_ms 需要支持 OS 的时候需要三个与 OS 相关的宏定义和函数来支持
    * 首先是 3 个宏定义:
    * delay_osrunning :用于表示 OS 当前是否正在运行,以决定是否可以使用相关函数
    * delay_ostickspersec :用于表示 OS 设定的时钟节拍,
    * delay_init 将根据这个参数来初始化 systick
    * delay_osintnesting :用于表示 OS 中断嵌套级别,因为中断里面不可以调度,
    * delay_ms 使用该参数来决定如何运行
    * 然后是 3 个函数:
    * delay_osschedlock :用于锁定 OS 任务调度,禁止调度
    * delay_osschedunlock :用于解锁 OS 任务调度,重新开启调度
    * delay_ostimedly :用于 OS 延时,可以引起任务调度.
    * 
    * 本例程仅作 UCOSII 和 UCOSIII 的支持,其他 OS,请自行参考着移植
    */
    /* 支持 UCOSII */
    #ifdef OS_CRITICAL_METHOD /* OS_CRITICAL_METHOD 定义了* 说明要支持 UCOSII*/
    #define delay_osrunning OSRunning /* OS 是否运行标记,0,不运行;1,在运行 */
    #define delay_ostickspersec OS_TICKS_PER_SEC /* OS 时钟节拍,即每秒调度次数 */
    #define delay_osintnesting OSIntNesting /* 中断嵌套级别,即中断嵌套次数 */
    #endif
    /* 支持 UCOSIII */
    #ifdef CPU_CFG_CRITICAL_METHOD /* CPU_CFG_CRITICAL_METHOD 定义了* 说明要支持 UCOSIII*/
    #define delay_osrunning OSRunning /* OS 是否运行标记,0,不运行;1,在运行 */
    #define delay_ostickspersec OSCfg_TickRate_Hz /* OS 时钟节拍,即每秒调度次数 */
    #define delay_osintnesting OSIntNestingCtr /* 中断嵌套级别,即中断嵌套次数 */
    #endif
    /**
    * @brief us 级延时时,关闭任务调度(防止打断 us 级延迟)
    * @param 无
    * @retval 无
    */
    static void delay_osschedlock(void)
    {
    #ifdef CPU_CFG_CRITICAL_METHOD /* 使用 UCOSIII */OS_ERR err;OSSchedLock(&err); /* UCOSIII 的方式,禁止调度,防止打断 us 延时 */
    #else /* 否则 UCOSII */OSSchedLock(); /* UCOSII 的方式,禁止调度,防止打断 us 延时 */
    #endif
    }
    /**
    * @brief us 级延时时,恢复任务调度
    * @param 无
    * @retval 无
    */
    static void delay_osschedunlock(void)
    {
    #ifdef CPU_CFG_CRITICAL_METHOD /* 使用 UCOSIII */OS_ERR err;OSSchedUnlock(&err); /* UCOSIII 的方式,恢复调度 */
    #else /* 否则 UCOSII */OSSchedUnlock(); /* UCOSII 的方式,恢复调度 */
    #endif
    }
    /**
    * @brief us 级延时时,恢复任务调度
    * @param ticks: 延时的节拍数
    * @retval 无
    */
    static void delay_ostimedly(uint32_t ticks)
    {
    #ifdef CPU_CFG_CRITICAL_METHODOS_ERR err;OSTimeDly(ticks, OS_OPT_TIME_PERIODIC, &err); /* UCOSIII 延时采用周期模式 */
    #elseOSTimeDly(ticks); /* UCOSII 延时 */
    #endif
    }
    

    (2)添加 FreeRTOS 的相关代码

    只需要在delay.c文件中使用 extern关键字导入一个FreeRTOS函数一 xPortSysTickHandler()即可,这个函数是用于处理FreeRTOS系统时钟节拍的,本教程是使用 SysTick作为FreeRTOS操作系统的心跳,因此需要在SysTick的中断服务函数中调用这个函数,因此将代码添加到SysTick中断服务函数之前,代码修改如下:

    extern void xPortSysTickHandler(void);
    

    (3)修改部分内容

    最后要修改的内容包括两个,分别是包含头文件和 4 个函数。

    包含头文件:

    //修改前:
    #include "includes.h"
    //修改后: 
    #include "FreeRTOS.h"
    #include "task.h"
    

    4个函数:

    (1) SysTick_Handler()

    修改前:

    void SysTick_Handler(void)
    {/* OS 开始跑了,才执行正常的调度处理 */if (delay_osrunning == OS_TRUE){/* 调用 uC/OS-II 的 SysTick 中断服务函数 */OS_CPU_SysTickHandler();}HAL_IncTick();
    }
    

    修改后:

    void SysTick_Handler(void)
    {HAL_IncTick();if(xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED){xPortSysTickHandler();}
    }
    

    (2) delay_init()

    修改前:

    void delay_init(uint16_t sysclk)
    {
    #if SYS_SUPPORT_OS                                      /* 如果需要支持OS */uint32_t reload;
    #endifg_fac_us = sysclk;                                  /* 由于在HAL_Init中已对systick做了配置,所以这里无需重新配置 */
    #if SYS_SUPPORT_OS                                      /* 如果需要支持OS. */reload = sysclk;                                    /* 每秒钟的计数次数 单位为M */reload *= 1000000 / delay_ostickspersec;            /* 根据delay_ostickspersec设定溢出时间,reload为24位* 寄存器,最大值:16777216,在168M下,约合0.09986s左右*/g_fac_ms = 1000 / delay_ostickspersec;              /* 代表OS可以延时的最少单位 */SysTick->CTRL |= 1 << 1;                            /* 开启SYSTICK中断 */SysTick->LOAD = reload;                             /* 每1/delay_ostickspersec秒中断一次 */SysTick->CTRL |= 1 << 0;                            /* 开启SYSTICK */
    #endif 
    }
    

    修改后:

    void delay_init(uint16_t sysclk)
    {
    #if SYS_SUPPORT_OS                                      /* 如果需要支持OS */uint32_t reload;
    #endifSysTick->CTRL = 0;HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8);g_fac_us = sysclk / 8;                                  /* 由于在HAL_Init中已对systick做了配置,所以这里无需重新配置 */#if SYS_SUPPORT_OS                                      /* 如果需要支持OS. */reload = sysclk / 8;                                    /* 每秒钟的计数次数 单位为M */reload *= 1000000 / configTICK_RATE_HZ;            /* 根据delay_ostickspersec设定溢出时间,reload为24位* 寄存器,最大值:16777216,在168M下,约合0.09986s左右*/             /* 代表OS可以延时的最少单位 */SysTick->CTRL |= 1 << 1;                            /* 开启SYSTICK中断 */SysTick->LOAD = reload;                             /* 每1/delay_ostickspersec秒中断一次 */SysTick->CTRL |= 1 << 0;                            /* 开启SYSTICK */
    #endif 
    }
    

    (3) delay_us()

    修改前:

    void delay_us(uint32_t nus)
    {uint32_t ticks;uint32_t told, tnow, tcnt = 0;uint32_t reload = SysTick->LOAD;        /* LOAD的值 */ticks = nus * g_fac_us;                 /* 需要的节拍数 */#if SYS_SUPPORT_OS                          /* 如果需要支持OS */delay_osschedlock();                    /* 锁定 OS 的任务调度器 */
    #endiftold = SysTick->VAL;                    /* 刚进入时的计数器值 */while (1){tnow = SysTick->VAL;if (tnow != told){if (tnow < told){tcnt += told - tnow;        /* 这里注意一下SYSTICK是一个递减的计数器就可以了 */}else{tcnt += reload - tnow + told;}told = tnow;if (tcnt >= ticks) {break;                      /* 时间超过/等于要延迟的时间,则退出 */}}}#if SYS_SUPPORT_OS                          /* 如果需要支持OS */delay_osschedunlock();                  /* 恢复 OS 的任务调度器 */
    #endif }
    

    修改后:

    void delay_us(uint32_t nus)
    {uint32_t ticks;uint32_t told, tnow, tcnt = 0;uint32_t reload = SysTick->LOAD;        /* LOAD的值 */ticks = nus * g_fac_us;                 /* 需要的节拍数 */told = SysTick->VAL;                    /* 刚进入时的计数器值 */while (1){tnow = SysTick->VAL;if (tnow != told){if (tnow < told){tcnt += told - tnow;        /* 这里注意一下SYSTICK是一个递减的计数器就可以了 */}else{tcnt += reload - tnow + told;}told = tnow;if (tcnt >= ticks) {break;                      /* 时间超过/等于要延迟的时间,则退出 */}}}
    }
    

    (4) delay_ms()

    修改前:

    void delay_ms(uint16_t nms)
    {#if SYS_SUPPORT_OS  /* 如果需要支持OS, 则根据情况调用os延时以释放CPU */if (delay_osrunning && delay_osintnesting == 0)     /* 如果OS已经在跑了,并且不是在中断里面(中断里面不能任务调度) */{if (nms >= g_fac_ms)                            /* 延时的时间大于OS的最少时间周期 */{delay_ostimedly(nms / g_fac_ms);            /* OS延时 */}nms %= g_fac_ms;                                /* OS已经无法提供这么小的延时了,采用普通方式延时 */}
    #endifdelay_us((uint32_t)(nms * 1000));                   /* 普通方式延时 */
    }
    

    修改后:

    void delay_ms(uint16_t nms)
    {uint32_t i;for(i=0; i<nms; i++){delay_us(1000);}
    }
    

4. 修改中断相关文件

FreeRTOS系统时基定时器的中断(SysTick中断)SVC中断PendSV中断
SysTick的中断服务函数在delay.c文件中已经定义了,并且FreeRTOS也提供了SVC和PendSV的中断服务函数,因此需要将HAL库提供的这三个中断服务函数注释掉,这里采用宏开关的方式让HAL库中的这三个中断服务函数不加入编译,使用的宏在sys.h中定义,因此还需要导入Sysh头文件,请读者按照表2.1.4.1找到对应的文件进行修改,修改后的代码如下所示:

/* 导入 sys.h 头文件 */
#include "./SYSTEM/SYS/sys.h"/* 加入宏开关 */
#if (!SYS_SUPPORT_OS)
void SVC_Handler(void)
{
}
#endif#if (!SYS_SUPPORT_OS)
void PendSV_Handler(void)
{
}
#endif#if (!SYS_SUPPORT_OS)
void SysTick_Handler(void)
{HAL_IncTick();
}
#endif

5. 修改FreeRTOSConfig.h文件

FreeRTOSConfig.h

#define   configPRIO_BITS   __NVIC_PRIO_BITS

stm32f103xe.h文件中修改:

#define __NVIC_PRIO_BITS   4U

为:

#define __NVIC_PRIO_BITS   4

在这里插入图片描述

6. 可选步骤

  1. 修改工程目标名称:

    本教程是以标准例程-HAL库版本的内存管理实验工程为基础工程,内存管理实验工程的工程日标名为“MALLOC”,为了规范工程,笔者建议将工程目标名修改为“FreeRTOS”或根据读者的实际场景进行修改,修改如下图所示:
    在这里插入图片描述

  2. 移出USMART调试组件:

    由于本教程并未使用到USMART调试组件,因此建议将USMART调试组件从工程中移除,如果读者需要使用USMART调试组件的话,也可选择保留,移除USAMRT调试组建后工程文件分组如下图所示(这里以正点原子的STM32F1系列开发板为例,其他开发板类似),修改后文件组为:
    在这里插入图片描述

  3. 添加定时器驱动:

    由于在后续的实验中需要使用到$TM32的基本定时器外设,因此需要向工程中添加定时器的相关驱动文件,读者也可在后续实验需要用到定时器的时候再进行添加。将定时器的相关驱动文件添加到工程的Drivers/BSP文件分组中,如下图所示(这里以正点原子的STM32F1系列开发板为例,其他开发板类似):
    )
    在这里插入图片描述

  4. 添加应用程序:

    添加freertos_demo.cfreertos_demo.h测试文件,对于 main.c 主要是在main()函数中完成一些硬件的初始化,最后调用 freertos_demo.c文件中的freertos_demo()函数。

    main.c

    #include "./SYSTEM/sys/sys.h"
    #include "./SYSTEM/usart/usart.h"
    #include "./SYSTEM/delay/delay.h"
    #include "./BSP/LED/led.h"
    #include "./BSP/LCD/lcd.h"
    #include "./BSP/KEY/key.h"
    #include "./BSP/SRAM/sram.h"
    #include "./MALLOC/malloc.h"
    #include "freertos_demo.h"const char *SRAM_NAME_BUF[SRAMBANK] = {" SRAMIN ", " SRAMEX "};int main(void)
    {HAL_Init();                             /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */delay_init(72);                         /* 延时初始化 */usart_init(115200);                     /* 串口初始化为115200 */led_init();                             /* 初始化LED */lcd_init();                             /* 初始化LCD */key_init();                             /* 初始化按键 */sram_init();                            /* SRAM初始化 */my_mem_init(SRAMIN);                    /* 初始化内部SRAM内存池 */my_mem_init(SRAMEX);                    /* 初始化外部SRAM内存池 */lcd_show_string(30,  50, 200, 16, 16, "YIZHI successed", RED);freertos_demo();
    }
    

    freertos_demo.c

    #include "freertos_demo.h"
    #include "./SYSTEM/usart/usart.h"
    #include "./BSP/LED/led.h"
    #include "./BSP/LCD/lcd.h"#include "FreeRTOS.h"
    #include "task.h"#define START_TASK_PRIO 1                   // 任务优先级 
    #define START_STK_SIZE  128                 // 任务堆栈大小 
    TaskHandle_t            StartTask_Handler;  // 任务句柄 
    void start_task(void *pvParameters);        // 任务函数 #define TASK1_PRIO      2                   // 任务优先级 
    #define TASK1_STK_SIZE  128                 // 任务堆栈大小 
    TaskHandle_t            Task1Task_Handler;  // 任务句柄 
    void task1(void *pvParameters);             // 任务函数 #define TASK2_PRIO      3                   // 任务优先级 
    #define TASK2_STK_SIZE  128                 // 任务堆栈大小 
    TaskHandle_t            Task2Task_Handler;  // 任务句柄 
    void task2(void *pvParameters);             // 任务函数 /*创建开始任务*/
    void freertos_demo(void)
    {   xTaskCreate((TaskFunction_t )start_task,            // 任务函数 (const char*    )"start_task",          // 任务名称 (uint16_t       )START_STK_SIZE,        // 任务堆栈大小 (void*          )NULL,                  // 传入给任务函数的参数 (UBaseType_t    )START_TASK_PRIO,       // 任务优先级 (TaskHandle_t*  )&StartTask_Handler);   // 任务句柄 vTaskStartScheduler();
    }/*创建两任务1和任务2*/
    void start_task(void *pvParameters)
    {taskENTER_CRITICAL();           // 进入临界区 // 创建任务1 xTaskCreate((TaskFunction_t )task1,(const char*    )"task1",(uint16_t       )TASK1_STK_SIZE,(void*          )NULL,(UBaseType_t    )TASK1_PRIO,(TaskHandle_t*  )&Task1Task_Handler);// 创建任务2 xTaskCreate((TaskFunction_t )task2,(const char*    )"task2",(uint16_t       )TASK2_STK_SIZE,(void*          )NULL,(UBaseType_t    )TASK2_PRIO,(TaskHandle_t*  )&Task2Task_Handler);vTaskDelete(StartTask_Handler); // 删除开始任务 taskEXIT_CRITICAL();            // 退出临界区 
    }/*任务一: LED0闪烁*/
    void task1(void *pvParameters)
    {  while(1){LED0_TOGGLE();                                                  vTaskDelay(1000);   //延时1000ticks }
    }/*任务二: LED1闪烁*/
    void task2(void *pvParameters)
    {  while(1){LED1_TOGGLE();vTaskDelay(500);    //延时500ticks }
    }
    

    freertos_demo.h

    #ifndef __FREERTOS_DEMO_H
    #define __FREERTOS_DEMO_Hvoid freertos_demo(void);#endif
    

相关文章:

02.FreeRTOS的移植

文章目录 FreeRTOS移植到STM32F103ZET6上的详细步骤1. 移植前的准备工作2. 添加FreeRTOS文件3. 修改SYSTEM文件4. 修改中断相关文件5. 修改FreeRTOSConfig.h文件6. 可选步骤 FreeRTOS移植到STM32F103ZET6上的详细步骤 1. 移植前的准备工作 **基础工程&#xff1a;**内存管理部…...

【个人笔记】一个例子理解工厂模式

工厂模式优点&#xff1a;创建时类名过长或者参数过多或者创建很麻烦等情况时用&#xff0c;可以减少重复代码&#xff0c;简化对象的创建过程&#xff0c;避免暴露创建逻辑&#xff0c;也适用于需要统一管理所有创建对象的情况&#xff0c;比如线程池的工厂类Executors 简单工…...

【C语言】数组栈的实现

栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 压栈&#…...

kafka 各种选举过程

一、kafka 消费者组协调器 如何选举 Kafka 中的消费者组协调器&#xff08;Group Coordinator&#xff09;是通过以下步骤选举的&#xff1a; 分区映射&#xff1a; Kafka 使用一个特殊的内部主题 __consumer_offsets 来存储消费者组的元数据。该主题有多个分区&#xff0c;每…...

树与二叉树【数据结构】

前言 之前我们已经学习过了各种线性的数据结构&#xff0c;顺序表、链表、栈、队列&#xff0c;现在我们一起来了解一下一种非线性的结构----树 1.树的结构和概念 1.1树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一…...

简单几步,把浏览器书签转换成导航网页

废话不多说直奔主题上干货 Step 1 下载浏览器书签 1&#xff0c;电脑浏览器点击下载Pintree Pintree 是一个开源项目&#xff0c;旨在将浏览器书签导出成导航网站。通过简单的几步操作&#xff0c;就可以将你的书签转换成一个美观且易用的导航页面。 2. 安装 Pintree B…...

Mac安装Hoomebrew与升级Python版本

参考 mac 安装HomeBrew(100%成功)_mac安装homebrew-CSDN博客 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 安装了Python 3.x版本&#xff0c;你可以使用以下命令来设置默认的Python版本&#xff1a; # 首先找到新安…...

代码审计:Bluecms v1.6

代码审计&#xff1a;Bluecms v1.6 漏洞列表如下(附Exp)&#xff1a; 未完待续… 1、include/common.fun.php->getip()存在ip伪造漏洞 2、ad_js.php sql注入漏洞 Exp:view-source:http://127.0.0.3/bluecms/ad_js.php?ad_id12%20UNION%20SELECT1,2,3,4,5,6,database() 3、…...

谷粒商城实战笔记-59-商品服务-API-品牌管理-使用逆向工程的前后端代码

文章目录 一&#xff0c; 使用逆向工程生成的代码二&#xff0c;生成品牌管理菜单三&#xff0c;几个小问题 在本次的技术实践中&#xff0c;我们利用逆向工程的方法成功地为后台管理系统增加了品牌管理功能。这种开发方式不仅能快速地构建起功能模块&#xff0c;还能在一定程度…...

如何利用Jenkins自动化管理、部署数百个应用

目录 1. Jenkins 安装与部署步骤 1.1 系统要求 1.2 安装步骤 1.2.1 Windows 系统 1.2.2 CentOS 系统 1.3 初次配置 2. Gradle 详细配置方式 2.1 安装 Gradle 2.1.1 Windows 系统 2.1.2 CentOS 系统 2.2 配置 Jenkins 中的 Gradle 3. JDK 详细配置方式 3.1 安装 JD…...

Java之归并排序

归并排序 归并排序(Merge Sort)算法&#xff0c;使用的是分治思想。分治&#xff0c;顾名思义&#xff0c;就是分而治之&#xff0c;将一个大问题分解成小的子问题来解决。小的子问题解决了&#xff0c;大问题也就解决了。 核心源码: mergeSort(m->n) merge(mergeSort(m-&g…...

了解ChatGPT API

要了解如何使用 ChatGPT API&#xff0c;可以参考几个有用的资源和教程&#xff0c;这些资源能帮助你快速开始使用 API 进行项目开发。下面是一些推荐的资源&#xff1a; OpenAI 官方文档&#xff1a; 访问 OpenAI 的官方网站可以找到 ChatGPT API 的详细文档。这里包括了 API …...

EasyAnimate - 阿里开源视频生成项目,国产版Sora,高质量长视频生成 本地一键整合包下载

EasyAnimate是阿里云人工智能平台PAI自主研发的DiT-based视频生成框架&#xff0c;它提供了完整的高清长视频生成解决方案&#xff0c;包括视频数据预处理、VAE训练、DiT训练、模型推理和模型评测等。在预训练模型的基础上&#xff0c;EasyAnimate可通过少量图片的LoRA微调来改…...

7月23日JavaSE学习笔记

异常&#xff1a; 程序中一些程序处理不了的特殊情况 异常类 Exception 继承自 Throwable 类&#xff08;可抛出的&#xff09; Throwable继承树 Error&#xff1a;错误/事故&#xff0c;Java程序无法处理&#xff0c;如 OOM内存溢出错误、内存泄漏...会导出程序崩溃 常见的…...

Linux——DNS服务搭建

&#xff08;一&#xff09;搭建nginx 1.首先布置基本环境 要求能够ping通外网&#xff0c;有yum源 2.安装nginx yum -y install nginx 然后查看验证 3.修改网页配置文件 修改文件&#xff0c;任意编写内容&#xff0c;然后去物理机测试 &#xff08;二&#xff09;创建一…...

C#中的wpf基础

在WPF中&#xff0c;Grid 是一种非常强大的布局控件&#xff0c;用于创建网格布局。它允许你将界面划分为行和列&#xff0c;并将控件放置在这些行和列中。 以下是一些关键点和示例&#xff0c;帮助你理解 WPF 中的 Grid&#xff1a; 基本属性 RowDefinitions&#xff1a;定义…...

基于微信小程序+SpringBoot+Vue的刷题系统(带1w+文档)

基于微信小程序SpringBootVue的刷题系统(带1w文档) 基于微信小程序SpringBootVue的刷题系统(带1w文档) 本系统是将网络技术和现代的管理理念相结合&#xff0c;根据试题信息的特点进行重新分配、整合形成动态的、分类明确的信息资源&#xff0c;实现了刷题的自动化&#xff0c;…...

SSH -i的用法

缘起 今天使用ssh -i指定私钥时遇到以下错误&#xff1a; WARNING: UNPROTECTED PRIVATE KEY FILE! Permissions 0644 for /home/ken/.ssh/my.pem are too open. It is required that your private key files are NOT accessible by others. This private key will b…...

小白学习webgis的详细路线

推荐打开boss直聘搜索相关岗位&#xff0c;查看岗位要求&#xff0c;对症下药是最快的。 第一阶段&#xff1a;基础知识准备 计算机基础 操作系统&#xff1a;理解Windows、Linux或macOS等操作系统的基本操作&#xff0c;学会使用命令行界面。网络基础&#xff1a;掌握TCP/I…...

使用ChatGPT来撰写和润色学术论文的教程(含最新升级开通ChatGpt4教程)​​

现在有了ChatGPT4o更加方便了, 但次数太少了 想要增加次数可以考虑升级开桶ChatGpt4​​ &#xff08; OPENAI4 可以减2刀&#xff09; 一、引言 在学术研究中&#xff0c;撰写高质量的论文是一项重要的技能。本教程将介绍如何利用ChatGPT来辅助完成从论文构思到润色的全过程…...

常见的 HTTP 状态码分类及说明

HTTP 响应状态码&#xff08;HTTP status code&#xff09;&#xff0c;表示服务器对请求的处理结果。常见的 HTTP 状态码有以下几类&#xff1a; 1xx: 信息响应 (Informational Responses) 100 Continue: 请求已收到&#xff0c;客户端应继续发送请求的其余部分。101 Switch…...

Leetcode700.二叉搜索树中搜索具体值

二叉搜索树的定义&#xff1a; 一颗空树或者具有以下性质的二叉树&#xff1a; 若任意节点的左子树不空&#xff0c;则左子树上所有节点的值均小于它的根节点的值&#xff1b;若任意节点的右子树不空&#xff0c;则右子树上所有节点的值均大于它的根节点的值&#xff1b;任意节…...

自动导入unplugin-auto-import+unplugin-vue-components

文章介绍 接下来将会以Vite Vue3 TS的项目来举例实现 在我们进行项目开发时&#xff0c;无论是声明响应式数据使用的ref、reactive&#xff0c;或是各种生命周期&#xff0c;又或是computed、watch、watchEffect、provide-inject。这些都需要前置引入才能使用&#xff1a; …...

Conda修改包/虚拟环境储存目录

Conda修改包/虚拟环境储存目录 关键字样例 关键字 通过conda config --show [key]可以查看某个配置的值&#xff0c;[key]留空可以查看所有配置 其中&#xff1a; envs-dirs 存放虚拟环境的储存目录pkgs_dirs 包的目录 通过conda config --add [key] [value]可以为配置添加值…...

Live555源码阅读笔记:哈希表的实现(C++)

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…...

警务平台app

智慧公安以大数据、云计算、人工智能、物联网和移动互联网技术为支撑&#xff0c;以“打、防、管、控”为目的&#xff0c;综合研判为核心&#xff0c;共享信息数据资源&#xff0c;融合业务功能&#xff0c;构建公安智慧大数据平台&#xff0c;实现公安信息数字化、网络化和智…...

Java代理模式详解

Java代理模式详解 概念 代理模式是一种设计模式&#xff0c;为其他对象提供一种代理以控制对这个对象的访问。在某些情况下&#xff0c;一个对象不适合或者不能直接引用另一个对象&#xff0c;而代理对象可以在客户端和目标对象之间起到中介的作用。在Java中&#xff0c;代理…...

docker centos镜像 npm安装包时报错“npm ERR! code ECONNRESET”

1.采用新的镜像地址 npm config set registry https://registry.npmmirror.com2.清理缓存 npm cache clean --force3.安装yarn npm install -g yarn4. 安装模块 在node_modules 同级目录执行下面命令&#xff1a; yarn add napi-build-utils env-paths express ejs cors …...

Angular中component和directive的区别?

在Angular中&#xff0c;Component和Directive都是重要的构建块&#xff0c;用于构建和组织应用程序的UI。然而&#xff0c;它们有不同的用途和特点。以下是Component和Directive的主要区别&#xff1a; Component&#xff08;组件&#xff09; 1、定义&#xff1a;Component…...

Unity 资源 之 Pop It 3D 解压玩具与双人AI游戏 Unity 资源包分享

精彩呈现&#xff1a;Pop It 3D 解压玩具与双人AI游戏 Unity 资源包分享 一、Pop It 3D 解压玩具的魅力二、双人游戏的互动乐趣三、Unity 游戏资源包的优势四、如何获取资源包 亲爱的游戏爱好者们&#xff0c;今天为大家带来一款令人兴奋的游戏资源——Pop It 3D 解压玩具双人带…...

linux离线安装mysql8(单机版)

文章目录 一、检查服务器是否有残留mysql资源&#xff0c;有的话就全删除1.1、查询mysql已安装的相关依赖&#xff1a;1.2、查找含有MySQL的目录 二、安装2.1、上传mysql安装包到文件夹下并解压2.2、移动及重命名2.3、mysql用户2.4、配置mysql所需的my.cnf文件2.5、给my.cnf配置…...

【Python】快速创建一个简易 HTTP 服务器(http.server)

目录 官方文档安装教程用命令行创建编写代码创建 实例 官方文档 http.server 警告&#xff1a; http.server 不推荐用于生产环境。它仅仅实现了 basic security checks 的要求。 安装 Python3 内置标准模块&#xff0c;无需安装。&#xff08;在之前的 Python2 版本名称是 Si…...

随着软件开发方法的不断演进,Cobol 程序如何适应敏捷开发和持续集成/持续部署(CI/CD)的流程?

Cobol是一种古老的编程语言&#xff0c;最初设计用于商业数据处理。虽然它不是为敏捷开发和CI/CD流程而设计的&#xff0c;但仍然可以通过一些技术和方法来使其与这些现代开发流程兼容。 以下是一些方法可以帮助Cobol程序适应敏捷开发和CI/CD流程&#xff1a; 拆分和模块化&am…...

nodejs - MongoDB 学习笔记

一、简介 1、MongoDB 是什么 MongoDB 是一个基于分布式文件存储的数据库&#xff0c;官方地址 https://www.mongodb.com/ 2、数据看是什么 数据库&#xff08;DataBase&#xff09;是按照数据结构来组织、存储和管理数据的应用程序。 3、数据库的作用 主要作用是 管理数据…...

photoshop学习笔记——移动工具

移动工具&#xff0c;可以对图层进行移动&#xff0c;快捷键 V 使用的素材已经放上了&#xff0c;直接下载即可 按住ctrl 可以自动选取&#xff0c;鼠标点击哪个对象&#xff0c;自动选中哪个图层 按住 shift 校正角度&#xff08;只能沿着直线移动&#xff09; 按住 alt 拖…...

HarmonyOS 质量、测试、上架速浏

1.应用质量要求&#xff1a; 1. 应用体验质量建议: 功能数据完备 功能完备 数据完备 基础体验要求 基础约束 兼容性 稳定性 性能 功耗 安全…...

TS的访问修饰符有哪些

如果你和我一样是从强类型语言(如C、C#、Java)转过来的&#xff0c;相信你会一眼就知道是什么 public&#xff08;默认&#xff09; - 全部可访问 protected - 自己和派生类可访问 private - 只有自己可访问 废话不多说&#xff0c;上代码&#xff1a; class Person {publ…...

网络安全之扫描探测阶段攻防手段(二)

扫描探测 扫描探测阶段是攻击者对目标网络进行深入了解的关键步骤&#xff0c;同时也是防御者识别潜在威胁和加强安全防护的机会。 攻击端&#xff1a;技术原理和工具 端口扫描&#xff1a; 原理&#xff1a;攻击者使用端口扫描工具来识别目标网络中开放的端口&#xff0c;这…...

C++:泛型算法了解

什么是泛型算法 泛型算法是C标准模板库&#xff08;STL&#xff09;中的一部分&#xff0c;它们表示的是可以用于不同类型的元素和多种容器类型的一些经典算法的公共接口。这些算法之所以被称为“泛型”&#xff0c;是因为它们可以操作在多种容器类型上&#xff0c;包括但不限…...

基于bert的自动对对联系统

目录 概述 演示效果 核心逻辑 使用方式 1.裁剪数据集 根据自己的需要选择 2.用couplet数据集训练模型 模型存储在model文件夹中 3.将模型转换为ONNX格式 4.打开index.html就可以在前端使用此自动对对联系统了。 本文所涉及所有资源均在传知代码平台可获取。 概述 这个生成器利用…...

js-vue中多个按钮状态选中类似于复选框与单选框实现

1.vue中多个按钮状态选中类似于复选框 在Vue中处理多个按钮的选中状态切换&#xff0c;通常我们会利用Vue的响应式数据系统来追踪每个按钮的选中状态。 html <div id"app"> <button v-for"button in buttons" :key"button.id" :c…...

ObservableCollection新增数据前判断数据是否存在

public class MyDataModel {public int Id { get; set; }public string Name { get; set; }}public static void Main(){// 创建 ObservableCollectionObservableCollection<MyDataModel> myDataCollection new ObservableCollection<MyDataModel>{new MyDataMode…...

DBus快速入门

DBus快速入门 参考链接&#xff1a; 中文博客&#xff1a; https://www.e-learn.cn/topic/1808992 https://blog.csdn.net/u011942101/article/details/123383195 https://blog.csdn.net/weixin_44498318/article/details/115803936 https://www.e-learn.cn/topic/1808992 htt…...

SQL Server 设置端口号:详细步骤与注意事项

目录 一、了解SQL Server端口号的基础知识 1.1 默认端口号 1.2 静态端口与动态端口 二、使用SQL Server配置管理器设置端口号 2.1 打开SQL Server配置管理器 2.2 定位到SQL Server网络配置 2.3 修改TCP/IP属性 2.4 重启SQL Server服务 三、注意事项 3.1 防火墙设置 3…...

Python面试题:结合Python技术,如何使用NetworkX进行复杂网络分析

NetworkX 是一个强大的 Python 库&#xff0c;用于创建、操作和研究复杂网络的结构、动力学和功能。它提供了丰富的功能来处理图和网络数据&#xff0c;适合用于复杂网络分析。以下是使用 NetworkX 进行复杂网络分析的基本步骤&#xff1a; 安装 NetworkX&#xff1a; pip inst…...

【C#/C++】C#调C++的接口,给C++传结构体数组

C#调C的接口&#xff0c;给C传结构体数组 1、背景2、实现 1、背景 C#软件创建了一个结构体数组用来存储图像的区域信息&#xff0c;分别是矩形框的左上像素的xy坐标和矩形框右下像素的xy坐标。需要传入给调用的C函数的参数列表中&#xff0c;我们选择使用C#传入一个结构体数组…...

ctfshow SSTI注入 web369--web372

web369 这把request过滤了&#xff0c;只能自己拼字符了 ""[[__clas,s__]|join] 或者 ""[(__clas,s__)|join] 相当于 ""["__class__"]举个例子&#xff0c;chr(97) 返回的是字符 a&#xff0c;因为 97 是小写字母 a 的 Unicode 编码…...

Llama + Dify,在你的电脑搭建一套AI工作流

theme: smartblue 点赞 关注 收藏 学会了 本文简介 最近字节在推Coze&#xff0c;你可以在这个平台制作知识库、制作工作流&#xff0c;生成一个具有特定领域知识的智能体。 那么&#xff0c;有没有可能在本地也部署一套这个东西呢&#xff1f;这样敏感数据就不会泄露了&…...

洛谷 P9854 [CCC 2008 J1] Body Mass Index

这题让我们计算出 BMI 值&#xff0c;随后判断属于哪个等级。 BMI 值计算公式&#xff1a; ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​。 BMI 范围 对应信息 …...

Redis面试三道题目

针对Redis的面试题&#xff0c;我将从简单到困难给出三道题目&#xff0c;并附上参考答案的概要。 1. 简单题&#xff1a;请简述Redis是什么&#xff0c;以及它的主要优点。 参考答案&#xff1a; Redis简介&#xff1a;Redis是一个开源的、使用ANSI C语言编写、支持网络、可…...