驱动进化之路

1. 面向对象分离硬件资源驱动思想

背景<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
在早期的嵌入设备和计算机系统中<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>硬件驱动程序通常是直接和硬件紧密耦合的<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>这种方式导致了驱动程序难以维护和扩展<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>因为每种新的硬件都可能需要全新的驱动代码<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

思想<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  • 模块化<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>将硬件相关的代码从系统的其他部分中分离出来<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>形成独立的模块<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>驱动模块<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg><h-char class=bd bd-beg>
  • 抽象层<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>引入硬件抽象层<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>HAL<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg><h-char class=bd bd-beg>使得上层软件可以不直接操作硬件<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>而是通过一层抽象的接口来进行<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 封装<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>使用面向对象的编程思想<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>将硬件的操作封装成类或对象<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>这样可以更容易管理和重用代码<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

技术细节<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  • 使用类的继承和多态来实现不同硬件的抽象和具体实现<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 提供统一的接口来访问硬件资源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>降低了对具体硬件的依赖<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

例子<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>假设有一个LED连接到一个GPIO引脚上<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  • 模块化<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>创建一个独立的LED驱动模块<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>而不是将LED操作代码直接嵌入到应用层代码中<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 抽象层<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>定义一个抽象的LED类<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>包含打开<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>关闭等方法<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight cpp"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">// LED抽象类
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">class "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title class_"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">LED {
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">public:
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"function"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">virtual "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">void "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">turnOn"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"params"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">() = "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"number"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">0;
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"function"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">virtual "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">void "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">turnOff"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"params"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">() = "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"number"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">0;
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">};
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">// GPIO LED 实现
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">class "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title class_"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">GPIO_LED : "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">public LED {
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">private:
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">int pin;
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">public:
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"built_in"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">GPIO_LED("bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">int gpioPin) : "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"built_in"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">pin(gpioPin) {}
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"function"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">void "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">turnOn"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"params"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">() "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">override {
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">// GPIO设置为高电平
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> }
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"function"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">void "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">turnOff"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"params"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">() "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">override {
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">// GPIO设置为低电平
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> }
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">};

2. Platform Device 平台总线模型

随着硬件设备的复杂性增加<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>需要一种更系统化的方式来管理设备驱动和硬件资源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>平台设备总线<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>Platform Bus<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>将所有硬件设备抽象为平台设备<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>Platform Devices<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>平台驱动<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>Platform Drivers<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg><h-char class=bd bd-beg>这种抽象使得驱动开发者不必关心具体的硬件细节<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>而是通过一套标准的接口来管理设备<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

通过这种模型<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>驱动开发者可以集中精力在设备的具体操作上<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>而不需要处理复杂的总线协议或硬件初始化流程<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>平台总线为驱动提供了标准的生命周期管理和资源访问方式<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

思想<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  • 平台设备<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>将硬件设备抽象为平台设备<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>Platform Device<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg><h-char class=bd bd-beg>这些设备通过平台总线<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>Platform Bus<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>连接到系统中<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 平台驱动<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>相应地<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>驱动程序也被抽象为平台驱动<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>Platform Driver<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg><h-char class=bd bd-beg>它们通过平台总线匹配到相应的设备<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

技术细节<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  • 在Linux内核中<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>struct platform_devicestruct platform_driver 是关键数据结构<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 设备和驱动通过设备树或者是硬编码的方式注册到平台总线上<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 使用总线驱动框架<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>如I2C<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>SPI等<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>来进一步抽象硬件接口<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight c"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">// 定义平台设备的结构
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"class"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">struct "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">platform_device {
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">// 设备的名称"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">用于匹配驱动
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">const "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">char *name;
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">int id;
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">bool id_auto;
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"class"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">struct "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">device "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">dev;
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> u32 num_resources;
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">// 指向资源数组的指针"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">资源包括内存区域"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">IRQ等
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"class"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">struct "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">resource *"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">resource;
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">/* 其他字段省略 */
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">};
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">// 定义平台驱动的结构
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"class"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">struct "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">platform_driver {
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">// 探测函数"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">当设备被发现时调用"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">负责初始化设备
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">int (*probe)("bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">struct platform_device *);
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">// 移除设备时调用"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">用于清理资源
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">int (*remove)("bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">struct platform_device *);
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">void (*shutdown)("bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">struct platform_device *);
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">int (*suspend)("bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">struct platform_device *, "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">pm_message_t state);
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">int (*resume)("bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">struct platform_device *);
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">// 内嵌的通用设备驱动结构"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">包含了驱动信息如驱动名称"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">所有者等
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"class"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">struct "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">device_driver "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">driver;
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">const "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"class"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">struct "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">platform_device_id *"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">id_table;
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">/* 其他字段省略 */
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">};

例子<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>同上<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>LED连接到GPIO<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  • 平台设备<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>定义一个平台设备来代表这个LED<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight c"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">static "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"class"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">struct "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">platform_device "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">led_device = {
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> .name = "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"led",
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> .id = "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"number"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">-1,
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> .dev = {
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> .platform_data = &gpio_pin_number, "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">// 假设这个GPIO引脚号作为平台数据
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> },
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">};
  • 平台驱动<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>编写一个平台驱动来操作这个LED<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight c"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">static "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"class"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">struct "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">platform_driver "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">led_driver = {
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> .probe = led_probe,
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> .remove = led_remove,
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> .driver = {
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> .name = "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"led",
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> .owner = THIS_MODULE,
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> },
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">};
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">static "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">int "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title function_"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">led_probe"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"params"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">("bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">struct platform_device *pdev)
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">{
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">// 获取设备的GPIO引脚信息并初始化LED
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">return "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"number"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">0;
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">}
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">static "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">int "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title function_"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">led_remove"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"params"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">("bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">struct platform_device *pdev)
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">{
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">// 清理LED相关的资源
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">return "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"number"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">0;
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">}

技术细节<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  • 通过平台设备和平台驱动<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>系统可以自动匹配设备和驱动<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>led_probe 函数在匹配成功后初始化LED<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>led_remove 函数在设备卸载时清理资源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

匹配过程

平台设备与驱动的匹配过程大致如下<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  1. 设备注册<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

    • 当内核启动或模块加载时<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>平台设备<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>struct platform_device<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>被注册到平台总线<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>platform_bus<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>上<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  2. 驱动注册<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

    • 平台驱动<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>struct platform_driver<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>也需要注册到平台总线上<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  3. 设备树解析<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

    • 如果使用设备树<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>内核会解析设备树文件<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>.dts或.dtb<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg><h-char class=bd bd-beg>从中获取设备信息<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>并创建相应的平台设备实例<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  4. 匹配尝试<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

    • 内核尝试将注册的驱动与平台总线上的设备进行匹配<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
    • 匹配过程主要遵循以下顺序<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
      • 设备树匹配<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>优先尝试使用设备树匹配规则<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>检查设备的compatible属性与驱动的of_match_table是否匹配<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
      • ID匹配<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>如果设备树匹配失败<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>尝试使用设备ID匹配<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
      • 名称匹配<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>最后<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>尝试使用驱动和设备的名称匹配<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  5. 成功匹配<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

    • 一旦找到匹配的设备和驱动<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>内核会调用驱动的probe方法<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>probe方法将接收到匹配的struct device<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>实际上是一个struct platform_device<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg><h-char class=bd bd-beg>驱动可以在这个方法中初始化设备<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  6. 资源分配<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

    • probe方法中<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>驱动可以访问设备的资源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>如IO内存<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>IRQ等<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg><h-char class=bd bd-beg>这些资源通常是通过设备树或平台设备注册时提供的<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  7. 设备绑定<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

    • 如果probe方法成功<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>设备将绑定到驱动<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>设备现在可以正常工作<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  8. 失败处理<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

    • 如果匹配失败或probe方法失败<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>内核会记录错误信息<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>驱动将不会绑定到设

3. 设备树<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>Device Tree<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

背景<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
随着SoC<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>System on Chip<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>的发展<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>硬件配置变得极为复杂和多样化<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>硬编码的方式变得难以维护<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

思想<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  • 解耦硬件描述<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>将硬件的描述从内核代码中分离出来<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>形成独立的设备树描述文件<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>.dts, .dtsi<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg><h-char class=bd bd-beg>
  • 动态配置<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>设备树提供了一种动态的<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>可配置的方式来描述系统硬件<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

技术细节<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  • 设备树使用一种类似JSON的格式来描述硬件结构<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>包括节点<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>nodes<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>表示设备<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>属性<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>properties<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>表示设备的特性<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 内核中的设备树编译器<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>dtc<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>将设备树源文件编译成二进制格式<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>DTB<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg><h-char class=bd bd-beg>内核启动时加载DTB来配置硬件<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 驱动程序通过设备树中的信息来获取设备的地址<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>IRQ等信息<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>实现即插即用<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

例子<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>同上<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>一个LED连接到GPIO<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  • 设备树描述<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

    "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight dts"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
    "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
    "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title class_"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">/ "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">{
    "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title class_"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">leds "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">{
    "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"attr"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">compatible "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"operator"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">= "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"gpio-led""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">;
    "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"attr"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">gpios "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"operator"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">= "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"params"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"><"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"variable"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">&gpio "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"number"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">17 GPIO_ACTIVE_HIGH>"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">; "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">// 假设LED连接到GPIO17
    "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"attr"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">label "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"operator"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">= "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"led""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">;
    "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">};
    "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">};
  • 驱动代码<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>现在驱动可以从设备树中获取LED的配置信息<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight c"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">static "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">int "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title function_"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">led_probe"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"params"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">("bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">struct platform_device *pdev)
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">{
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"class"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">struct "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">device_node *"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"title"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">node = pdev->dev.of_node;
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"type"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">int gpio;
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">if (of_property_read_u32(node, "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"gpios", &gpio))
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">return -ENODEV;
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">// 使用GPIO进行LED操作
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"keyword"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">return "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"number"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">0;
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">}

设备树描述了硬件配置<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>驱动通过解析设备树节点来获取硬件信息<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>如GPIO引脚号<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg><h-char class=bd bd-beg>这种方式使得硬件配置与内核代码解耦<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>硬件变化只需修改设备树文件即可<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

进化意义<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  • 从面向对象到平台总线模型<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>再到设备树的演变过程中<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>硬件资源的管理变得越来越抽象和灵活<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>每个阶段都使得驱动开发和维护更加高效<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>减少了对具体硬件的依赖<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>增强了系统的可移植性和可维护性<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>通过LED点灯这个简单的例子<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>我们可以看到这种进化带来的实际好处<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>从最初的硬编码<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>到设备树的动态配置<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>使得系统对硬件变化的适应性大大增强<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 从面向对象到平台总线模型<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>再到设备树<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>硬件资源的管理和配置变得越来越抽象和通用<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>减少了对具体硬件的依赖<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>提升了系统的可移植性和可维护性<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 设备树的引入大大简化了内核的硬件描述方式<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>使得硬件支持的添加和修改变得更加灵活和高效<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

这个过程展示了操作系统在面对越来越复杂的硬件环境时<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>不断优化和抽象硬件管理方法的演进过程<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

常用依赖包管理工具换源方法大全

在国内使用一些依赖包管理工具时<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>由于网络问题<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>下载速度往往比较慢<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>通过切换到国内的镜像源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>可以显著加快依赖包的下载速度<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>本文详细整理了常用依赖包管理工具切换到国内镜像的方法<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>帮助开发者提高效率<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>


1. npm 切换国内源

国内常用的 npm 镜像源是 淘宝镜像<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>它同步了官方 npm 仓库的内容<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>且下载速度较快<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

设置淘宝镜像为默认源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">npm config "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"built_in"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">set registry https://registry.npmmirror.com

验证是否设置成功<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">npm config get registry
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"># 如果输出 https://registry.npmmirror.com"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">说明设置成功"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">

临时使用淘宝镜像<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">npm install --registry=https://registry.npmmirror.com

2. Yarn 切换国内源

Yarn 同样可以直接使用淘宝镜像源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

设置淘宝镜像为默认源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">yarn config "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"built_in"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">set registry https://registry.npmmirror.com

验证是否设置成功<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">yarn config get registry
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"comment"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"># 输出 https://registry.npmmirror.com 表示设置成功"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">

临时使用淘宝镜像<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">yarn add package-name --registry=https://registry.npmmirror.com

3. pip 切换国内源

Python 的包管理工具 pip 可以通过指定国内的镜像源来加速下载<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>推荐使用豆瓣源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

临时使用豆瓣源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">pip install package-name -i https://pypi.douban.com/simple

永久设置国内镜像<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

在用户目录下创建或修改 pip 配置文件<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  • Windows: C:\Users\你的用户名\pip\pip.ini
  • macOS/Linux: ~/.pip/pip.conf

然后添加以下内容<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight ini"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"section"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">[global]
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"attr"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">index-url = https://pypi.douban.com/simple

4. Conda 切换国内源

Conda 是 Anaconda 的包管理工具<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>设置国内镜像可以通过清华大学的镜像源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

临时使用清华源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">conda install package-name -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/

永久设置清华大学源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">conda config --"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"built_in"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">set show_channel_urls "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"built_in"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">yes

5. Composer 切换国内源

Composer 是 PHP 的包管理工具<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>可以使用中国全量镜像<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>由 Laravel China 社区维护<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg><h-char class=bd bd-beg>

设置国内镜像<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

恢复默认源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">composer config -g --"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"built_in"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">unset repos.packagist

6. RubyGems 切换国内源

Ruby 的包管理工具 gem 可以使用淘宝镜像<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

设置淘宝镜像<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/

确认源是否配置正确<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">gem sources -l

7. Maven 切换国内源

Maven 是 Java 的包管理工具<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>可以通过修改 settings.xml 文件来使用国内镜像<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

修改 settings.xml<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

~/.m2/settings.xml 中添加以下内容<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight xml"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"tag"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"><"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"name"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">mirrors>
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"tag"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"><"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"name"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">mirror>
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"tag"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"><"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"name"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">id>alimaven"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"tag"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"></"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"name"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">id>
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"tag"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"><"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"name"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">mirrorOf>central"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"tag"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"></"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"name"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">mirrorOf>
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"tag"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"><"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"name"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">name>aliyun maven"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"tag"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"></"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"name"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">name>
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"tag"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"><"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"name"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">url>https://maven.aliyun.com/repository/central"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"tag"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"></"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"name"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">url>
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"tag"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"><"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"name"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">layout>default"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"tag"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"></"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"name"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">layout>
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"tag"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"></"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"name"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">mirror>
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"tag"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"></"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"name"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">mirrors>

8. Gradle 切换国内源

对于 Android 开发者<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>Gradle 的国内源配置也可以显著加快依赖下载速度<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

修改 build.gradle 文件<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight groovy"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">allprojects {
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> repositories {
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> maven { url "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">'https://maven.aliyun.com/repository/public' }
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> maven { url "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">'https://maven.aliyun.com/repository/jcenter' }
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> maven { url "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">'https://maven.aliyun.com/repository/google' }
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> }
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">}

9. Node.js 镜像加速

如果你需要安装 Node.js 本身<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>也可以通过淘宝镜像加速<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">nvm install node --registry=https://registry.npmmirror.com

10. Docker 镜像加速

Docker 在国内下载镜像时可能会遇到速度缓慢的问题<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>可以使用国内的镜像源加速<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

设置 Docker 国内镜像<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

/etc/docker/daemon.json 中添加以下内容<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight json"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">{
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"attr"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"registry-mirrors""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">: "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">[
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"https://registry.docker-cn.com""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">,
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"https://mirror.ccs.tencentyun.com"
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">]
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">}

然后重启 Docker<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">sudo systemctl restart docker

11. apt 换源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>Ubuntu/Debian<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

apt 是 Ubuntu 和 Debian 系统常用的包管理工具<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>切换到国内镜像可以显著加快软件包的下载速度<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>常用的国内镜像源有 阿里云<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>清华大学中科大 镜像源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

步骤 1<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>备份原有的源列表

先备份 /etc/apt/sources.list 文件<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">sudo "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"built_in"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">cp /etc/apt/sources.list /etc/apt/sources.list.bak

步骤 2<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>编辑 sources.list

使用文本编辑器打开 sources.list 文件<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">sudo nano /etc/apt/sources.list

步骤 3<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>选择一个国内源替换原有的源

你可以选择以下任意一个国内镜像源来替换原有的源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  • 阿里云镜像<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
  • 清华大学镜像<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse
  • 中科大镜像<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">deb https://mirrors.ustc.edu.cn/ubuntu/ focal main restricted universe multiverse
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">deb https://mirrors.ustc.edu.cn/ubuntu/ focal-updates main restricted universe multiverse
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">deb https://mirrors.ustc.edu.cn/ubuntu/ focal-backports main restricted universe multiverse
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">deb https://mirrors.ustc.edu.cn/ubuntu/ focal-security main restricted universe multiverse

注意<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>focal 是 Ubuntu 20.04 的代号<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>如果你使用的是其他版本<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>请将 focal 替换为对应版本的代号<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

步骤 4<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>更新软件包列表

保存并退出编辑器后<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>运行以下命令更新软件包列表<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">sudo apt update

12. 总结

通过切换国内镜像源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>你可以在很多常用的包管理工具中加速依赖的下载和安装过程<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>省下不少时间<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>以下是常见工具切换国内源的方法总结<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  • npm<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>淘宝镜像<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>npm config set registry https://registry.npmmirror.com
  • Yarn<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>淘宝镜像<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>yarn config set registry https://registry.npmmirror.com
  • pip<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>豆瓣源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>pip install package-name -i https://pypi.douban.com/simple
  • Conda<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>清华源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
  • Composer<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>阿里云源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
  • RubyGems<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>淘宝镜像<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/
  • Maven<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>阿里云源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>修改 ~/.m2/settings.xml
  • Gradle<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>阿里云源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>修改 build.gradle
  • Node.js<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>淘宝镜像<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>nvm install node --registry=https://registry.npmmirror.com
  • Docker<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>配置国内镜像<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>加速容器镜像下载
  • apt<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>使用阿里云<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>清华大学或中科大镜像加速软件包下载

小小吐槽——CSDN 为什么要强制登录<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

在开发过程中<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>大家应该都有过这样的经历<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>你在 CSDN 上找到了一段有用的代码<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>然而<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>当你准备复制时<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>结果 CSDN 突然弹出一个登录框<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>让你必须登录才能复制<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>有些情况下甚至还会提示你充会员才能无障碍地复制<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

这种体验真的让人心累<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>作为一个开发者<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>最需要的是高效地获取信息<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>而不是被迫跳过这些繁琐的登录步骤<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>CSDN 的这种行为让人感觉像是被“卡脖子”<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>逼迫你为基础的功能付费<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

这就像你走进了一家图书馆<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>看到一本书的精彩片段<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>正准备抄下笔记<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>却被管理员拦住<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>“想抄<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>先交钱<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>” 这种强行限制内容获取的做法<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>似乎违背了互联网的初衷——信息的自由传播<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

话是说回来<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>在如今信息发达的时代<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>GitHubStack Overflow 这样的平台提供丰富的开源资源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>比起被限制的 CSDN<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>更值得推荐<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>


通过切换到国内镜像源<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>你可以显著加快下载依赖的速度<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>节省时间与精力<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>而至于某些平台的强制登录和会员制度<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>真的应该反思一下<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>知识的自由传播<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>难道不应该是互联网的初心吗<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

ReelBlend:一键生成扫街照片与 POV 视频

街拍摄影与 POV<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>第一人称视角<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>视频<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>已经成为当下社交媒体内容创作的热门形式<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>尤其是在平台如 YouTube<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>Instagram 和 TikTok 上<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>创作者通过动态的视频和静态的照片交替展示<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>捕捉街头氛围与视觉冲击力<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>吸引了大量粉丝<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>然而<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>这类视频的制作常常需要繁琐的后期剪辑工作<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>对非专业人士来说是一个技术和时间的双重挑战<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

为了填补这一痛点<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>我设想了一款工具<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>能够一键实现扫街照片与 POV 视频的交叉拼接<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>生成适配社交媒体标准的视频<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>本文将从软件工程的角度<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>深入探讨如何从想法出发<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>完成需求分析与系统设计<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>并最终实现这款工具<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>


想法的核心<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>一键完成街拍视频剪辑

目标功能

  1. 快速生成视频<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>用户上传的照片与视频片段可以快速交替排列<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>生成一个流畅的短视频<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  2. 便捷转场效果<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>提供基础的转场效果<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>如淡入淡出<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>滑动过渡等<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg><h-char class=bd bd-beg>让内容看起来更具专业感<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  3. 自定义参数<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>用户可以调整每张照片/视频片段的显示时长<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>选择过渡效果<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>添加背景音乐等<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  4. 适配社交平台需求<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>生成符合主流社交媒体<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>9:16<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>16:9 等<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>分辨率和格式的高质量视频文件<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

需求分析<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>解决用户痛点

在软件工程中<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>需求分析是任何项目的起点<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>对这款工具的需求分析可以分为两部分<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>用户需求技术需求<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

1. 用户需求

目标用户主要包括街拍摄影师<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>Vlogger 和社交媒体内容创作者<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>他们的需求包括<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  • 快速完成剪辑<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>希望避免使用复杂的剪辑软件<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>减少学习曲线和操作时间<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 高效拼接照片与视频<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>简单上传照片和视频<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>快速生成交替切换的内容<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 可视化控制<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>希望在生成视频之前调整时间轴顺序和参数设置<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 适配社交媒体格式<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>输出内容需符合各平台的分辨率和比例要求<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>例如 Instagram 的 9:16 竖屏<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

痛点总结<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  • 现有的视频剪辑软件<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>如 Premiere<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>Final Cut Pro<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>虽然功能强大<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>但对于简单内容的制作流程过于复杂<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 社交媒体创作追求高效<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>用户需要一款轻量级<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>专注于特定功能的工具<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

2. 技术需求

从技术角度<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>这款工具需要满足以下核心需求<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  • 支持多种媒体格式<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>照片<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>JPG/PNG<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>和视频<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>MP4/MOV<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>是常见的输入类型<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 视频拼接与转场处理<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>需要高效处理照片与视频的拼接<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>缩放和转场特效<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 音频嵌入与匹配<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>支持导入背景音乐<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>自动调整音乐长度与节奏<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 输出高质量视频<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>生成的视频需支持 1080p 或更高分辨率<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>同时提供多种比例选项<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>9:16<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>16:9<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg><h-char class=bd bd-beg>
  • 实时预览<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>提供视频生成前的预览功能<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>便于用户调整内容<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

系统设计<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>从需求到实现

1. 核心功能模块

为了满足上述需求<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>系统需要实现以下功能模块<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

前端<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>用户界面<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  • 文件上传模块<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>支持照片与视频的拖拽上传<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>显示上传进度<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 时间轴编辑模块<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>用户可以直观地调整照片与视频的排列顺序<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 参数设置模块<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>设置每张照片/视频的显示时长<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>转场效果<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>输出分辨率等<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 实时预览模块<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>在导出视频之前<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>用户可以查看拼接效果<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

后端<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>逻辑处理<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  • 视频拼接与转场逻辑<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>通过高效的多媒体处理工具<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>如 FFmpeg<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>实现照片与视频的拼接<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>缩放<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>转场处理<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 音频处理模块<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>支持音频文件的嵌入与自动匹配<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 导出与格式管理模块<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>生成符合用户需求的视频文件<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>支持多种分辨率与比例<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

2. 技术架构

前端技术栈

  • React.js 或 Vue.js<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>用于构建动态的<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>响应式的用户界面<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • Tailwind CSS 或 Chakra UI<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>快速实现简洁美观的界面设计<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • 拖拽功能库<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>react-sortable-hoc<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>用于实现时间轴的拖拽排序<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

后端技术栈

  • Node.js<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>处理业务逻辑与 API 请求<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>提供文件上传和视频生成服务<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • FFmpeg<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>核心的多媒体处理工具<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>用于视频拼接<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>转场<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>缩放和音频嵌入<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  • Express.js<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>搭建后端 API<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>处理前端请求<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

存储与导出

  • 文件存储<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>上传的照片和视频临时存储在服务器<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>生成的视频可选择下载或上传到云端<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>如 AWS S3<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg><h-char class=bd bd-beg>
  • 输出格式<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>支持 MP4 格式<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>分辨率包括 1080p<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>720p<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>比例包括 9:16<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>16:9 等<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

3. 系统功能流程图

以下是用户从上传文件到生成视频的核心流程<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

  1. 上传照片与视频

    • 用户通过前端界面上传照片和视频片段<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>支持拖拽上传<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
    • 后端接收文件并存储<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>同时解析文件以便后续处理<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  2. 时间轴编辑与参数设置

    • 用户在前端调整照片与视频的顺序<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>并设置时间长度与转场效果<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
    • 最终生成一个配置文件<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>JSON<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg><h-char class=bd bd-beg>传递到后端<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  3. 视频拼接与转场处理

    • 后端通过 FFmpeg 根据用户配置<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>完成照片与视频的拼接与转场特效处理<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
    • 如果用户添加了背景音乐<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>系统会自动调整音乐长度<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
  4. 实时预览与导出

    • 前端调用后端生成的实时预览片段<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>用户确认无误后<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>生成最终视频文件<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>
    • 用户可选择下载视频或直接分享至社交媒体<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

关键技术实现

1. 视频拼接与转场<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>FFmpeg 的使用

FFmpeg 是多媒体处理的强大工具<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>可以高效完成视频拼接<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>转场<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>比例调整等任务<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>以下是一些关键操作的实现<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

图片转换为视频

将一张图片转换为 5 秒的视频<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">ffmpeg -loop 1 -i photo1.jpg -c:v libx264 -t 5 -pix_fmt yuv420p photo1.mp4

拼接图片与视频

将图片和视频合并<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>添加淡入淡出转场效果<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">ffmpeg -i photo1.jpg -i video1.mp4 -filter_complex \
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"[0:v]fade=t=out:st=4:d=1[v0]; \
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> [1:v]fade=t=in:st=0:d=1[v1]; \
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> [v0][v1]concat=n=2:v=1:a=0[out]" \
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">-map "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"[out]" output.mp4

背景音乐嵌入

将背景音乐嵌入视频<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>并调整音量<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight bash"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">ffmpeg -i output.mp4 -i music.mp3 -filter_complex \
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"[1:a]volume=0.5[a1]; [0:a][a1]amix=inputs=2:duration=shortest" \
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">-final_output.mp4

2. 时间轴编辑功能

时间轴的实现基于前端框架<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>如 React<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg><h-char class=bd bd-beg>通过拖拽操作生成一个 JSON 格式的配置文件<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>示例如下<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"highlight json"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"code"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">{
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"attr"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"timeline""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">: "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">[
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">{ "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"attr"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"type""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">: "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"photo""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">, "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"attr"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"file""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">: "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"photo1.jpg""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">, "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"attr"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"duration""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">: "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"number"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">5 "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">}"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">,
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">{ "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"attr"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"type""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">: "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"video""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">, "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"attr"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"file""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">: "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"video1.mp4""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">, "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"attr"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"duration""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">: "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"number"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">10 "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">}
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">]"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">,
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"attr"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"transitions""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">: "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"fade""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">,
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"attr"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"audio""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">: "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"music.mp3""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">,
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"attr"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"resolution""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">: "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"1080p""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">,
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"> "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"attr"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"aspect_ratio""bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">: "bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"string"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"9:16"
"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"line"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">"punctuation"bd bd-beg">"bd-box"bd bd-beg">">"bd bd-beg">">}

后端根据此配置文件<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>按照顺序拼接内容生成最终视频<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>


结语<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>工具的价值与展望

这款工具的设计目标是通过高效<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>直观的方式<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>帮助街拍摄影师和社交媒体创作者快速完成视频编辑<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>降低技术门槛<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>从灵感到实现<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>我们从用户需求出发<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>结合开源技术<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>>如 FFmpeg<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg><h-char class=bd bd-beg>打造了一款轻量级的视频剪辑工具<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>

未来<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>我们可以进一步优化该工具<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>比如加入 AI 场景分析<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>自动匹配转场效果<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>或提供更多的模板功能<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>让用户创作更加得心应手<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>对于街拍爱好者来说<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>这款工具将成为他们分享视觉故事的最佳助手<span class=<h-char class=bd bd-beg>bd-box<h-char class=bd bd-beg>><h-char class=bd bd-beg>