Linux环境搭建MCU开发环境
操作系统版本: ubuntu 22.04
文本编辑器: vscode
开发板: stm32f103c8t6
调试器: st-link
前言
步骤一: 安装交叉编译工具链
步骤二: 创建工程目录结构
步骤三: 调试器驱动安装
步骤四: 烧录工具安装
步骤五: 调试环境搭建
一 交叉编译工具链
交叉编译工具链是用于在一种计算机平台(x86架构)上编译生成另一种平台(ARM架构)可执行代码的开发工具集合,包含交叉编译器(
arm-none-eabi-gcc
)、交叉链接器(arm-none-eabi-ld)
、交叉调试器(arm-none-eabi-gdb)
、标准库(newlib
标准库)等组件;
交叉编译工具链命名规则
arch [-vendor] [-os] [-eabi/gnueabi/gnueabihf] [-gcc/g++]
arch:
目标架构,常见架构: ARM架构(arm/aarch64) RISC-V架构
vendor:
工具链提供商,当
工具链不依赖特定芯片厂商,采用none
代替
OS:
用于明确目标设备的操作环境
,当os字段值为 none 时,表示目标设备无操作系统(裸机),当os字段值为 linux 时,表示目标设备运行Linux操作系统;注意:
- 实时操作系统的运行环境仍被视为 裸机 ,因为其内核不提供传统 OS 的系统调用和复杂功能;
- 同时没有
vendor 与 os
,采用一个none代替;
eabi/gnueabi/gnueabihf(
Embedded Application Binary Interface):
EABI规定
- 函数调用约定(如寄存器使用、参数传递顺序)
- 栈帧布局和内存管理规则
- 数据类型对齐方式(如结构体成员的内存布局)
- 浮点运算处理方式(硬件 FPU 或软件模拟)
注意:
- 如果芯片支持硬件浮点,需选择带
hf
(硬浮点)后缀的工具链,如arm-none-linux-gnueabihf-gcc
,无硬件浮点则使用软浮点(-gnueabi
)eabi
通常与none
结合使用(如arm-none-eabi
),表示裸机程序的二进制接口规范gnueabi 或 gnueabihf
:通常与与linux
结合(如arm-none-linux-gnueabihf
),表示Linux应用的二进制接口(支持硬浮点)
二 安装交叉编译工具链
STM32F103C8T6为ARM cortex-m3内核(基于ARMV7-M架构),32位架构,目标开发板需要运行裸机程序,因此选择交叉编译工具链为 arm-none-eabi-gcc
uname -a # 用于获取系统的内核相关信息包括内核名称,主机名,硬件架构
lsb_release -a #用于查询发行版的用户层面信息包括系统名称、版本号等
官网地址: Downloads | GNU Arm Embedded Toolchain Downloads – Arm Developer
步骤一:将arm-none-eabi-gcc指定版本下载到本地
步骤二:将本地交叉编译工具包上传到ubuntu中自定义文件夹并解压
语法格式: scp [选项] <源路径> <目标路径>
使用前提: linux开启SSH服务,Windows使用PowerShell
示例: scp C:\文件路径\文件.txt 用户名@ip地址:/home/用户名/目标路径
本文采用scp指令上传压缩包,等待上传完成
scp C:\Users\Admin\Downloads\gcc-arm-none-eabi-10.3.tar.bz2 shuju@123.249.39.44:/home/shuju/ToolChain
xshell环境中进入到ToolChain目录下,创建arm-none-eabi-gcc目录,将压缩包剪切到该目录下,进入该目录解压压缩包
tar -xjvf gcc-arm-none-eabi-10.3.tar.bz2
步骤三:安装arm-none-eabi-gcc
安装环境依赖包,依赖包指软件运行所必需的其他软件组件,它们提供基础功能(如系统调用接口、库函数、编译工具等),确保主程序能正常编译和执行;
使用
1. 编译阶段:依赖包提供基础库(如arm-none-eabi-gcc
编译代码时:libc
、libm
)和头文件(如stdio.h
);2. 链接阶段:依赖包中的
binutils
(如ld
、objcopy
)负责生成可执行文件;3. 调试阶段:
gdb-multiarch
(依赖包的一部分)用于调试 ARM 程序;
sudo apt-get update
sudo apt-get install build-essential libncurses-dev flex bison gperf python3 python3-pip python3-setuptools python3-serial python3-click python3-cryptography python3-future python3-pyparsing python3-pyelftools cmake ninja-build ccache libffi-dev libssl-dev dfu-util
首先查找到交叉编译工具链的可执行路径,然后进行系统级配置
创建全局配置文件
# 创建系统级配置文件(需要管理员权限)
sudo vim /etc/profile.d/arm_toolchain.sh# 在文件中添加以下内容(替换 /home/shuju/toolchain/gcc-arm-none-eabi/gcc-arm-none-eabi-10.3-2021.07/bin 为你的实际路径)export PATH="/home/shuju/toolchain/gcc-arm-none-eabi/gcc-arm-none-eabi-10.3-2021.07/bin
:$PATH"
修改文件权限
sudo chmod +x /etc/profile.d/arm_toolchain.sh
创建符号链接到系统目录
# 创建工具链目录的符号链接(注意替换为bin文件的上层路径)
sudo ln -s /home/shuju/toolchain/gcc-arm-none-eabi/gcc-arm-none-eabi-10.3-2021.07 /usr/local/arm-toolchain# 将工具链 bin 目录链接到系统路径
sudo ln -s /usr/local/arm-toolchain/bin/* /usr/local/bin/
最后检查交叉编译器是否安装成功
arm-none-eabi-gcc -v #判断安装是否成功
三 创建工程目录结构
- ST官网获取标准外设库
官网地址:https://www.st.com.cn/zh/embedded-software/stsw-stm32054.html
标准库目录结构介绍
进入到Libraries文件夹中,只有CMSIS文件夹与STM32F10x_StdPeriph_Driver,CMSIS(Cortex-M系列微控制器的软件接口标准)目录组织结构如下:
core_cm3.h文件:Cortex-M3处理器核心寄存器定义,提供NVIC、SysTick等内核功能;
stm32f10x.h文件:提供STM32外设寄存器基础定义,封装寄存器结构体,方便底层操作;system_stm32f10x.h文件:配置系统时钟和PLL,设置系统时钟频率;
arm目录:存放keil专用的启动文件;
gcc_ride7目录:存放 GCC 专用的启动文件
;
STM32F10x_StdPeriph_Driver(外设驱动标准库文件)目录组织结构如下:
misc.c stm32f10x_xxx.c/misc.h stm32f10x_xxx.h文件:提供常用外设的接口,封装了GPIO、USART、RCC、TIM、SPI、I2C、DMA等常用外设的函数库;
开发STM32项目,必须包含以下文件:
- 启动文件,启动文件的作用为MCU复位后执行的汇编启动代码,负责初始化堆栈指针,程序计数器,异常向量表等等,由于采用gcc编译程序,开发板为stm32f103c8t6,因此选择启动文件为startup_stm32f10x_md.s;
- 内核文件 (core_cm3.h/core_cm3.c)
- 芯片头文件 (stm32f10x.h)
- 系统初始化文件(system_stm32f10x.c/system_stm32f10x.h)
- 外设驱动标准库文件 (STM32F10x_StdPeriph_Driver目录下所有文件)
- 外设配置头文件(用户自定义创建)选择启用哪些外设驱动模块并配置库的参数选项,标准库的stm32f10x.h文件默认会包含stm32f10x_conf.h,如果此文件不存在会导致编译错误;
- 链接脚本,链接脚本用于设置程序的入口点并且决定了编译器生成的可执行文件(ELF/HEX/BIN)在芯片中的内存布局,但STM32F1 标准库中,官方并未直接提供预配置的 GCC 链接脚本;
- Makefile 自动化编译整个工程
外设配置文件(stm32f10x_conf.h)
#ifndef __STM32F10x_CONF_H
#define __STM32F10x_CONF_H//启用需要的外设库头文件,未启用的库就注释掉
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"//启用断言
#define assert_param(expr) ((void)0)#endif
mcu工程结构配置如下:
链接脚本STM32F103C8T6_FLASH.ld文件
/* 定义芯片内存区域 */
MEMORY
{FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K /* Flash 起始地址与大小 */RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K /* RAM 起始地址与大小 */
}/* 定义堆栈空间 */
_Min_Heap_Size = 0x200; /* 最小堆大小(根据需要调整) */
_Min_Stack_Size = 0x400; /* 最小栈大小(根据需要调整) *//* 定义关键符号地址 */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* 栈顶地址(RAM末尾) *//* 段分配 */
SECTIONS
{/* 中断向量表必须放在 Flash 起始地址 */.isr_vector :{. = ALIGN(4);KEEP(*(.isr_vector)) /* 保留中断向量表 */. = ALIGN(4);} >FLASH/* 代码段(.text)和只读数据(.rodata) */.text :{. = ALIGN(4);*(.text) /* 代码 */*(.text*) /* 其他代码(如内联函数) */*(.glue_7) /* ARM/Thumb 胶水代码 */*(.glue_7t) /* Thumb-2 胶水代码 */*(.eh_frame)/* 只读数据(常量、字符串等) */*(.rodata)*(.rodata*). = ALIGN(4);} >FLASH/* 初始化数据(.data):在 Flash 中存储初始值,运行时复制到 RAM */_sidata = .; /* .data 初始值的 Flash 地址 */.data : AT ( _sidata ){. = ALIGN(4);_sdata = .; /* .data 的 RAM 起始地址 */*(.data)*(.data*). = ALIGN(4);_edata = .; /* .data 的 RAM 结束地址 */} >RAM/* 未初始化数据(.bss):运行时清零 */.bss :{. = ALIGN(4);_sbss = .; /* .bss 的起始地址 */*(.bss)*(.bss*)*(COMMON) /* 公共符号 */. = ALIGN(4);_ebss = .; /* .bss 的结束地址 */} >RAM/* 用户堆栈空间 */._user_heap_stack :{. = ALIGN(8);PROVIDE ( end = . );PROVIDE ( _end = . );. = . + _Min_Heap_Size;. = . + _Min_Stack_Size;. = ALIGN(8);} >RAM/* 移除调试信息(可选) *//DISCARD/ :{libc.a ( * )libm.a ( * )libgcc.a ( * )*(.init)*(.fini)}
}
Makefile文件编写如下:
# 工具链配置
CC = arm-none-eabi-gcc
AS = arm-none-eabi-gcc -x assembler-with-cpp
OBJCOPY = arm-none-eabi-objcopy
SIZE = arm-none-eabi-size# 目标名称和构建目录
TARGET = main
BUILD_DIR = build# MCU配置
MCU = -mcpu=cortex-m3 -mthumb
DEFS = -DSTM32F10X_MD -DUSE_STDPERIPH_DRIVER# 头文件路径(已包含 User/ 目录)
INC_DIRS = -I. \-IUser \-ICMSIS/CM3/CoreSupport \-ICMSIS/CM3/DeviceSupport \-ILibrary/inc# 编译选项
CFLAGS = $(MCU) $(DEFS) -O0 -g3 -Wall -fdata-sections -ffunction-sections $(INC_DIRS)
ASFLAGS = $(MCU) $(DEFS) $(INC_DIRS)
LDFLAGS = $(MCU) -TStart/STM32F103C8T6_FLASH.ld \-Wl,--gc-sections -specs=nosys.specs -Wl,-Map=$(BUILD_DIR)/$(TARGET).map# 源文件列表
SRCS = \User/main.c \Start/startup_stm32f10x_md.s \CMSIS/CM3/DeviceSupport/system_stm32f10x.c \$(wildcard Library/src/*.c)# 生成目标文件列表
OBJS = $(addprefix $(BUILD_DIR)/,$(notdir $(SRCS:.c=.o)))
OBJS := $(OBJS:.s=.o)# 默认目标(添加 .o 文件清理步骤)
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin@echo "Cleaning intermediate .o files..."rm -f $(OBJS) # 生成ELF文件
$(BUILD_DIR)/$(TARGET).elf: $(OBJS)$(CC) $^ $(LDFLAGS) -o $@$(SIZE) $@# 生成HEX和BIN文件
$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)$(OBJCOPY) -O ihex $< $@$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)$(OBJCOPY) -O binary -S $< $@# 编译规则(保持不变)
$(BUILD_DIR)/%.o: User/%.c | $(BUILD_DIR)$(CC) -c $(CFLAGS) $< -o $@$(BUILD_DIR)/%.o: CMSIS/CM3/DeviceSupport/%.c | $(BUILD_DIR)$(CC) -c $(CFLAGS) $< -o $@$(BUILD_DIR)/%.o: Library/src/%.c | $(BUILD_DIR)$(CC) -c $(CFLAGS) $< -o $@$(BUILD_DIR)/%.o: Start/%.s | $(BUILD_DIR)$(AS) -c $(ASFLAGS) $< -o $@# 创建构建目录
$(BUILD_DIR):mkdir -p $@# 清理(删除整个 build 目录)
clean:rm -rf $(BUILD_DIR).PHONY: all clean flash
测试用例
#include "stm32f10x.h"
#include "stm32f10x_conf.h"//定义板载LED引脚
#define LED_PIN GPIO_Pin_13
#define LED_PORT GPIOC// 简单延时函数
void delay(uint32_t count)
{for (volatile uint32_t i = 0; i < count; i++);
}int main()
{// 1. 初始化系统时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);// 2. 配置GPIO为推挽输出GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = LED_PIN;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz; // 速度50MHzGPIO_Init(LED_PORT, &GPIO_InitStruct);// 3. 主循环:LED闪烁while (1) {GPIO_WriteBit(LED_PORT, LED_PIN, Bit_SET); // LED灭delay(500000);GPIO_WriteBit(LED_PORT, LED_PIN, Bit_RESET); // LED亮delay(500000);}
}
运行结果:
三 安装调试器驱动程序
安装ST-Link驱动程序
Linux内核默认支持ST-Link/V2,因此无需单独安装驱动;
纯Linux环境 - udev规则配置(可选)
udev
是Linux
系统中的一个 用户空间设备管理器,负责动态管理/dev
目录下的设备节点(usb、
键盘、 鼠标等等 ),操作系统作为软硬件资源的管理者,不允许用户跨过操作系统直接访问硬件资源;
Linux
系统默认将usb
设备(ST-Link
、J-Link
)的权限设置为root
所有,普通用户无法直接访问;
udev 规则
是用户编写的配置文件(位置: /etc/udev/rules.d/
),用于定义当设备插入或移除时系统应执行的操作,可以为设备设置权限(允许普通用户访问);
以root
身份进入/etc/udev/rules.d/
目录,创建49-stlinkv2.rules
文件(
数字49
决定了规则加载的顺序,数字越小的文件越先被处理,后面的文件中的规则可能会覆盖前面的)
,添加如下内容
# ST-Link/V2
SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="3748", MODE="0666", GROUP="plugdev"
# ST-Link/V2.1
SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="374b", MODE="0666", GROUP="plugdev"
# ST-Link/V3
SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="374d", MODE="0666", GROUP="plugdev"
生效规则并重启服务
Linux环境
以普通用户执行如下指令:
sudo udevadm control --reload-rules
sudo udevadm trigger
sudo usermod -aG plugdev $USER # 将当前用户加入plugdev组
sudo reboot # 重启生效
wsl环境
wsl
系统中默认不运行systemd-udevd
守护进程,因此即使配置了 udev 规则,规则也不会自动生效,但是需要手动配置权限,方便以普通用户的身份烧录程序;
# 安装 USBIP 工具和依赖
sudo apt update
sudo apt install linux-tools-virtual hwdata
sudo update-alternatives --install /usr/local/bin/usbip usbip `ls /usr/lib/linux-tools/*/usbip | tail -n1` 20# 将用户加入dialout组
sudo usermod -aG dialout $USER
创建权限修复脚本
# 创建自动修复脚本
sudo vim /usr/local/bin/fix_stlink_perms.sh
将下述内容拷贝到新创建的脚本fix_stlink_perms.sh 文件中
#!/bin/bash
# 修复 ST-Link 设备权限
for dev in /dev/bus/usb/*/*; doif [ -e "$dev" ]; thensudo chmod 666 "$dev"fi
done
设置脚本权限并添加到 .bashrc 自动执行
#设置脚本权限
sudo chmod +x /usr/local/bin/fix_stlink_perms.sh#自动执行修复脚本
echo '/usr/local/bin/fix_stlink_perms.sh' >> ~/.bashrc
source ~/.bashrc
安装J-Link驱动程序(可选)
由于开发主机为 x86_64 架构,因此选择Linux (x86/x64) 版本的 J-Link 驱动;
J-Link驱动只负责与调试器硬件通信,JLink驱动版本的选择与目标单片机型号无关,只要开发主机架构相同,驱动选择就相同;
官网地址:SEGGER - The Embedded Experts - Downloads - J-Link / J-Trace
本文选择:SEGGER - The Embedded Experts - Downloads
DEB(Debian Package)是基于 Debian 系统(Ubuntu)的软件包格式,将deb安装包上传到ubuntu中自定义的JLink_Deb目录,执行如下指令进行安装
# 直接安装DEB包
sudo dpkg -i JLink_Linux_V792_x86_64.deb# 若出现依赖错误,修复缺失依赖
sudo apt --fix-broken install
输入JLink,Tab键按两次判断JLink是否安装成功
udev规则配置
打开/etc/udev/rules.d/99-jlink.rules文件,添加如下内容
# SEGGER J-Link devices
SUBSYSTEM=="usb", ATTR{idVendor}=="1366", MODE="0666", GROUP="plugdev"
SUBSYSTEM=="usb", ATTR{idVendor}=="1366", ATTR{idProduct}=="0101", MODE="0666", GROUP="plugdev" # J-Link Edu
SUBSYSTEM=="usb", ATTR{idVendor}=="1366", ATTR{idProduct}=="0102", MODE="0666", GROUP="plugdev" # J-Link Plus
SUBSYSTEM=="usb", ATTR{idVendor}=="1366", ATTR{idProduct}=="0103", MODE="0666", GROUP="plugdev" # J-Link Ultra
SUBSYSTEM=="usb", ATTR{idVendor}=="1366", ATTR{idProduct}=="0121", MODE="0666", GROUP="plugdev" # J-Link OB
生效规则并重启服务
切换到普通用户,执行如下操作
sudo udevadm control --reload-rules
sudo udevadm trigger
sudo usermod -aG plugdev $USER # 将当前用户加入plugdev组
sudo reboot # 重启生效
四 安装烧录工具
官网地址:Client Challenge
本文选择pyOCD进行安装,pyOCD 要求 Python 版本至少为 3.6,输入如下指令查看python版本
pyocd --version
pyOCD 可以通过 pip 直接安装,pip 是 Python Package Index (PyPI) 的官方包管理工具,用于安装、升级、卸载和管理 Python 的第三方库(Packages),
# 安装PyOCD
pip3 install --user pyocd# 验证安装
pyocd list --targets | grep stm32f103 # 应显示stm32f103RC
纯Linux环境 - udev规则配置
创建规则文件99-pyocd.rules 并添加如下内容
sudo vim /etc/udev/rules.d/99-pyocd.rules
# ST-Link/V2
SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="3748", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="374b", MODE="0666"# J-Link
SUBSYSTEM=="usb", ATTR{idVendor}=="1366", MODE="0666"
sudo udevadm control --reload-rules
sudo udevadm trigger
sudo usermod -aG plugdev $USER # 将当前用户加入plugdev组
sudo reboot # 重启生效
WSL环境
创建权限修复脚本
# 创建自动修复脚本
sudo vim /usr/local/bin/fix_usb_perms.sh
将下述内容拷贝到新创建的脚本fix_usb_perms.sh 文件中
#!/bin/bash
# 修复所有 USB 设备权限
for dev in /dev/bus/usb/*/*; do[ -e "$dev" ] && sudo chmod 666 "$dev"
done
# 每次打开终端自动修复权限
echo "fix_usb_perms" >> ~/.bashrc
pyOCD 烧录固件
存储器地址映射
Flash
主存储区 (Main
Flash Memory
) :0x0800 0000
-0x0800 FFFF
(64KB
),存储用户程序(代码、常量数据),上电后默认从0x0800 0000
开始执行;
pyOCD核心烧录指令
擦除指令 pyocd erase
:清除芯片Flash存储区,支持三种模式
--chip
: 全片擦除--sector
:按扇区擦除--mass
: 深度擦除
pyocd erase --target stm32f103rc --chip # 长选项版本
pyocd erase -t stm32f103rc -c # 短选项版本
烧录指令 pyocd load/pyocd flash:
将程序文件(Hex/Bin)写入 Flash
- 烧录Hex文件
pyocd load 16进制文件名 --target stm32f103rc --erase sector #长选项版本
pyocd load 16进制文件名 -t stm32f103rc -e sector #短选项版本
- 烧录Bin文件
pyocd flash -a 0x08000000 -e sector -t stm32f103c8t6 二进制文件
复位指令 pyocd erase:
重启目标芯片,使新程序生效
复位类型存在软件复位,硬件复位,系统复位,核心复位四种方式,--type sw 指定复位方式为软件复位,--type hw 指定复位方式为硬件复位;
pyocd reset --type sw --target stm32f103c8t6
辅助指令:
# 列出已连接的调试器
pyocd list --probes# 列出支持的芯片型号
pyocd list --targets
烧录测试
硬件连接
安装usbipd-win
wsl2 未提供 USB 设备的直接映射功能,无法直接访问本地Windows 的 USB 设备,Ubuntu 系统相当于远程服务器,若ST-Link 设备连接在本地 Windows 电脑上,而远程服务器 物理上不直接连接该设备,因此必然无法识别,所以需要将本地 Windows 的 USB 设备 跨网络共享给远程服务器,usbip 是一个 Linux 工具,允许通过网络共享 USB 设备,而 usbipd-win 是 Windows 版本的实现,usbipd-win 允许将 USB 设备从 Windows 主机共享到其他设备或虚拟机;
官网地址:https://github.com/dorssel/usbipd-win/releases
解决方案
Windows 端: 安装
usbipd-win
,将 ST-Link 设备共享为 IP 设备远程 Ubuntu 端: 安装
usbip
工具,通过 IP 地址连接共享的 USB 设备
windows端安装usbipd-win
以管理员身份运行Windows PowerShell,输入如下指令,若出现下载失败,启动 fq 软件即可;
winget install dorssel.usbipd-win
下载结束之后以管理员身份重启Windows PowerShell, 按照如下步骤进行配置usbipd-win
# 功能: 列出当前系统上所有可用的USB设备
usbipd list
# 功能: 用于将本地 USB 设备注册到 USB/IP 守护进程(usbipd),使其能够通过网络被远程客户端访问
# --busid:指定待绑定的USB设备的总线ID,可通过usbipd list获得设备的总线IDusbipd bind --busid=<busid># usbipd bind --busid 2-2
# 查看usbipd的服务状态,判断况是否需要手动启动usbipd server
usbipd state
# 查看windows端的IP地址供后续使用
ipconfig
# 允许TCP 3240端口通过防火墙
New-NetFirewallRule -DisplayName "USBIPD" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 3240
注意:保持当前PowerShell窗口运行,不要关闭此窗口
云服务器端安装
ubuntu系统中安装 usbip 客户端工具,无论是哪个版本的ubuntu系统,皆可按照此方案安装usbip,执行如下指令:
步骤一: ubuntu系统安装必要的编译工具和依赖库:
sudo apt update
sudo apt install -y build-essential libudev-dev libwrap0-dev libtool automake autoconf pkg-config hwdata
步骤二:克隆并编译linux-tools
源码
# 获取内核源码, 进入到用户家目录, 解压源码
sudo apt install linux-source
cd ~
tar -xf /usr/src/linux-source-*.tar.bz2
cd linux-source-*/tools/usb/usbip
步骤三:进入源码目录(已进入 linux-source-*/tools/usb/usbip
)后,执行以下命令生成编译配置文件
# 生成configure脚本
./autogen.sh
步骤四:采用configure
命令指定编译参数
# --with-tcp-wrappers=no 关闭TCP包装器
# --with-usbids-dir 指定 USB 设备数据库路径./configure --with-tcp-wrappers=no --with-usbids-dir=/usr/share/hwdata
步骤五:编译并安装
# 编译 -j$(nproc) 利用多核加速编译
make -j$(nproc)
# 安装
sudo make install
步骤六:验证安装是否成功
usbip version
步骤七:扫描 Windows 主机的 USB 设备
查看ubuntu客户端ip地址
ifconfig
由于Ubuntu 客户端(ip:
192.168.0.24
)与 Windows 服务器(ip:192.168.3.30
)之间存在网络层隔离,会导致无法通信,因此需要将 Windows 服务器 IP 修改为192.168.0.XX
(与 Ubuntu 同网段),子网掩码255.255.255.0
,网关192.168.0.1
;
- 打开控制面板,点击网络和Internet
- 首先点击网络和共享中心,然后窗口左侧点击 “更改适配器设置”。
- 在 "网络连接" 窗口中,找到当前使用的网络连接(如以太网或 Wi - Fi),右键点击该连接并选择 “属性;
- 弹出的属性窗口中,找到 " Internet 协议版本 4(TCP/IPv4)",选中它并点击 "属性" 按钮;
- 在 "IP 地址"字段中输入 "192.168.0.XX"(将 "XX" 替换为你指定的数字),IP 应设置为
192.168.0.2 ~ 192.168.0.254
之间的未被占用的地址,在 "子网掩码" 字段中输入 "255.255.255.0",在 "默认网关" 字段中输入 "192.168.0.1",最后保存退出即可;
相关文章:

Linux环境搭建MCU开发环境
操作系统版本: ubuntu 22.04 文本编辑器: vscode 开发板: stm32f103c8t6 调试器: st-link 前言 步骤一: 安装交叉编译工具链 步骤二: 创建工程目录结构 步骤三: 调试…...
Android高级开发第一篇 - JNI(初级入门篇)
文章目录 Android高级开发JNI开发第一篇(初级入门篇)🧠 一、什么是 JNI?✅ 为什么要用 JNI? ⚙️ 二、开发环境准备开发工具 🚀 三、创建一个支持 JNI 的 Android 项目第一步:创建新项目项目结构…...
Kubernetes RBAC权限控制:从入门到实战
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言:为什么需要RBAC? 在Kubernetes集群中,权限失控是导致安全漏洞的核心原因之一。试想以下场景: 开发…...
python实战项目71:基于Python的US News世界大学排名数据爬取
python实战项目71:基于Python的US News世界大学排名数据爬取 一、项目背景1.1 研究意义1.2 技术背景1.3 应用场景二、爬虫系统设计与实现2.1 分析页面、寻找数据真实接口2.2 发送请求,获取响应内容2.3 提取数据2.4 保存数据三、完整代码四、总结与展望一、项目背景 1.1 研究…...

【基础算法】高精度(加、减、乘、除)
文章目录 什么是高精度1. 高精度加法解题思路代码实现 2. 高精度减法解题思路代码实现 3. 高精度乘法解题思路代码实现 4. 高精度除法 (高精度 / 低精度)解题思路代码实现 什么是高精度 我们平时使用加减乘除的时候都是直接使用 - * / 这些符号,前提是进行运算的数…...
跨平台开发框架electron
桌面端开发框架有很多,比如C#的WPF和Winform,Dart的Flutter,JS的Electron,Rust的Tauri。 目前应用比较广的是Electron,比如我们常见的开发工具VsCode,就是基于Electron开发的。 所以这篇文章我们就来聊聊Electron。 简…...

Windows最快速打开各项系统设置大全
目录 一、应用背景 二、设置项打开方法 2.1 方法一界面查找(最慢) 2.2 方法二cmd命令(慢) 2.3 方法三快捷键(快) 2.4 方法四搜索栏(快) 2.5 方法五任务栏(最快&am…...

嵌入式编译工具链熟悉与游戏移植
在自己的虚拟机Ubuntu系统下,逐步编译 mininim源码(波斯王子重制开源版) 指令流程 sudo apt-get remove liballegro5-dev liballegro-image5-dev \liballegro-audio5-dev liballegro-acodec5-dev liballegro-dialog5-dev sudo apt-get install automak…...

DeepSeek-R1-0528,官方的端午节特别献礼
DeepSeek:端午安康!刻在国人骨子里的浪漫 2025 年 05 月 28 日 | DeepSeek 端午特别献礼 当粽叶飘香时,DeepSeek 悄然带来一份节日惊喜 版本号 DeepSeek-R1-0528 正式上线 官方赋予它的灵魂是: 思考更深 推理更强 用户通过官网…...
LNMP环境中php7.2升级到php7.4
以下是 CentOS 7 上从 PHP 7.2 升级到 PHP 7.4 的详细步骤,结合知识库中的方法和注意事项: 1.备份现有环境 #备份 PHP 配置文件 cp /etc/php.ini /etc/php.ini.bak cp -r /etc/php.d /etc/php.d.bak#备份网站文件和数据库 tar -czvf website_backup.tar…...

001 flutter学习的注意事项及前期准备
在学习flutter之前,还需要进行一些初始的配置,然后才可以学习flutter 1.安装flutter 国内官网:https://flutter.cn 国际官网:https://flutter.dev 安装完成后,按照官网上面的操作步骤进行配置…...
FactoryBean 接口
Spring 框架中 FactoryBean 接口的特性,这是 Spring 提供的一种特殊机制,用于创建和管理复杂 Bean。让我通过示例和解释帮您理解这个概念。 一、FactoryBean 是什么? FactoryBean 是 Spring 框架提供的一个工厂接口,用于创建复杂…...

CS144 - Lecture 1 记录
CS144 - Lecture 1 由于没讲义,全看课了,系统性的总结有点难,记一些有趣的东西吧。 数据链路和网络层的传输 我们可以看见,对于发送方,我们的数据链路层为我们的网络层提供服务,在经过路由的时候…...
【Redis】大key问题详解
目录 1、什么是大key2、大key的危害【1】阻塞风险【2】网络阻塞【3】内存不均【4】持久化问题 3、如何发现大key【1】使用内置命令【2】使用memory命令(Redis 4.0)【3】使用scan命令【4】监控工具 4、解决方案【1】拆分大key【2】使用合适的数据结构【3】…...

【数据结构】——二叉树--链式结构
一、实现链式结构二叉树 二叉树的链式结构,那么从名字上我们就知道我们这个二叉树的底层是使用链表来实现的,前面我们的二叉树是通过数组来实现的,那么在其是完全二叉树的情况下,此时我们使用数组来实现就会使得其空间浪费较少&a…...
TKernel模块--杂项
TKernel模块–杂项 1.DEFINE_HARRAY1 #define DEFINE_HARRAY1(HClassName, _Array1Type_) \ class HClassName : public _Array1Type_, public Standard_Transient { \public: …...

充电便捷,新能源汽车移动充电服务如何预约充电
随着新能源汽车的普及,充电便捷性成为影响用户体验的关键因素之一。传统的固定充电桩受限于地理位置和数量,难以完全满足用户需求,而移动充电服务的出现,为车主提供了更加灵活的补能方式。通过手机APP、小程序或在线平台ÿ…...
laya3的2d相机与2d区域
2d相机和2d区域都继承自Sprite。 2d相机必须作为2d区域的子节点,且2d相机必须勾选isMain才能正常使用。 2d区域下如果没有主相机,则他和Sprite无异,他的主要操作皆是针对主相机。 2d相机可以调整自己的移动范围,是否紧密跟随&a…...
2024 CKA模拟系统制作 | Step-By-Step | 19、题目搭建-升级集群
目录 免费获取题库配套 CKA_v1.31_模拟系统 一、题目 二、考点分析 1. Kubernetes 升级策略 2. 节点维护操作 3. 组件升级技术 4. 权限与访问控制 三、考点详细讲解 1. Kubernetes 升级流程 2. 组件版本兼容性 3. drain 操作深度解析 四、实验环境搭建步骤 五、总…...
47道ES67高频题整理(附答案背诵版)
1.ES5、ES6(ES2015)有什么区别? ES5(ECMAScript 5)和ES6(也称为ECMAScript 2015)是JavaScript语言的两个版本,它们之间有一些重要的区别和改进: let 和 const 关键字: …...
Lauterbach TRACE32专栏
官方培训视频 trace32使用技巧博文 系统崩溃分析 - vmcore 加载到 Trace32 Trace 32 离线 dump 分析环境搭建方法 内核trace分析工具入门 如何用Trace32分析内核死机 trace32调试攻略 TRACE32调试:基础调试技巧之SystemMode、SNOOPer https://cloud.tencent…...

基于 Chrome 浏览器扩展的Chroma简易图形化界面
简介 ChromaDB Manager 是基于 Chrome 浏览器扩展的一款 ChromaDB(一个流行的向量数据库)的数据查询工具。提供了一个用户友好的界面,可以直接从浏览器连接到本地 ChromaDB 实例、查看集合信息和分片数据。本工具特别适合开发人员快速查看和…...
python打卡day41
简单CNN 数据增强卷积神经网络定义的写法batch归一化:调整一个批次的分布,常用与图像数据特征图:只有卷积操作输出的才叫特征图调度器:直接修改基础学习率 一、数据增强 在图像数据预处理环节,为提升数据多样性&#x…...

IM系统的负载均衡
1.IM场景的负载均衡 2.方案总览 SDK层想要连接一个TCP网关或者WebSocket网关的方案 SDK单地址:在SDK中写死某个网关的IP或者域名,缺点是更换地址需要重新打包SDK SDK多地址:防止某一个地址嗝屁了写上多个地址用足保持高可用 暴露接口给客户端:SDK层访问接口动态获得地址 注…...
前端八股 tcp 和 udp
都是传输层协议 udp 数据报协议 不可靠面向数据包对于应用层传递的报文加上UDP首部就传给网络层 tcp 传输控制协议 可靠 会将报文分段进行传输 区别: 1.tcp 可靠 udp 不可靠 2.tcp 面向连接 三握四挥 udp 无连接 3.tcp面向字节流 udp面向报文 4.效率低 效率高…...

使用 Zabbix 监控 MySQL 存储空间和性能指标的完整实践指南
目录 引言 一、最终目标支持功能 二、监控方案设计 2.1 技术选型 2.2 设计思路 三、实现步骤 3.1 准备工作 3.11 创建 MySQL 监控账号 3.12 配置 .my.cnf 文件 3.2 编写统一脚本 3.3 配置 Zabbix Agent UserParameter 3.4 Zabbix 前端配置建议 四、总结 引言 MySQL …...

【技能拾遗】——家庭宽带单线复用布线与配置(移动2025版)
📖 前言:在家庭网络拓扑中,客厅到弱电箱只预埋了一根网线,由于已将广电的有线电视取消并改用IPTV。现在需要解决在客厅布置路由器和观看IPTV问题,这里就用到单线复用技术。 目录 🕒 1. 拓扑规划ὕ…...

异步日志监控:FastAPI与MongoDB的高效整合之道
title: 异步日志监控:FastAPI与MongoDB的高效整合之道 date: 2025/05/27 17:49:39 updated: 2025/05/27 17:49:39 author: cmdragon excerpt: FastAPI与MongoDB整合实现日志监控系统的实战指南。首先配置MongoDB异步连接,定义日志数据模型。核心功能包括日志写入接口、聚合…...

在 Android 上备份短信:保护您的对话
尽管我们的Android手机有足够的存储空间来存储无数的短信,但由于设备故障、意外删除或其他意外原因,您可能会丢失重要的对话。幸运的是,我们找到了 5 种有效的 Android SMS 备份解决方案,确保您的数字聊天和信息保持安全且可访问。…...

标题:2025海外短剧爆发年:APP+H5双端系统开发,解锁全球流量与变现新大陆
描述: 2025年出海新风口!深度解析海外短剧系统开发核心(APPH5双端),揭秘高效开发策略与商业化路径,助您抢占万亿美元市场! 全球娱乐消费模式正在剧变。2025年,海外短剧市场已从蓝海…...