【单片机学习笔记】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
相关文章:
【单片机学习笔记】Windows+Vscode+STM32F4+freeRTOS+FatFs gcc环境搭建
为摒弃在接受keil邮件,研究了下gun编译,以STM32F407为例,简单记录 1. 软件包准备 Git 选择对应版本直接安装即可https://git-scm.com/download/winmakegcc 1)将上述软件包放置于C盘根目录 2)添加环境变量 3&am…...
Oracle 控制文件的作用与控制文件创建
1、控制文件存储的数据信息 1) 数据库名称和数据库唯一标识符 (DBID),通过 select name,dbid from v$database; 查 询 DBID 和数据库名称 2) 创建数据库的时间戳 3) 有关数据文件、联机重做日志文件、归档重做日志文件的信息 4) 表空间信息 5) 检查点信息 6) 日志序…...
bootloader介绍
什么是bootloader bootloader是处理器上电后执行的第一个程序boot:将硬件引导到正常工作的状态loader:加载操作系统内核到内存的指定位置现在bootloader的功能:增加开机显示、开机音乐、OTA升级、固件验证等功能常见的bootloader:…...
以太网——ARP协议工作原理
ARP目录 MAC地址一、ARP是什么?二、ARP工作原理工作机制总结三、ARP报文结构四、ARP缓存MAC地址 我们知道别人的 IP 地址后,就能够向这个 IP 地址所在的主机发送数据包。但是IP 地址只是标识网络层的地址,那么在网络层下方数据链路层是不是也有一个地址能够告诉对方主机自己…...
一文了解AIGC与ChatGPT
一、AIGC简介 1.AIGC基础 (1)AIGC是什么 AIGC是人工智能图形计算的缩写,是一种基于图形处理器(GPU)的计算技术,可以加速各种计算任务,包括机器学习、深度学习、计算机视觉等。 AIGC是一种基于GPU的计算技术&#x…...
Java利用反射和读取xml实现迷你容器
由于需要框架能实现多态,达到控制反转解耦。所以容器还是需要的,容器的存在可以简化对象获取工作,但是容器也不是万能的。合理使用即可,Spring对我来说太庞大了,用不着,为此给框架写一个迷你版容器。 容器…...
Android12之DRM基本接口实现(二)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…...
普通二维码跳转微信小程序实战
简介 服务端springboot项目,前端基于uniapp的微信小程序,要求扫描二维码之后进入到小程序指定页面,下面记录一下实现过程以及过程中遇到的问题. 实现过程 下面是成功跳转的配置截图: 首先说下二维码规则,这个地方需要填写扫描二维码之后打开的地址,这个地址在我的项目里…...
spring boot 配置加载顺序
由官网的文档得知 https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config Default properties (specified by setting SpringApplication.setDefaultProperties).PropertySource annotations on your Configuration classe…...
基于stm32控制的4G模块在设备模式下通讯
这里的32控制其实和51的控制思路都是一样的,都是先利用一个网络助手将家里的无线网生成局域网,接着通过花生壳软件将局域网变成公共网,最后是利用串口助手,在4G模块的AT指令模式写入命令ATSOCKTCPC,公共网IP地址,公共网端口号&…...
预测宝可梦武力值、分类宝可梦
regression case 股票预测 无人车看到的各种sensor 影像镜头看到马路上的东西作为输入,输出就是方向盘角度等等的操纵策略 scalar 标量 这个是热力图,相当于你的XYZ但是Z用颜色表示了 closed-form solution 闭合解 learning rate事先定好的数值 在lin…...
Linux使用find命令查找文件
find命令 简介语法格式基本参数 参考实例根目录下文件名称的例子指定路径下特定类型的例子指定路径、文件类型特定文件名称的例子指定路径、文件类型特定文件大小的例子指定路径、文件类型 查找近期修改时间的例子指定路径、文件类型 查找空文件或目录的例子指定路径、文件类型…...
安卓使用android studio跨进程通信之AIDL
我写这篇文章不想从最基础的介绍开始,我直接上步骤吧. 1.创建服务端 1.1:创建服务端项目:我的as版本比较高,页面就是这样的 1.2:创建AIDL文件,右键项目,选中aidl aidl名字可以自定义也可以默认 basicTypes是自带的,可以删掉,也可以不删,然后把你自己所需的接口写上去 1.3:创建…...
RabbitMQ基础篇 笔记
RabbitMQ 余额支付 同步调用 一步一步的来,支付业务写完后,如果之后加需求,还需要增加代码,不符合开闭原则。 性能上也有问题,openfeign是同步调用,性能太差。 同步调用耦合太多。 同步的优势是可以立…...
实践小记—静态成员的使用注意(或许由此产生的不知名Bug)
序言 在实际生产过程中,为了便于调用,static修饰的成员会比较容易出现。 如果后期该变量并不会被修改,可以考虑使用。但如果后期需要被修改,使用该变量修饰符则需要慎重考虑。 尤其是在对硬件控制的实际生产中,更需…...
华为OD 身高体重排序(100分)【java】A卷+B卷
华为OD统一考试A卷B卷 新题库说明 你收到的链接上面会标注A卷还是B卷。目前大部分收到的都是B卷。 B卷对应20022部分考题以及新出的题目,A卷对应的是新出的题目。 我将持续更新最新题目 获取更多免费题目可前往夸克网盘下载,请点击以下链接进入ÿ…...
在Word中,图片显示不全
在今天交作业的时候,发现了一个非常SB的事情,把图片复制过去显示不完全: 使用文心一言查看搜索了一下,发现可能是以下几种原因: 图片所在行的行高设置不正确。可以重新设置行高,具体步骤包括打开图片显示…...
C++数据结构X篇_20_选择排序
文章目录 1. 选择排序原理2. 选择排序原理核心代码3. 选择排序时间消耗 1. 选择排序原理 选择排序:相对于冒泡排序,减少了交换次数,下图展示了选择排序的原理,具体仍需要结合代码分析。 2. 选择排序原理核心代码 //选择排序 v…...
华为OD技术面试-最短距离矩阵(动态规划、广度优先)
背景 记录2023-10-21 晚华为OD三面的手撕代码题,当时没做出来,给面试官说了我的想法,评价:解法复杂了,只是简单的动态规范 或 广度优先算法,事后找资料记录实现方式。 题目 腐烂的橘子 问题描述ÿ…...
【代码规范】switch 块级的作用域问题
代码规范的一些事儿 问题 今日 Git 提交代码时,出现报错: error Unexpected lexical declaration in case block no-case-declarations 解决过程 我马上就去百度,就找到了这篇文章:解决 Unexpected lexical declaration in ca…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...
uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...
