STM32G431RBT6移植FreeRTOS

引言: 本文专门为参加了蓝桥杯嵌入式赛道的同学准备, 大家可能会有这样一个问题, 比完赛之后, 对于像继续使用STM32G431RBT6学习FreeRTOS的, 发现网上的教程使用的板子基本上都是F1和F4的, 其实呢, 随便移植一下就能在我们自己的板子上面运行FreeTROS了。如果大家有ARM Linux的学习经历, 比如系统移植的基础, 那再来学这个FreeRTOS就比较容易了。

目录

一、FreeRTOS简介

二、什么是移植

三、移植实验开始

1.源码下载

2.源码目录结构简单分析

3.创建工程

4.开始移植

5.各种报错开始

四、创建几个任务看看移植效果

五、FreeRTOS为什么能进行裁剪

六、总结

七、FreeRTOS学习资源


一、FreeRTOS简介

        首先看一下FreeRTOS 的名字,可以分为两部分:“Free”和“RTOS”,“F ree”就是免费的、自由的、不受约束的意思,“RTOSRTOS”全称是R eal Time Operating System System,中文名就是实时操作系统,要注意的是,RTOS 并不是值某一特定的操作系统,而是指一类操作系统,例如,µ C/OS OS,FreeRTOSFreeRTOS,RTXRTX,RT T hread 等这些都是RTOS 类的操作系统。因此,从FreeRTOS 的名字中就能看出,F reeROTS 是一款免费的实时操作系统。
        操作系统是允许多个任务“同时运行”的,操作系统的这个特性被称为多任务。然而实际上,一个CPU 核心在某一时刻只能运行一个任务,而操作系统中任务调度器的责任就是决定在某一时刻CPU 究竟要运行哪一个任务,任务调度器使得CPU 在各个任务之间来回切换并处理任务,由于切换处理任务的速度非常快,因此就给人造成了一种同一时刻有多个任务同时运行的错觉。
        操作系统的分类方式可以由任务调度器的工作方式决定,比如有的操作系统给每个任务分配同样的运行时间,时间到了就切换到下一个任务,Unix 操作系统就是这样的。RTOS 的任务调度器被设计为可预测的,而这正是嵌入式实时操作系统所需要的。在实时环境中,要求操作系统必须实时地对某一个事件做出响应,因此任务调度器的行为必须是可预测的。像F reeRTOS这种传统的RTOS 类操作系统是由用户给每个任务分配一个任务优先级,任务调度器就可以根据此优先级来决定下一刻应该运行哪个任务。
        FreeRTOS 是众多RTOS 类操作系统中的一种,F reeRTOS 十分的小巧,可以在资源有限的微控制器中运行,当然了,F reeRTOS 也不仅仅局限于在微控制器中使用。就单从文件数量上来看F reeRTOS 要比µ C/OS 少得多。

国内外常见的几种物联网操作系统: 

题外话: Linux和物联网操作系统的区别

Linux是一个通用的操作系统内核,最初由Linus Torvalds创建,用于各种计算设备,从个人电脑到服务器再到嵌入式系统。Linux内核是一个开放源代码项目,因此可以根据需要进行定制和修改。物联网操作系统则是专门为连接到互联网的物联网设备设计的操作系统,通常具有以下特点:

1. 资源受限性:物联网设备通常具有有限的处理能力、内存和存储空间,因此物联网操作系统需要具备轻量级和高效能的特性。

2. 实时性:物联网应用中的某些任务可能对时间敏感,需要在特定时间内完成。因此,一些物联网操作系统提供实时性能,以确保任务的及时执行。

3. 低功耗:许多物联网设备需要长时间运行,因此物联网操作系统需要优化能源消耗,以延长设备的电池寿命或降低能源成本。

4. 通信支持:物联网操作系统通常需要支持各种通信协议,如Wi-Fi、蓝牙、LoRa等,以便设备能够与其他设备或云平台进行通信。

5. 安全性: 物联网设备可能面临各种安全威胁,因此物联网操作系统需要提供安全功能,如数据加密。

上面这张图是基于LInux内核开发的几款操作系统。

二、什么是移植

当在嵌入式系统中从一个硬件平台或操作系统移植软件时,我们称之为移植(Porting)。移植意味着将软件(通常是操作系统、驱动程序或应用程序)从一个平台或环境移植到另一个平台或环境,使其能够在目标平台上运行。 移植通常涉及以下几个方面:

硬件适配:目标平台通常具有不同的处理器架构、外设、存储器和输入/输出接口等硬件特性。因此,移植过程需要对软件进行适配,以确保其能够与目标硬件兼容并正确运行。这可能涉及修改驱动程序或底层硬件抽象层(HAL)。

操作系统适配: 如果软件依赖于特定的操作系统,那么在将其移植到新平台时,需要确保目标平台上有相应的操作系统支持。如果目标平台上没有现成的操作系统支持,可能需要移植一个新的操作系统或调整现有操作系统以适应目标平台。

编译和链接: 移植软件可能需要调整编译器、链接器和构建工具链以适应目标平台的体系结构和工具集。

性能优化:在移植软件时,通常需要对性能进行优化,以确保在目标平台上能够达到合理的性能水平。这可能涉及调整算法、数据结构或代码结构,以充分利用目标平台的硬件资源。

功能兼容性:移植软件时需要确保其功能在目标平台上能够正常运行,并且与原始平台上的行为保持一致。

总的来说,移植是将软件从一个环境移植到另一个环境的过程,涉及到对硬件、操作系统、编译工具链和性能进行适配和优化,以确保软件能够在目标平台上正确运行。想象成人类的器官移植, 在移植之前是不是得适配才能正常的工作。

三、移植实验开始

        移植实验开始之前相信大家肯定都是有裸机开发的基础的, 提前说一下我对操作系统的理解, 没有装操作系统之前, 我们下载到单片机中运行的程序都叫做裸机程序, 那么, 操作系统又是什么呢, 其实操作系统就是第一个裸机程序, 它的作用是为应用程序的执行提供运行环境。如果在有人问题操作系统是什么, 你就可以说操作系统其实就是一个裸机程序, 为应用程序的运行提供运行的环境。对于Linux这样的通用型操作系统内核来说, 它的作用和上面一样, 但是还需要加上这几句话, 向上提供接口, 向下控制硬件, 它的几大功能模块分别是内存管理, 进程管理、文件系统、设备驱动、网络协议栈。

上面这张图就展示了Linux整体框架构图。

1.源码下载

官网: www.freertos.org

下载可能有些慢, 嫌慢的兄弟可以去码云下载。

2.源码目录结构简单分析

3.创建工程

这里使用cubeMx创建工程我就大致掠过了, 相信大家都是会的。

打开Keil工程

编译一下

接着去到源码目录下, 准备一个存放BSP相关代码的地方

头文件的地方我们也来一个

4.开始移植

去到FreeRTOS源码位置, 将内存管理, 和M4相关的代码拿到我们创建号的工程目录下

继续, 把下面的代码移植过去先

接着把FreeRTOS的头文件拿过来

其实这些步骤大家可以自己按照自己的习惯来,这些都不是关键的地方。

修改一下调试器相关的内容

到此我们先编译一下, 说找不到这个配置文件, 这个文件很重要, 稍后做出解释。

这个文件有几种办法获取, 第一自己编写, 需要对整个FreeRTOS的源码非常的熟悉, 不推荐, 第二去源码中找示例, 推荐。

将其拷贝到我们的工程目录的头文件路径下面去

又报错了, 头文件找不到

下问题, 找一下

这个位置, 存放cpu代码的目录下面有一个头文件, 加一下

5.各种报错开始

这个错误出现的原因是因为FreeRTOS的源码中因为需要匹配各种架构的cpu和板卡, 使用了大量的条件编译, 以达到根据条件编译的定义内容编译不同的架构的代码。

方便大家复制

#if defined (__ICCARM__) || defined (__CC_ARM__) || defined (__GNUC__)#include <stdint.h>extern uint32_t SystemCoreClock;
#endif

继续报错

把FreeRTOSConfig.h文件包含在port.c文件中, 这样就能找到了

再次编译

又又报错了, 这次的原因是因为这几个异常的ISR定义重复了, 为什么会重复呢, 是因为在FreeRTOS的任务调度代码中就是利用了这几个异常的机制, 实现的任务每隔一个时间片调度依次任务。就是FreeRTOS定义了。

请看上图, 在FreeRTOS的配置文件中定义了, 所谓的配置文件, 没办法因为咱们嵌入式开发是没有啥子精美的界面的, 又不可能搞一个很漂亮的界面给我们自己根据cpu的架构, 板卡的资源信息自行选配, 所以就是用了大量的宏开关, 简单来说就是编译器在编译整个项目源码的时候, 会根据这些宏开关,或者说是符号的定义轻快选择不同的代码编译。

回到这几个ISR符号重复定义的问题, 解决办法是去到我们的xxx_it.c中注释掉这几个符号

再次编译

又又又报错了, 说这几个函数没有定义,是因为我们的配置文件选上了这些配置, 解决办法是去到配置文件中将相应的宏开关关闭, 这样在编译的使用就不编译这几个函数了。

修改前

修改后

其实还可以我们自己定义这些钩子函数, 其实就是回调函数, 是官方留给我们的接口, 可以自己定义在出现这些错误的时候, 做一些出错处理

再次编译

0error 0warning, nice, 恭喜, 大家马上接近成功了。为什么这样说呢, 是因为咱们的这个栈空间的设置是有问题的, 一会再最后给大家演示。

这个是因为我们再创建工程的时候没有用到adc uart timer等, 所以Mx没有拷贝对应的定以到工程中。我们自己添加一下

打开咱们使用到的

如果大家有移植的是由栈空间不够了,教大家怎么修改

但还是要基于我们的硬件来改。

内存布局:

四、创建几个任务看看移植效果

http://www.freertos.org

可以去FreeRTOS的官网查看API示例, 还是非常简单的这些函数

#include "main.h"
#include "bsp_led.h"
#include "FreeRTOS.h"
#include "task.h"
#include "bsp_uart.h"
#include <stdio.h>
#include "FreeRTOSConfig.h"
#include "lcd.h"TaskHandle_t start_handle;
void start_task(void *arg);
void FreeRTOS_Entry(void);int main(void)
{HAL_Init();SystemClock_Config();Led_Init();Uart_Init();FreeRTOS_Entry();
}void FreeRTOS_Entry(void)
{BaseType_t retval;printf("1\r\n");retval = xTaskCreate(      start_task,(const char *) " start_task",128,NULL,1,(TaskHandle_t *)&start_handle);if(retval != pdPASS ) {Error_Handler();}printf("2\r\n");vTaskStartScheduler();printf("3\r\n");}void start_task(void *arg)
{while(1) {printf("task running\r\n");Led_Control(LED_ON, 1);Led_Control(LED_TOGGLE, 1);Led_Control(LED_TOGGLE, 3);Led_Control(LED_TOGGLE, 5);Led_Control(LED_TOGGLE, 7);vTaskDelay(1000);}}

五、FreeRTOS为什么能进行裁剪

就是因为freeRtos根据不同的不同的硬件情况、包括不同的PCU架构, 不同的Flash SRAM大小, 

FreeRTOS还提供不同的内存分配算法。

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H/* 头文件 */
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include <stdint.h>extern uint32_t SystemCoreClock;/* 基础配置项 */
#define configUSE_PREEMPTION                            1                       /* 1: 抢占式调度器, 0: 协程式调度器, 无默认需定义 */
#define configUSE_PORT_OPTIMISED_TASK_SELECTION         1                       /* 1: 使用硬件计算下一个要运行的任务, 0: 使用软件算法计算下一个要运行的任务, 默认: 0 */
#define configUSE_TICKLESS_IDLE                         0                       /* 1: 使能tickless低功耗模式, 默认: 0 */
#define configCPU_CLOCK_HZ                              SystemCoreClock         /* 定义CPU主频, 单位: Hz, 无默认需定义 */
//#define configSYSTICK_CLOCK_HZ                          (configCPU_CLOCK_HZ / 8)/* 定义SysTick时钟频率,当SysTick时钟频率与内核时钟频率不同时才可以定义, 单位: Hz, 默认: 不定义 */
#define configTICK_RATE_HZ                              1000                    /* 定义系统时钟节拍频率, 单位: Hz, 无默认需定义 */
#define configMAX_PRIORITIES                            32                      /* 定义最大优先级数, 最大优先级=configMAX_PRIORITIES-1, 无默认需定义 */
#define configMINIMAL_STACK_SIZE                        128                     /* 定义空闲任务的栈空间大小, 单位: Word, 无默认需定义 */
#define configMAX_TASK_NAME_LEN                         16                      /* 定义任务名最大字符数, 默认: 16 */
#define configUSE_16_BIT_TICKS                          0                       /* 1: 定义系统时钟节拍计数器的数据类型为16位无符号数, 无默认需定义 */
#define configIDLE_SHOULD_YIELD                         1                       /* 1: 使能在抢占式调度下,同优先级的任务能抢占空闲任务, 默认: 1 */
#define configUSE_TASK_NOTIFICATIONS                    1                       /* 1: 使能任务间直接的消息传递,包括信号量、事件标志组和消息邮箱, 默认: 1 */
#define configTASK_NOTIFICATION_ARRAY_ENTRIES           1                       /* 定义任务通知数组的大小, 默认: 1 */
#define configUSE_MUTEXES                               1                       /* 1: 使能互斥信号量, 默认: 0 */
#define configUSE_RECURSIVE_MUTEXES                     1                       /* 1: 使能递归互斥信号量, 默认: 0 */
#define configUSE_COUNTING_SEMAPHORES                   1                       /* 1: 使能计数信号量, 默认: 0 */
#define configUSE_ALTERNATIVE_API                       0                       /* 已弃用!!! */
#define configQUEUE_REGISTRY_SIZE                       8                       /* 定义可以注册的信号量和消息队列的个数, 默认: 0 */
#define configUSE_QUEUE_SETS                            1                       /* 1: 使能队列集, 默认: 0 */
#define configUSE_TIME_SLICING                          1                       /* 1: 使能时间片调度, 默认: 1 */
#define configUSE_NEWLIB_REENTRANT                      0                       /* 1: 任务创建时分配Newlib的重入结构体, 默认: 0 */
#define configENABLE_BACKWARD_COMPATIBILITY             0                       /* 1: 使能兼容老版本, 默认: 1 */
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS         0                       /* 定义线程本地存储指针的个数, 默认: 0 */
#define configSTACK_DEPTH_TYPE                          uint16_t                /* 定义任务堆栈深度的数据类型, 默认: uint16_t */
#define configMESSAGE_BUFFER_LENGTH_TYPE                size_t                  /* 定义消息缓冲区中消息长度的数据类型, 默认: size_t *//* 内存分配相关定义 */
#define configSUPPORT_STATIC_ALLOCATION                 0                       /* 1: 支持静态申请内存, 默认: 0 */
#define configSUPPORT_DYNAMIC_ALLOCATION                1                       /* 1: 支持动态申请内存, 默认: 1 */
#define configTOTAL_HEAP_SIZE                           ((size_t)(10 * 1024))   /* FreeRTOS堆中可用的RAM总量, 单位: Byte, 无默认需定义 */
#define configAPPLICATION_ALLOCATED_HEAP                0                       /* 1: 用户手动分配FreeRTOS内存堆(ucHeap), 默认: 0 */
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP       0                       /* 1: 用户自行实现任务创建时使用的内存申请与释放函数, 默认: 0 *//* 钩子函数相关定义 */
#define configUSE_IDLE_HOOK                             0                       /* 1: 使能空闲任务钩子函数, 无默认需定义  */
#define configUSE_TICK_HOOK                             0                       /* 1: 使能系统时钟节拍中断钩子函数, 无默认需定义 */
#define configCHECK_FOR_STACK_OVERFLOW                  0                       /* 1: 使能栈溢出检测方法1, 2: 使能栈溢出检测方法2, 默认: 0 */
#define configUSE_MALLOC_FAILED_HOOK                    0                       /* 1: 使能动态内存申请失败钩子函数, 默认: 0 */
#define configUSE_DAEMON_TASK_STARTUP_HOOK              0                       /* 1: 使能定时器服务任务首次执行前的钩子函数, 默认: 0 *//* 运行时间和任务状态统计相关定义 */
#define configGENERATE_RUN_TIME_STATS                   0                       /* 1: 使能任务运行时间统计功能, 默认: 0 */
#if configGENERATE_RUN_TIME_STATS
#include "./BSP/TIMER/btim.h"
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()        ConfigureTimeForRunTimeStats()
extern uint32_t FreeRTOSRunTimeTicks;
#define portGET_RUN_TIME_COUNTER_VALUE()                FreeRTOSRunTimeTicks
#endif
#define configUSE_TRACE_FACILITY                        1                       /* 1: 使能可视化跟踪调试, 默认: 0 */
#define configUSE_STATS_FORMATTING_FUNCTIONS            1                       /* 1: configUSE_TRACE_FACILITY为1时,会编译vTaskList()和vTaskGetRunTimeStats()函数, 默认: 0 *//* 协程相关定义 */
#define configUSE_CO_ROUTINES                           0                       /* 1: 启用协程, 默认: 0 */
#define configMAX_CO_ROUTINE_PRIORITIES                 2                       /* 定义协程的最大优先级, 最大优先级=configMAX_CO_ROUTINE_PRIORITIES-1, 无默认configUSE_CO_ROUTINES为1时需定义 *//* 软件定时器相关定义 */
#define configUSE_TIMERS                                1                               /* 1: 使能软件定时器, 默认: 0 */
#define configTIMER_TASK_PRIORITY                       ( configMAX_PRIORITIES - 1 )    /* 定义软件定时器任务的优先级, 无默认configUSE_TIMERS为1时需定义 */
#define configTIMER_QUEUE_LENGTH                        5                               /* 定义软件定时器命令队列的长度, 无默认configUSE_TIMERS为1时需定义 */
#define configTIMER_TASK_STACK_DEPTH                    ( configMINIMAL_STACK_SIZE * 2) /* 定义软件定时器任务的栈空间大小, 无默认configUSE_TIMERS为1时需定义 *//* 可选函数, 1: 使能 */
#define INCLUDE_vTaskPrioritySet                        1                       /* 设置任务优先级 */
#define INCLUDE_uxTaskPriorityGet                       1                       /* 获取任务优先级 */
#define INCLUDE_vTaskDelete                             1                       /* 删除任务 */
#define INCLUDE_vTaskSuspend                            1                       /* 挂起任务 */
#define INCLUDE_xResumeFromISR                          1                       /* 恢复在中断中挂起的任务 */
#define INCLUDE_vTaskDelayUntil                         1                       /* 任务绝对延时 */
#define INCLUDE_vTaskDelay                              1                       /* 任务延时 */
#define INCLUDE_xTaskGetSchedulerState                  1                       /* 获取任务调度器状态 */
#define INCLUDE_xTaskGetCurrentTaskHandle               1                       /* 获取当前任务的任务句柄 */
#define INCLUDE_uxTaskGetStackHighWaterMark             1                       /* 获取任务堆栈历史剩余最小值 */
#define INCLUDE_xTaskGetIdleTaskHandle                  1                       /* 获取空闲任务的任务句柄 */
#define INCLUDE_eTaskGetState                           1                       /* 获取任务状态 */
#define INCLUDE_xEventGroupSetBitFromISR                1                       /* 在中断中设置事件标志位 */
#define INCLUDE_xTimerPendFunctionCall                  1                       /* 将函数的执行挂到定时器服务任务 */
#define INCLUDE_xTaskAbortDelay                         1                       /* 中断任务延时 */
#define INCLUDE_xTaskGetHandle                          1                       /* 通过任务名获取任务句柄 */
#define INCLUDE_xTaskResumeFromISR                      1                       /* 恢复在中断中挂起的任务 *//* 中断嵌套行为配置 */
#ifdef __NVIC_PRIO_BITS#define configPRIO_BITS __NVIC_PRIO_BITS
#else#define configPRIO_BITS 4
#endif#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY         15                  /* 中断最低优先级 */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5                   /* FreeRTOS可管理的最高中断优先级 */
#define configKERNEL_INTERRUPT_PRIORITY                 ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY            ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_API_CALL_INTERRUPT_PRIORITY           configMAX_SYSCALL_INTERRUPT_PRIORITY/* FreeRTOS中断服务函数相关定义 */
#define xPortPendSVHandler                              PendSV_Handler
#define vPortSVCHandler                                 SVC_Handler/* 断言 */
#define vAssertCalled(char, int) printf("Error: %s, %d\r\n", char, int)
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )/* FreeRTOS MPU 特殊定义 */
//#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
//#define configTOTAL_MPU_REGIONS                                8
//#define configTEX_S_C_B_FLASH                                  0x07UL
//#define configTEX_S_C_B_SRAM                                   0x07UL
//#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY            1
//#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS             1/* ARMv8-M 安全侧端口相关定义。 */
//#define secureconfigMAX_SECURE_CONTEXTS         5#endif /* FREERTOS_CONFIG_H */

 

六、总结

上述实验中虽然实现了将FreeRTOS移植到了比赛指定的板子上面, 但是由于SRAM的大小有限, 当代码量很大的时候就会出现硬件异常。所以咱们比赛使用的板子还是不适合移植FreeRTOS。

七、FreeRTOS学习资源

正点原子资料下载: 正点原子资料下载中心 — 正点原子资料下载中心 1.0.0 文档

B站教程

在这里对正点原子背后的工作人员、授课老师致以崇高的敬意。

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

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

相关文章

二叉树的最大深度 - LeetCode 热题 37

大家好&#xff01;我是曾续缘&#x1f61b; 今天是《LeetCode 热题 100》系列 发车第 37 天 二叉树第 2 题 ❤️点赞 &#x1f44d; 收藏 ⭐再看&#xff0c;养成习惯 二叉树的最大深度 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最…

JAVA面向对象(下 )(一、继承和方法重写)

一、继承 1.1 什么是继承 生活中继承是指&#xff1a; 继承财产>延续财产 继承/遗传 父母的长相&#xff0c;基因 > 延续上一代的基因 继承技能、专业、职位 >延续 继承中华民族的传统文化 > 延续 青出于蓝而胜于蓝 或 长江后浪推前浪&#xff0c;前浪被拍在…

【图像分割】光流生成标签(matlab)

文章目录 1. 框架2. opticalFlow_label3. 光流 1. 框架 2. opticalFlow_label close all; clear; clc; % 使用光流进行标签的生成 %% 视频帧的读取 npy_data readNPY(train.npy);%% 提取标签的坐标 first_label squeeze(npy_data(2,1,:,:)); h fspecial("gaussian&quo…

PgSQL之WITH Queries/Statement

PostgreSQL WITH 子句 在 PostgreSQL 中&#xff0c;WITH 子句提供了一种编写辅助语句的方法&#xff0c;以便在更大的查询中使用。 WITH 子句有助于将复杂的大型查询分解为更简单的表单&#xff0c;便于阅读。这些语句通常称为通用表表达式&#xff08;Common Table Express…

快速了解开发过程中VO、DTO、BO、 DO、PO、POJO、Entity的概念、区别、作用

​ 目录 ​前言 VO&#xff08;Value Object&#xff0c;值对象&#xff09; DTO&#xff08;Data Transfer Object&#xff0c;数据传输对象&#xff09; BO&#xff08;Business Object&#xff0c;业务对象&#xff09; DO&#xff08;Data Object&#xff0c;数据对象…

OpenCV从入门到精通实战(六)——多目标追踪

基于原生的追踪 使用OpenCV库实现基于视频的对象追踪。通过以下步骤和Python代码&#xff0c;您将能够选择不同的追踪器&#xff0c;并对视频中的对象进行实时追踪。 步骤 1: 导入必要的库 首先&#xff0c;我们需要导入一些必要的Python库&#xff0c;包括argparse、time、…

三级等保安全解决方案——实施方案

实施方案设计 本方案将依照国家有关信息安全建设的一系列法规和政策&#xff0c;为电台建立体系完整、安全功能强健、系统性能优良的网络安全系统。以“统一规划、重点明确、合理建设、逐步强化”为基本指导原则。根据电台网络系统不同信息的重要性调整保护策略&#xff0c;不欠…

SpringBoot项目创建,详细流程

一、前言 Spring Boot是一个开源的Java框架&#xff0c;由Pivotal团队&#xff08;现为VMware旗下&#xff09;开发&#xff0c;通过提供默认配置和一系列启动器&#xff08;starters&#xff09;来简化项目配置&#xff0c;使得开发者能够快速启动和运行Spring应用程序。 ‍ …

K8s 部署 elasticsearch-7.14.0 集群 及 kibana 客户端

一、K8s 部署 elasticsearch-7.14.0 集群 安装规划 组件replicas类型es3StatefulSetkibana1Deployment 使用 k8s 版本为&#xff1a;v1.18.0 。 本次使用 OpenEBS 来作为存储引擎&#xff0c;OpenEBS 是一个开源的、可扩展的存储平台&#xff0c;它提供了一种简单的方式来创…

国内首款千亿参数MoE模型APUS-xDAN-4.0:性能逼近GPT-4,可在4090显卡上运行

前言 随着人工智能技术的快速发展&#xff0c;模型参数的数量已成为衡量其复杂性和处理能力的重要指标。近日&#xff0c;国内科技企业APUS与AI创企新旦智能联合宣布&#xff0c;成功开源了国内首个千亿参数的混合专家模型&#xff08;MoE&#xff09;&#xff0c;APUS-xDAN-4…

锁策略和死锁问题

锁策略 乐观锁 vs 悲观锁重量级锁 vs 轻量级锁自旋锁 vs 挂起等待锁读写锁 vs 互斥锁公平锁 vs 非公平锁可重入锁 vs 不可重入锁死锁死锁产生的必要条件如何简单的解决死锁问题 小结 这里不是描述的某个特定锁,而是描述的锁的特性,描述的是"一类锁". 乐观锁 vs 悲观…

Java配置环境变量的过程

第一步&#xff1a;先找到你下载java的文件夹。 第二步&#xff1a;点击它进入看到新的文件夹继续点击。 第三步&#xff1a;点击bin文件。 第四步&#xff1a;点进去bin文件之后复制上述文件的地址。 第五步&#xff1a;回到你的电脑位置右键鼠标点击空白位置出现属性点进去 第…

设计模式胡咧咧之策略工厂实现导入导出

策略模式&#xff08;Strategy Pattern&#xff09; 定义&#xff1a; 定义了一组算法&#xff0c;将每个算法都封装起来&#xff0c;并且使它们之间可以互换。 本质: 分离算法&#xff0c;选择实现 应用场景 何时使用 一个系统有许多类&#xff0c;而区分他们的只是他们直接…

复合机器人在磁钢上下料中的应用及其优势分析

复合机器人是一种集成了移动机器人和工业机器人功能的设备&#xff0c;其独特之处在于拥有“手、脚、眼、脑”的综合能力&#xff0c;从而实现了更高的灵活性和操作效率。在磁钢上下料的应用场景中&#xff0c;复合机器人能够发挥显著的优势。 首先&#xff0c;复合机器人可以根…

Photomator 3.3.5 (macOS Universal) - 照片编辑软件

Photomator 3.3.5 (macOS Universal) - 照片编辑软件 适用于 Mac、iPhone 和 iPad 的终极照片编辑器 请访问原文链接&#xff1a;https://sysin.org/blog/photomator/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Photomat…

计算机网络 -- 网络编程基础

一 学习准备 1.1 IP地址 在 前文中我们提到过: IP 是全球网络的基础&#xff0c;使用 IP 地址来标识公网环境下主机的唯一性&#xff0c;我们可以根据 目的IP地址 进行跨路由器的远端通信。 但是我们也提到了&#xff0c;通过 IP 地址&#xff0c;只能寻找到目标主机&#xff…

视频质量度量VQM算法详细介绍

视频质量评价 视频质量评价(Video Quality Assessment,VQA)是指通过主观、客观的方式对视频图像的内容、画质等,进行感知、衡量与评价。 ITU definations subjective assessment: the determination of the quality or impairment of programme-like pictures presented…

【代码随想录】【动态规划】day48:打家劫舍

打家劫舍1 def rob(self, nums):""":type nums: List[int]:rtype: int"""# 分为两个情况&#xff0c;偷还是不偷&#xff0c;# dp[i]为考虑到第i个房间时的最大值if len(nums) 0: # 如果没有房屋&#xff0c;返回0return 0if len(nums) 1: #…

【 书生·浦语大模型实战营】作业(五):LMDeploy 量化部署

【 书生浦语大模型实战营】作业&#xff08;五&#xff09;&#xff1a;LMDeploy 量化部署 &#x1f389;AI学习星球推荐&#xff1a; GoAI的学习社区 知识星球是一个致力于提供《机器学习 | 深度学习 | CV | NLP | 大模型 | 多模态 | AIGC 》各个最新AI方向综述、论文等成体系…

Linux debian gdb dump

1.开发背景 记录 debian 下应用程序崩溃调试方法 2.开发需求 程序越界可以定位到越界的位置附近 3.开发环境 debian 操作系统&#xff0c;如果不支持需要查看是否存在对应的可执行文件 4.实现步骤 4.1 设置 dump 输出大小 ulimit -c unlimited # 设置输出大小 生成core 文…