【单片机学习笔记】Windows+Vscode+STM32F4+freeRTOS+FatFs gcc环境搭建

为摒弃在接受keil邮件,研究了下gun编译,以STM32F407为例,简单记录

1. 软件包准备

  • Git
    选择对应版本直接安装即可https://git-scm.com/download/win
  • make
  • gcc
    在这里插入图片描述
    1)将上述软件包放置于C盘根目录
    在这里插入图片描述
    2)添加环境变量
    在这里插入图片描述

3)cmd命令行测试环境
分别输入

make -v
gcc -v

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

2. 编写makefile

# ------------------------------------------------
#
# @file Makefile (based on gcc)
# @author urien
# @version v1.0.0
#
# ChangeLog :
#   2023-10-20
# ------------------------------------------------######################################
# target
######################################
TARGET = update######################################
# building variables
######################################
# debug build?
DEBUG = 1
# optimization
OPT = -Og#######################################
# paths
#######################################
# Build path
BUILD_DIR = build######################################
# source
######################################
# C sources
C_DIRS += ../Libraries/FreeRTOS
C_DIRS += ../Libraries/FreeRTOS/portable/GCC/ARM_CM4F
C_DIRS += ../Libraries/CMSIS/Device/ST/STM32F4xx/Source
C_DIRS += ../Libraries/STM32F4xx_StdPeriph_Driver/src
C_DIRS += ../User/app
C_DIRS += ../User/bsp
C_DIRS += ../User/mid
C_DIRS += ../User/misc
C_DIRS += ../User/gui/app
C_DIRS += ../User/gui/lib
C_DIRS += ../User/usb
C_DIRS += ../Libraries/FATFS/source
C_DIRS += ../Libraries/STM32_USB_HOST_Library/Core/src
C_DIRS += ../Libraries/STM32_USB_HOST_Library/Class/MSC/src
C_DIRS += ../Libraries/PDF 
SRC_OBJS_DIRS += $(foreach DIR, $(C_DIRS), $(wildcard $(DIR)/*.c))
C_SOURCES = $(SRC_OBJS_DIRS) \
../Libraries/FreeRTOS/portable/MemMang/heap_4.c \
../Libraries/STM32_USB_OTG_Driver/src/usb_core.c \
../Libraries/STM32_USB_OTG_Driver/src/usb_hcd.c \
../Libraries/STM32_USB_OTG_Driver/src/usb_hcd_int.c \# Core/Src/main.c \
# Core/Src/fr# ASM sources
ASM_SOURCES =  \
startup_stm32f407xx.s#######################################
# binaries
#######################################
PREFIX = arm-none-eabi-
# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx)
# either it can be added to the PATH environment variable.
ifdef GCC_PATH
CC = $(GCC_PATH)/$(PREFIX)gcc
AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp
CP = $(GCC_PATH)/$(PREFIX)objcopy
SZ = $(GCC_PATH)/$(PREFIX)size
else
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc -x assembler-with-cpp
CP = $(PREFIX)objcopy
SZ = $(PREFIX)size
endif
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S#######################################
# CFLAGS
#######################################
# cpu
CPU = -mcpu=cortex-m4# fpu
FPU = -mfpu=fpv4-sp-d16# float-abi
FLOAT-ABI = -mfloat-abi=hard# mcu
MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)# macros for gcc
# AS defines
AS_DEFS = # C defines
C_DEFS =  \
-DSTM32F407xx \
-DSTM32F40_41xxx \
-DUSE_STDPERIPH_DRIVER \
-DUSE_USB_OTG_FS \
-DUSER_VECT_TAB_ADDRESS \
# -D__FPU_PRESENT \
# -D__FPU_USED \# AS includes
AS_INCLUDES =  # C includesC_INCS += ../Libraries/CMSIS/Include
C_INCS += ../Libraries/CMSIS/Core/Include
C_INCS += ../Libraries/CMSIS/Device/ST/STM32F4xx/Include
C_INCS += ../Libraries/STM32F4xx_StdPeriph_Driver/inc
C_INCS += ../Libraries/FreeRTOS/include
C_INCS += ../Libraries/FreeRTOS/GCC/ARM_CM4F
C_INCS += ../Libraries/FreeRTOS/portable/GCC/ARM_CM4F
C_INCS += ../Libraries/PDF
C_INCS += ../User/app
C_INCS += ../User/bsp
C_INCS += ../User/mid
C_INCS += ../User/misc
C_INCS += ../User/gui/app
C_INCS += ../User/gui/lib
C_INCS += ../User/usb
C_INCS += ../Libraries/STM32_USB_OTG_Driver/inc
C_INCS += ../Libraries/STM32_USB_HOST_Library/Class/MSC/inc
C_INCS += ../Libraries/STM32_USB_HOST_Library/Core/inc
C_INCS += ../Libraries/FATFS/source
INCS_OBJS_DIR = $(foreach DIR2, $(C_INCS), $(wildcard $(DIR2)/*.h))
INCS_OBJS_PATH = $(sort $(dir $(INCS_OBJS_DIR)))
C_INCLUDES = $(addprefix -I,$(INCS_OBJS_PATH)) \# compile gcc flags
ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sectionsCFLAGS += $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sectionsifeq ($(DEBUG), 1)
CFLAGS += -g -gdwarf-2
endif# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"#######################################
# LDFLAGS
#######################################
# link script
LDSCRIPT = STM32F407VGTx_FLASH.ld# libraries
LIBS = -lc -lm -lnosys 
LIBDIR = 
# LDFLAGS += -lc -lrdimon -u _printf_float
# LDFLAGS += -specs=nano.specs
LDFLAGS += $(MCU) -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections# default action: build all
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin#######################################
# build the application
#######################################
# list of objects
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))
# list of ASM program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
vpath %.s $(sort $(dir $(ASM_SOURCES)))$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)$(AS) -c $(CFLAGS) $< -o $@$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile$(CC) $(OBJECTS) $(LDFLAGS) -o $@$(SZ) $@$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)$(HEX) $< $@$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)$(BIN) $< $@	$(BUILD_DIR):mkdir $@		#######################################
# clean up
#######################################
clean:-rm -fR $(BUILD_DIR)#######################################
# dependencies
#######################################
-include $(wildcard $(BUILD_DIR)/*.d)#######################################
# download .hex/.bin by jlink
#######################################
#Your JLink installation directory
PATH_WINPC = 'C:/Program Files (x86)/SEGGER/JLink/'
#PATH_LINUX = /opt/SEGGER/JLink_V640b/JLinkExe
JK_DPATH = $(PATH_WINPC)
#Jlink script store directory
JKS_DIR = .
#Chip type
CHIP_TYPE = STM32F407VG
flash:@$(JK_DPATH)JLink.exe -device $(CHIP_TYPE) -if SWD -speed 4000 -autoconnect 1 -CommanderScript $(JKS_DIR)/flash.jlink@echo "Download Completed!"debug:@$(JK_DPATH)JLinkGDBServer.exe -select USB -device $(CHIP_TYPE) -if SWD -speed auto -noir -LocalhostOnly# *** EOF ***

3. __CC_ARM转__GUNC__注意

启动文件及LD文件
通过CubeMx工具生成即可
目录路径表示问题
// __CC_ARM环境
#define DBG_PATH_DIR '\\'		   // 目录结构
// __GUNC__环境
#define DBG_PATH_DIR '/'		   // 目录结构
字节对齐及指定位置存储问题
// __CC_ARM环境
__align(32) unsigned char ucaMemPool[MEM_MAX_SIZE]; // 内存池(32字节对齐)
// __GUNC__环境
#pragma pack(32)  // 内存池(32字节对齐)
unsigned char ucaMemPool[MEM_MAX_SIZE];
#pragma pack()// __CC_ARM环境
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__((at(0X10000000)));	
// __GUNC__环境
static uint8_t ucHeap[configTOTAL_HEAP_SIZE] __attribute__ ((section(".ccmram")));
/**
其中.ccmram在LD中定义,如果没有则需要自定义
*/.ccmram :{. = ALIGN(4);_sccmram = .;       /* create a global symbol at ccmram start */*(.ccmram)*(.ccmram*). = ALIGN(4);_eccmram = .;       /* create a global symbol at ccmram end */} >CCMRAM AT> FLASH
FreeRTOS兼容问题

在这里插入图片描述

底层接口RVDS替换为GCC

const功能接口注册问题
// __CC_ARM环境
#define REGISTER_CMD(cmd, handler, desc)             \const char _register_##cmd##_cmd[] = #cmd;       \const char _register_##cmd##_desc[] = #desc;     \CMD_USED cmd_t _register_##cmd SECTION("CMDS") = \{                                            \_register_##cmd##_cmd,                   \_register_##cmd##_desc,                  \(unsigned int)CMD_HASH,                  \(cmd_handler)&handler};
void cmd_get_time(void *param)
{CALENDAR_T struCal;if_rtc_get(&struCal);__printf("%d-%d-%d %d:%d:%d %d\r\n", struCal.year, struCal.month, struCal.day,struCal.hour, struCal.minute, struCal.second, struCal.week);
}
REGISTER_CMD(get_time, cmd_get_time, get_time);// __GUNC__环境需要实现功能注册必须建表。
// 屏蔽原先接口
#define REGISTER_CMD(...)
// 新建关联表
cmd_t cmd_table[] ={{"set_time", "set_time[ymdhmsw]", 0, cmd_set_time},{"get_time", "get_time", 0, cmd_get_time},{"get_sensor", "get_sensor", 0, cmd_get_sensor},{"set_tp", "set_tp[tp1 tp2]", 0, cmd_set_target},...{0, 0, 0, 0},
};
USB_OTG问题

移植是需要删除一下文件:

usbh_msc_fatfs.c
usb_conf_template.h
特殊函数替换

__CC_ARM环境

// THUMB指令不支持汇编内联
// 采用如下方法实现执行汇编指令WFI
__asm void WFI_SET(void)
{WFI;
}
// 关闭所有中断(但是不包括fault和NMI中断)
__asm void INTX_DISABLE(void)
{CPSID IBX LR
}
// 开启所有中断
__asm void INTX_ENABLE(void)
{CPSIE IBX LR
}
// 设置栈顶地址
// addr:栈顶地址
__asm void MSR_MSP(u32 addr)
{MSR MSP, r0 // set Main Stack valueBX r14
}

__GUNC__环境

/*** @brief       执行: WFI指令(执行完该指令进入低功耗状态, 等待中断唤醒)* @param       无* @retval      无*/
void sys_wfi_set(void)
{__ASM volatile("wfi");
}/*** @brief       关闭所有中断(但是不包括fault和NMI中断)* @param       无* @retval      无*/
void sys_intx_disable(void)
{__ASM volatile("cpsid i");
}/*** @brief       开启所有中断* @param       无* @retval      无*/
void sys_intx_enable(void)
{__ASM volatile("cpsie i");
}/*** @brief       设置栈顶地址* @note        左侧的红X, 属于MDK误报, 实际是没问题的* @param       addr: 栈顶地址* @retval      无*/
void sys_msr_msp(uint32_t addr)
{__set_MSP(addr); /* 设置栈顶地址 */
}
IAP相关问题

bootloader工程flash最好也修改限制自身的大小限制

MEMORY
{RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128KCCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64KFLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K
}

bootloader跳转问题
在这里插入图片描述

// __GUNC__环境编译后得到的hex及bin文件无法满足以下条件
if ((tmp & 0x2FFE0000) == 0x20000000) // 检查栈顶地址是否合法.
目前没有找到更好的办法,做注释处理。
u32 tmp = 0;
s8 iap_load_app(u32 appxaddr)
{//	if ((tmp & 0x2FFE0000) == 0x20000000) // 检查栈顶地址是否合法.{jump2app = (iapfun) * (vu32 *)(appxaddr + 4); // 用户代码区第二个字为程序开始地址(复位地址)__set_MSP(appxaddr);						  /* 设置栈顶地址 */// MSR_MSP(*(vu32 *)appxaddr);					  // 初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)jump2app(); // 跳转到APP.}return 1;
}

application需要修改三处

// 第一处 LD文件
MEMORY
{RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128KCCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64KFLASH (rx) : ORIGIN = 0x08010000, LENGTH = 960K
}// 第二处 makefile文件
// 增加USER_VECT_TAB_ADDRESS宏定义
C_DEFS =  \
-DUSER_VECT_TAB_ADDRESS \// 第三处 system_stm32f4xx.c文件
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field. \This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET 0x00000000U     /*!< Vector Table base offset field. \This value must be a multiple of 0x200. */
#else
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field. \This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET 0x00010000U      /*!< Vector Table base offset field. \This value must be a multiple of 0x200. */
#endif                                   /* VECT_TAB_SRAM */
#endif                                   /* USER_VECT_TAB_ADDRESS */
关于下载

下载可以借用sergger - jlink驱动,在makefile文件添加如下:

#######################################
# download .hex/.bin by jlink
#######################################
#Your JLink installation directory
PATH_WINPC = 'C:/Program Files (x86)/SEGGER/JLink/'
#PATH_LINUX = /opt/SEGGER/JLink_V640b/JLinkExe
JK_DPATH = $(PATH_WINPC)
#Jlink script store directory
JKS_DIR = .
#Chip type
CHIP_TYPE = STM32F407VG
flash:@$(JK_DPATH)JLink.exe -device $(CHIP_TYPE) -if SWD -speed 4000 -autoconnect 1 -CommanderScript $(JKS_DIR)/flash.jlink@echo "Download Completed!"debug:@$(JK_DPATH)JLinkGDBServer.exe -select USB -device $(CHIP_TYPE) -if SWD -speed auto -noir -LocalhostOnly

主要注意两个地方:

1)驱动的安装位置

2)JKS_DIR定义的位置,这个直接索引编译后的hex文件

浮点数打印及格式化问题
makefile文件中去除-specs=nano.specs
# LDFLAGS += -specs=nano.specs

注意:去除后编译大小将增加40K代码空间

关于VSCODE编写代码高亮、索引、宏定义关联问题

在.vscode文件夹下根据需要添加目录索引及相关宏定义即可

在这里插入图片描述

4. 关于二次开发

二次开发新建的文件,存放于user对应的目录下即可,无需修改makefile文件。

4. 编译、下载、清除

urien@urien MINGW64 /d/work/prj_sealer/05软件/biolink-m4/source/application/Project (branch_sealer_gcc)
$ make -j20
....-mfloat-abi=hard -TSTM32F407VGTx_FLASH.ld  -lc -lm -lnosys  -Wl,-Map=build/update.map,--cref -Wl,--gc-sections -o build/update.elf
arm-none-eabi-size build/update.elftext    data     bss     dec     hex filename243772   60912  113784  418468   662a4 build/update.elf
arm-none-eabi-objcopy -O ihex build/update.elf build/update.hex
arm-none-eabi-objcopy -O binary -S build/update.elf build/update.binurien@urien MINGW64 /d/work/prj_sealer/05软件/biolink-m4/source/application/Project (branch_sealer_gcc)
$
urien@urien MINGW64 /d/work/prj_sealer/05软件/biolink-m4/source/application/Project (branch_sealer_gcc)
$ make flash
...
Script processing completed.Download Completed!urien@urien MINGW64 /d/work/prj_sealer/05软件/biolink-m4/source/application/Project (branch_sealer_gcc)
$
urien@urien MINGW64 /d/work/prj_sealer/05软件/biolink-m4/source/application/Project (branch_sealer_gcc)
$ make clean
rm -fR build

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

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

相关文章

【Git】idea提交项目到Gitee

文章目录 1. 创建Gitee仓库1. 新建仓库2. 添加描述3. 复制仓库地址 2. idea建立连接提交2.1 Create Git Repository2.2 选择要提交的根目录2.3 Commit2.4 Push2.5 提交成功 1. 创建Gitee仓库 1. 新建仓库 2. 添加描述 3. 复制仓库地址 点击右上角克隆/下载&#xff0c;复制HT…

pv操作题目笔记

对于 pv 操作分以下几步走 什么是pv操作 PV操作在进程同步中通常指的是信号量&#xff08;Semaphore&#xff09;操作。信号量是一种用于控制多个并发进程或线程之间的同步和互斥访问的同步工具。PV操作通常涉及两个基本操作&#xff1a;P操作&#xff08;wait操作&#xff0…

MD5生成和校验

MD5生成和校验 2021年8月19日席锦 任何类型的一个文件&#xff0c;它都只有一个MD5值&#xff0c;并且如果这个文件被修改过或者篡改过&#xff0c;它的MD5值也将改变。因此&#xff0c;我们会对比文件的MD5值&#xff0c;来校验文件是否是有被恶意篡改过。 什么是MD5&#xff…

微信小程序实现类似于 vue中ref管理调用子组件函数的方式

微信小程序中确实有类似于 vue 中 ref管理子组件的方式、 这里 我给子组件定义了一个 class 只要是 css选择器拿得到的 都没什么问题 但你要保证唯一性 建议前端开发还是慎重一点 就算是不能重复也尽量用class 因为id总还是有风险的 然后 我在子组件中顶一个了一个函数 start…

计网----数据包在传输中的变化过程,单播组播和广播,ARP协议,ARP代理,免费ARP,DNS协议,路由数据转发过程

计网----数据包在传输中的变化过程&#xff0c;单播组播和广播&#xff0c;ARP协议&#xff0c;ARP代理&#xff0c;免费ARP&#xff0c;DNS协议&#xff0c;路由数据转发过程 一.数据包在传输中的变化过程&#xff08;在同一个路由器下&#xff09; 1.传输数据时&#xff0c…

RPA的尽头是超自动化?

超自动化在经过数年的发酵期后&#xff0c;已从一个科技概念崛起为市值近千亿元的新赛道&#xff0c;包括各大互联网巨头、科技公司都纷纷围绕超自动化进行战略布局。 一方面&#xff0c;是行业巨头选择纷纷跻身超自动化新赛道&#xff0c;另一方面&#xff0c;RPA行业的领军企…

Proteus仿真--VB上位机程序控制DS1302时钟仿真(Proteus仿真+程序)

本文主要介绍基于51单片机的VB上位机程序控制DS1302时钟仿真设计&#xff08;完整仿真源文件及代码见文末链接&#xff09; 简介 硬件电路主要分为单片机主控模块、DS1302模块、LCD1602液晶显示模块以及串口模块 &#xff08;1&#xff09;单片机主控模块&#xff1a;单片机选…

Git最佳实践:git常用命令和原理

Git 是一个开源的分布式版本控制系统。 Git 工作区、暂存区和版本库 工作区&#xff1a;就是你在电脑里能看到的目录。暂存区&#xff1a;英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件&#xff08;.git/index&#xff09;中&#xff0c;所以我们把暂存区有时…

Leetcode—104.二叉树的最大深度【简单】

2023每日刷题&#xff08;六&#xff09; Leetcode—104.二叉树的最大深度 递归实现代码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/int maxDepth(struct TreeNode* root){…

热点不热!如何修复笔记本电脑未连接到移动热点的问题

当你远离常规Wi-Fi时,移动热点是让你的笔记本电脑上网的关键,但当它没有按计划运行时,你会怎么办?以下是Windows笔记本电脑无法连接到移动热点时的几种修复方法。 为什么我的笔记本电脑没有连接到我的热点 由于你的笔记本电脑正试图连接到另一个有限制和可能存在问题的设…

PHP yield

概念&#xff1a; Generator&#xff1a;带 yield的function yield&#xff1a;Generator或task的中断关键字&#xff0c;执行到yield时一次调度周期执行完即阻塞&#xff0c;并返回右侧表达式结果&#xff0c;等待下一次调度器运行next()或迭代遍历才会继续往下执行&#xff0…

2023-10-23 LeetCode每日一题(老人的数目)

2023-10-23每日一题 一、题目编号 2678. 老人的数目二、题目链接 点击跳转到题目位置 三、题目描述 给你一个下标从 0 开始的字符串 details 。details 中每个元素都是一位乘客的信息&#xff0c;信息用长度为 15 的字符串表示&#xff0c;表示方式如下&#xff1a; 前十…

rust学习——泛型 (Generics)

文章目录 泛型 Generics泛型详解结构体中使用泛型枚举中使用泛型方法中使用泛型为具体的泛型类型实现方法 const 泛型&#xff08;Rust 1.51 版本引入的重要特性&#xff09;const 泛型表达式 泛型的性能 泛型 Generics Go 语言在 2022 年&#xff0c;就要正式引入泛型&#xf…

mysql下载和安装,使用

先下载安装 官方下载 已下载备份软件 安装&#xff0c;一路下一步设置环境变量 4. 打开一个cmd&#xff0c;输入mysql -u root -p

Spark内核调度

目录 一、DAG &#xff08;1&#xff09;概念 &#xff08;2&#xff09;Job和Action关系 &#xff08;3&#xff09;DAG的宽窄依赖关系和阶段划分 二、Spark内存迭代计算 三、spark的并行度 &#xff08;1&#xff09;并行度设置 &#xff08;2&#xff09;集群中如何规划并…

Visual Studio Code官网下载、vscode下载很慢、vscode下载不了 解决方案

前言 开发界的小伙伴们对于Visual Studio Code开发环境来可以说非常熟悉了&#xff0c;但由于在Visual Studio Code官网的下载速度非常的慢&#xff0c;即便开了代理也是一样的很慢、甚至下载被中断&#xff0c;几乎不能下载。 解决方案 1、在Web浏览器上打开vscode官网&#…

RabbitMQ基础篇 笔记

RabbitMQ 余额支付 同步调用 一步一步的来&#xff0c;支付业务写完后&#xff0c;如果之后加需求&#xff0c;还需要增加代码&#xff0c;不符合开闭原则。 性能上也有问题&#xff0c;openfeign是同步调用&#xff0c;性能太差。 同步调用耦合太多。 同步的优势是可以立…

Android View拖拽startDragAndDrop,Kotlin

Android View拖拽startDragAndDrop&#xff0c;Kotlin import android.os.Bundle import android.util.Log import android.view.DragEvent import android.view.View import android.view.View.OnDragListener import android.view.View.OnLongClickListener import android.w…

C语言之排序

1.冒泡排序 冒泡排序就不多说了&#xff0c;只需要两层循环嵌套&#xff0c;两两比较确定相对正确的顺序即可。 2.插入排序 插入排序的思想就是每一次向后寻找一个再将其与前面有序的部分进行对比&#xff0c;寻找合适位置插入。 这里关键要避免让前移超出目前读取的数字&…

高效MMdetection(3.1.0)环境安装和训练自己数据集教程(实现于Linux(ubuntu),可在windows尝试)

一、前言 很久没用mmdetection了&#xff0c;作为目标检测常见的几个深度学习框架&#xff0c;mmdetection用的人还是很多的&#xff0c;其中比较吸引人的一点就是mmdetection集成了非常多的算法&#xff0c;对于想做实验对比和算法学习的人来说&#xff0c;基于这个框架可以事…