ps:梅花项目复现

简介:什么是OTA

OTA(Over-the-Air)是一种通过无线方式进行数据传输和更新的技术,通常用于电子设备(如智能手机、汽车、物联网设备等)的软件、固件或配置更新。OTA可以在设备与服务器之间进行远程传输,用户无需将设备接入电脑或进行有线操作。

在智能手机和其他智能设备中,OTA通常用于推送操作系统更新、安全补丁或应用程序更新。通过OTA,用户只需要通过Wi-Fi或移动网络连接,便能自动接收并安装最新的更新,而无需手动干预。

常见的OTA应用包括:

  1. 操作系统更新:如Android和iOS设备定期进行系统版本更新。

  2. 固件升级:如智能家居设备、路由器、汽车等硬件设备的固件更新。

  3. 软件和应用程序更新:确保设备上的应用保持最新版本。

OTA的优点是便捷和高效,能够确保设备随时保持最新状态,同时减少用户的操作负担。

————————————————

升级流程:

1.制作升级包

2.下载升级包

3.验签升级

4.更新程序

升级流程图:

升级方式:

1.后台式下载

    后台式下载:在升级的时候,新固件在后台悄悄下载即新固件下载属于应用程序功能的一部分,在新固件下载过程中,应用可以正704常使用,也就是说整个下载过程对用户来说是无感的,下载完成后系统再跳到BootLoader程序,由BootLoader完成新固件覆盖老固件的操作。比如智能手机升级Android或者iOS系统都是采用后台式方式,新系统下载过程中,手机可以正常使用。

2.非后台式下载

    非后台式下载:在升级的时候,系统需要先从应用程序跳入到BootLoader程序,由BootLoader进行新固件下载工作:下载完成后BootLoader继续完成新固件覆盖老固件的操作,至此升级结束。早先的功能机就是采用非后台来升级操作系统的,即用户需要先长按某些按键进入bootloader模式,然后再进行升级,整个升级过程中手机正常功能都无法使用

ps:对于设备内存小的设备经常是使用非后台下载

————————————————

创建项目:

注:这个项目是在Linux环境下进行创建展开

为什么需要在Linux下进行编译?

答:超过几万行的代码在win下就不是特别适合了,keil在编译的过程中把所有生成的中间件(.OBJ)放在同一个根目录下,会导致一个问题。

举例说明:在main目录下,新建一个tool.c文件,又在ringbuff文件下新建一个tool.c文件这时候你编译就会报错,说你有同名的obj文件,必须改掉其中一·个名字。

最大的问题就是:KEIL在编译时候,不支持目录结构!!!

最好用的配置:VSCODE(SSH远程链接Linux)

+makefile+gcc+scons+cmake+ninja+clang+llvm+python(辅助编译)+bash

————————————————

如何配置需要的运行环境:拿WSL连接举例子

ps:需要点小魔法

开始我们先打开任务管理器,开启虚拟化,如果未开启,我们需要进入bios命令开启

我们之后要打开程序和功能选项,再点击侧边的启用或者关闭windows功能,最后将圈出两个启动,最后重启电脑

下一步打开命令控制行

依次:检查版本更新(命令:wsl --update),再查看可以安装的Linux版本(命令: wsl --list --online)

之后我们选择 Ubuntu-20.04安装(命令: wsl --install Ubuntu-20.04)

安装好之后跟着流程创建名字和密码即可

如果要卸载,直接查询拥有的子系统版本,然后命令wsl --unregister xxxx即可

——————————————

开始在Linux环境下进行创建工程

如果对Linux没有概念,也不懂怎么操作的可以看看黑马的课,看完第二章即可,这样有个系统 的认识↓连接

————————————

第一章-01-操作系统概述_哔哩哔哩_bilibili

————————————

首先我们打开vscode通过远程连接,选择wsl直接连接我们直接进入我们需要的子系统

在通过命令行创建文件夹

后面就是日常的创建工程添加库文件,配置json文件,这里需要注意的是我们需要手动添加一个.ld文件(Linker Script(链接脚本))

什么是.ld文件,为什么我们用keil的时候不需要?

  .ld 文件是 Linker Script(链接脚本),主要用于指导linker在链接阶段确保生成的可执行文件能够正确地加载到目标芯片的内存中。这个文件定义了如何将编译后的程序(包括 .text.data 等段)加载到指定的内存位置(如 Flash 和 RAM)。(不同类型的芯片.ld文件自然不同)。我们再通过makefile来使用GCC编译器调用链接器根据LD文件提供的内存布局、符号地址、段的分布等信息来生成对应芯片可以使用的可执行文件

    在keil创建工程的时候他自己会生成分散加载文件(scatter file)是自动生成的,你不需要手动添加,除非有特殊需求。(keil中没有make和makefile,可视化的界面就完成了对编译器和连接器的调用)

  • Keil 使用的是 .sct 文件(scatter-loading file),功能和 GCC 的 .ld 文件相似:指定代码和数据的内存布局。

  • CubeMX /keil会根据你选的芯片、外设、内存大小等自动生成这个文件(例如 stm32xxxx_flash.sct)。

怎么获取.ld文件?

我们使用CubeMX创建工程直接拿过来用即可,选择对应芯片类型,直接选择创建工程即可

直接获得

配置gcc编译器

谷歌搜索arm-none-eabi-gcc

查看乌班图下架构环境选择对应gcc

下载后直接拖人home目录下wsl文件里面

这里不能再通过图形界面解压了

我们需要通过终端下载bzip2

命令:sudo apt install bzip2

之后解压压缩包

命令:tar xjvf (压缩包名称)

后面将其移动到toolchain目录下

再配置json文件路径

  这里我们可以cd到bin目录下,ls -l一下文件,查看时候具有权限,ok都是具有wr(读写)x(execute)的这样就导入成功了!!!!

ps:一个坑,有些同学这些还是发现无法跳跳转,那是因为这里使用的相对路径(绝对路径没问题),使用相对路径需要加上${workspaceFolder}/意思是以这个项目目录为基点,查找文件!!

那么为什么"includePath"里面不用加,直接相对路径就可以呢??

那是因为

——————————————————————

什么是make,makefile,cmake,CMakeList.txt他们都有什么作用?

  • Makefile 是一个脚本文件,里面写着项目的“编译规则”。

  • 它本质上就是告诉 make 工具:“哪些源文件要编译,编译用什么命令,生成什么文件,文件之间的依赖关系”。

  • make自动化构建工具,专门用来读 Makefile,然后自动执行里面写的命令

  • make 自己不编译任何东西,也不是编译器,它只是“调度员”——让系统去执行你指定的命令。

为什么我们在使用keil5的时候直接点击编译就ok了?

Keil5通过图形界面(如Options for Target)让用户设置编译器选项、头文件路径、库文件、链接脚本等,自动将这些配置转换为底层命令,无需手动编写构建规则。

但是在Linux中,开发者通常使用GCC、Clang等独立工具链,需要手动编写Makefile来定义

简单来说,make就是用来把一系列源文件(头文件,库文件等等需要用到的文件)来进行批处理,本身没有编译和连接的功能,我们需要用编写makefile来操作make进行编译和连接,make就相当于我们的打工仔。

但是makefile文件在源文件非常多时也很复杂,这时候我们需要用cmake来书写makefile文件,那我们怎么使用cmake呢?这时候就需要使用CMakeList.txt文件了!!

下面我们看看流程图

那么make、makefile、编译器(gcc)和链接器是什么关系呢?

总结:流程是👇

你写 Makefile
   ↓
make 读取 Makefile
   ↓
make 执行里面的 gcc(和 ld)命令
   ↓
gcc 编译源文件
   ↓
ld 链接生成最终的可执行文件
 

书写Makefile文件

没有一点基础的可以先看看这个视频,还有后面的文档教程,同时makefile只需要你会改就行,能用cmake,不需要花费太多时间在这上面

——————————

20分钟Makefile光速入门教程_哔哩哔哩_bilibili

概述 — 跟我一起写Makefile 1.0 文档

——————————

下面开始我们的make

首先安装make

这先搁置......博主这里看makefile自己也比较难配置,后面回过头再补

——————————

为什么vscode通过wsl来连接Linux,下创建嵌入式工程,请问,json文件里面也要配置路径和定义,makefile文件中也要,都是什么作用呢?

回答:.json文件主要是用于增强开发体验,比如智能提示、编译任务、调试器对接等。不是必须的不会影响生成启动文件,但是makefile是必须的!!!

那么既然vscode只是编辑器,为什么还需要setting.json文件来定义识别.h文件呢?

这是因为 .h 文件内容本身无法明确区分是 C 语言还是 C++。但:

  • C 语言中的头文件可能使用宏定义、结构体、函数声明等纯 C 特性

  • C++ 则会包含类、模板、命名空间等复杂结构

如果 VS Code 插件判断错了语言模式,它就会用错误的方式来分析 .h 文件,导致:

  • 智能提示失效

  • 错误提示频繁(如 extern "C" 在 C 中非法)

  • 跳转和宏解析混乱

所以 .vscode/settings.json 中的 "files.associations" 设置就是为了告诉语言服务插件:

“这个文件虽然是 .h,但你一定要用 C 语言的方式去分析它,不要当成 C++。”

最后给下settting.json的配置

——————————————

固件升级

什么是固件

固件是指嵌入在硬件设备中的软件,负责设备的基本操作和控制。

固件升级是指通过更新设备的固件,以修复错误、提升性能或增加新功能!

固件升级方法

1.使用专用的烧录工具:利用厂商提供的专用工具进行固件烧录,比如JLINK、STLINK等,但终端客户没有相应的设备,且需要一定的专业技能才能完成烧录,因此对普通用户并不适用

2.通过OTA(Over-The-Air)无线升级: 通过无线网络(WIFI/BT)更新固件,更便捷,但需要对应的蓝牙和WIFI功能,通常在消费级产品上应用

3.利用有线方式升级: 使用串口或USB连接电脑,通过专用软件进行固件升级,使用较为麻烦,但连接升级稳定,通常用在工控领域上

手机升级步骤

智能手机的固件升级方式主要包括线刷和AB分区两种方式

线刷升级

线刷是指通过数据线将手机连接到电脑,利用专用工具进行图件升级

1、下载固件包
2、安装手机驱动程序和刷机工具
3、关闭手机,并按特定的按键组合(如首量下键+电源键)进入刷机模式
4、将手机通过数据线连接到电脑
5.打开剧机工具,加载下载的面件包
6、开始刷机过程,工具会将断的国件用以手机存储
7、刷机完成后,手机会自动重用并选行新的国件

优点
    可恢复系统崩溃的设备
    提供较高的控制权,可以进行深度的系统修改
缺点
   过程复杂,对普通用户不友好
   有一定的风险,可能导致设备无法后规

AB分区升级

AB分区是一种无缝升级机制,利用两个系统分区(A和B)来实现固件的女全更新

1.系统自动下载适用于手机型号的升级包到备用分区(如当前运行在A分区,则下载到B分区)

2、系统在后台将升级包安装到备用分区,用广可以继续使用设备而不受影响

3.安装完成后,系统重启并切换到备用分区(B分区》,还行新的固件

4.如果新的固件出现问题,可以自动回浓到原来的分区(A分区)

 优点

    用户体验好,升级过程不影响设备使用

    安全性好,具有自动回滚机制

缺点

    占用较多存储空间

    硬件需要支持MMU功能

STM32的固件升级方式

利用官方的DFU升级

特点

    使用USB接口进行升级,速度较快

    不需要额外的硬件设备,只需通过USB连接即可完成

 适用场景

    产品量产:工厂可以批景更新设备固件,稳定且高效

通过烧录工具升级

特点

    通过专用的烧录工具《如s--.nk、aunk)进行升级

    速度快,通过,AC比者SWD接口烧录

    可以进行低级调试和编程,遇用一开发和生产测试

适用场景

    工厂生产线:大规模生而过程中
    开发阶段,开友人员可以使用就录一具进行调试和国件烧录

通过OTA升级

  • 特点

    • 无线升级,无需物理连接设备,用户体验好

    • 可以远程更新设备固件,适用于部署在远程或不易接触的设备

    • 升级过程中需要确保连接稳定

    • bootloader对升级失败有极强的兼容性

  • 适用场景

    • 远程设备:部署在偏远地区或难以接触的设备,如物联网设备

    • 现场更新:需要在现场进行固件更新,但不方便进行有线连接的设备

通过串口升级

  • 特点:

    • 使用串口连接电脑和设备进行升级,开发简单快速

    • 需要编写专门的Bootloader来支持串口升级

  • 适用场景:

    • 现场调试:开发人员可以在现场快速更新和调试固件

    • 小批量生产:不需要大规模生产设备的情况下,通过串口进行固件升级

    • 总结

    • 官方的DFU升级: 适用于开发和量产,但不适用于终端产品升级

    • 烧录工具升级: 用于生产线和开发调试,调试场景居多

    • OTA升级: 无线更新,适用于远程和现场设备,通常应用在消费电子上

    • 串口升级: 简单易行,适用于开发和小批量生产,工业场景使用较多

STM32制作固件升级

首先的芯片上电启动流程:

ps:下面都是我自己的理解集合,会写的细一些

流程:BOOT选择启动位置,初始化PC,SP指针,让后进入复位中断(初始化时钟,执行_main函数),最后进入main函数,下面我们来一一拆解。

注:每一条汇编语句会占四个字节

一.BOOT选择

BOOT有三种模式,分别代表了启动模式,也就是启动位置,我们通常是模式1也就是主闪存启动(flash)

ps:不同的启动位置都有自己的中断向量表

二.开始上电

1.芯片第一条指令肯定从0x00000000位置读取(为什么,因为这是ARM规定的,ST买了ARM的内核,但没权限改ARM内核代码(因为加密混淆了),所以想从0800000开始的话,就只能通过内核以外的手段实现),但是根据BOOT模式的不同,该地址保存的地址也不同,比如BOOT0设置为0,从flash开始执行,那么就会把0x08000000位置的地址映射0x00000000,将其中包含的地址放入SP指针中(这一波是硬件自动完成)下面是中断向量表

2.然后将0x08000004位置的地址映射0x00000004处,PC指针开始执行中断处理程Reset_Handler,这里面包括了:

调用 SystemInit:配置系统时钟等硬件。

跳转到 __main:进入 C 运行时环境。

SystemInit 是 ST 库提供的函数,负责初始化时钟、外设等,比如设置系统时钟为 72MHz(F4系列是168MHz)

__main 是 C 运行时库的入口,它会初始化全局变量(复制 .data 段(包含已初始化的全局变量)到 SRAM,清零 .bss 段(包含未初始化的全局变量)),然后跳转到用户写的 main 函数,至此头文件初始化完成

——————————

再说的细一点启动流程:启动文件,bootloader,主程序的关系

启动文件就是startup.s汇编文件,他是第一个执行的文件,他会根据启动位置的不同,在不同启动位置生成不同内容的中断向量表,每个可以启动的位置都有自己的中断向量表,下面的bootloader(位置0x1FFFF000)代码

bootloader和主程序的关系就是储存在不同的位置,如果BOOT0设置为1,程序会将0x00000004位置的地址映射0x1FFFF004处执行对应的配置,根据是否要升级主程序,选择对应策略,不升级就会跳转回主程序的Reset_Handler,从新配置,之后在进入main函数执行。

实际上在四个地址都储存了__initial_sp,这个挺反直觉的,实际上发生跳转是在0x00000004位置,当然理解为0x00000000直接跳转影响不大

——————————

Bootloader设计特点

  • 功能

    • Bootloader是一个小型的程序,用于引导主程序的启动,并在需要时进行固件升级

    • 通常位于Flash存储的起始地址,并在设备上电或复位时首先运行

  • 设计要点:

    • Bootloader应尽可能小,以节省存储空间

    • Bootloader需要在各种情况下可靠地运行,包括电源波动和中断

    • 能够引导主程序,通过有线方式更新主程序

Bootloader流程图

引导主程序关键步骤

  1. 关闭所有使用到的中断,Deinit所有外设

  2. 从固件地址获取SP和PC指针

  3. 设置PC指针,跳转到主程序的Reset_Handler执行

  4. (接下来是主程序额外增加的步骤)

  5. 设置SCB->VTOR,重新设置中断向量表

升级模式关键步骤

  1. 串口RX中断接收PC发来的数据

  2. 判断接收到一帧完整的数据包

  3. 解析数据包,根据操作指令完成对应的功能

主程序的修改

  1. 设置ROM地址偏移,从0x08010000处开始存放主程序固件

  2. 设置中断向量表地址,使得中断服务程序地址表正确读取

——————————————————————

BootLoader程序现象

下面例子位三秒内通过上位机(pc)软件传入固件升级

————————————————

BootLoader代码分析

注意bootloader在上电过程中参与的时间:bootloader程序的执行是在上电后,先启动启动文件,初始化执行完成Reset Handler后会跳转到 Bootloader,判断是否升级,还是直接执行主程序,但是本人将Bootloader程序放在0x08000000位置,上电后默认执行Bootloader程序。

——————————————

升级方式总结(后面放升级流程图)

整体框架,通过上位机(pc)发送对应通信协议指令,来与下位机交互,实现bootloader升级功能

下面是接收数据之前的逻辑判断,重点的固件升级流程会附上代码解析。

通信协议

————————————

什么是CRC校验

CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,简单来说就是上位机发送数据同时发送计算好的CRC校验码,下位机接收数据后,自己重新计算校验码,对比校验码是否一致,来判断接收数据是否正确。下面是CRC校验的科普视频

[CRC校验]手算与直观演示_哔哩哔哩_bilibili

————————————

代码逻辑

1.一定要使用的中间件ringbuffer

        该程序的下载和接收都是通过串口传输内容,串口的波特率是115200,一位起始位,八位数据位,一位停止位,总共十个数据位,一秒可以传输11520字节的数据。我们使用的F4系列的时钟频率为168MHZ,意味着一秒可以处理168MHZ的汇编指令,一般一句C代码有3~5个汇编指令构成。

        说了这么多,我们要知道通过串口接收数据,每一次接收数据RDR 移位寄存器的内容已传输到 USART_DR 寄存器时对应标志位会置 1,都会触发一次中断,从而触发中断函数,中断函数代码不过5行,大概20条汇编指令。意味着单片机可以一秒内读取8M次数据,频率远远大于串口数据传输频率(0.001152M)。

        所以我们不需要担心串口传输过快导致的数据丢失,而要关注程序延迟导致没有及时读取程序造成的数据丢失。这里我们需要要使用ringbuffer来循环储存数据,给数据一个缓冲区域。

2.如何接收数据和处理数据

        大体逻辑:我们通过串口中断来循环接收数据,每一次接收到完整的数据,就通过opcode来识别处理,我们通过下图的函数一来接收数据,进行初步的数据分类,然后函数二来通过分类进行细致的处理

        函数一如何执行:

        我们首先需要通过创建主结构体来进行数据的初步处理,主结构体里面包括数据暂存结构体数据分类结构体,通过主结构体的bl_state_machine_t(状态机)来判断上位机是传入何种数据,来调整状态机参数,从而进入下一层的处理。

        数据暂存结构体每次执行都会清空,根据状态机不同,来将参数储存到数据分类结构体不同成员中

        数据分类结构体用来储存对应的数据类型,长度,已经数据和CRC校验值,后面再调用函数二中直接根据其中数据进行执行。

        使用结构体可以很好的将程序模块化处理

        使用static关键字,使得函数生命周期结束,数据也能得到保存,同时初始值默认为0,不需要手动初始化

        我们使用标志位fullpkt,只有在取得完整的数据同时通过CRC校验,才能进行数据的执行

举例子:以上位机发送Erase命令演示

        1.上位机发送opcode为BL_OP_ERASE,在bootloader_main函数中,通过rb8_get将数据获取,放入到data中,开始调用函数一(bl_recv_handler)

        2.用static创建静态全局变量,初始值默认为0,且使用对应数据暂存结构体数据分类结构体指针来对主题结构体赋值,将数据存储到数据暂存结构体中

        3.开始执行条件函数,因为初始化都为0,同时设置IDLE状态默认值为0(细节),开始直接执行case BL_SM_IDLE,注意index初始化为0,根据通信协议HEARDER都为长度为1,上面有代码rx->data[rx->index++] = data,index对应的就是数据长度,接收到指定长度后,会置零。这里判断opcode为0xAA确定传输开始,将状态机置为START!!

        4.循环再次运行会次函数,因为状态为START会直接进入pkt的内容填充(最终会把pkt内容全部填充完成),后面执行函数二时候会根据这个opcode选择不同执行命令,此时状态变为opcode

        5.这个阶段会将数据长度信息进行填充,我们可以注意到这里index需要 == 2才行,说明函数循环两次才能进入if语句,我们可以对应通信协议👇,这次会传输两个字节数据。我们这里需要进行长度判断,如果传输数据超长,需要返回储物判断!!!后面进入到PARAM状态直接传输数据

        6.这里不使用index判断是因为,我们不需要管数据长度,只需要依次将数据填充入pkt结构体的数据数组即可,等传输数据长度达到预定长度,进入下一个CRC校验状态。

        ps1:这里使用的index++,是先给pkt->[index]赋值,index数值才会加1,这样当index长度和lengh长度相等时,赋值下一个状态,为什么是相等呢?因为我们正常计数是从1开始,长度假如为10就是十个数,但是数组默认是0开始导致index到9实际上已经放入10个数值了。

        ps2:实际上这里的DATA就是 PARAM并不是什么多出来的东西

        7.进入CRC校验过程,这里实际上是上位机传输一个计算好的CRC数值,我们后面需要受到数据后根据数据大小进行自己计算,算出一个CRC与之相比,相等即是传输正确。

        这里将fullpkt置为true表示固件已经完整接收。

        8. fullpkt = true后我们返回就会出来,执行成功if判断,进入行数二,可以看到函数二是直接使用pkt数据。

        9.假设opcode为BL_OP_RESET,直接跳转目标函数。

        10.我们先看看erase结构体,里面只需要有地址和擦除大小即可调用库函数

        11.进行长度检验,大小,数据擦除位置是否在预设程序范围内,之后进行打开flash锁,进行擦除,上锁。

        ps:这里直接用pkt->param(uint8_t数组),变成为void*类型后,再赋值给结构体(里面成员都是uint32_t),一般来说都是多少类型通过void*转化,再转化回自己类型,类似uint8_t转化为uint8_t,这里我为什么可以?

        指针类型的转化,本质就是判断可以查看的地址范围,如uint8_t的指针,只能查看该地址后一位的数据,如果是uint32_t就可以查看四位的数据,所以我们只需要保证pkt->param[0-3]位的数据,是erase->address需要的数据即可(类似32 位整数 0x12345678 地址内容
0x00    0x12
0x01    0x34
0x02    0x56
0x03    0x78)这种是小端写法,也就是低位字节在低位。

        12.最后上位机会发送启动命令,通过application函数直接启动

        13.boot_application函数需要初始化sp和pc指针,然后关闭所有的中断(会影响跳转主程序),直接运行pc指针指向位置的中断服务程序,主程序开始......

总结        

        我们拿出一条OPCODE指令来走了一遍通信协议和代码逻辑,其他指令也是类似,细节需要自己打磨。

——————————————————————

ESP32C3

芯片介绍

        这一款芯片使用的不是arm架构,而是RISC-V架构,这是一种开源架构,最近很火热,他自带了蓝牙,WiFi,射频等功能

与ARM架构的不同

        使用的开发平台不同,ST系列使用keil开发,ESP系列使用Aeduino或者ESP-IDF开发,这个OTA项目会将ESP作为主机在ESP-IDF平台开发使用,不是再是传统的AT指令从机模式使用,可以看到下面的功能框图也有很大区别👇

什么是 IDF,和 STM32 的标准库/KEIL 什么区别?

同时IDF写的配置文件是 CMakeLists.txt,而不是传统的 Makefile

开始学习esp系列

        进入官网下载资料:

        进入官网 Wireless SoCs, Software, Cloud and AIoT Solutions | Espressif Systems

        找到C3芯片

选择技术说明书

自行对比下和ST系列有哪些区别(大部分都很类似)

下载配置ESP-IDF

下载地址:ESP-IDF Getting Started | Espressif Systems

我们选择自己需要的版本配置,这里我们依旧选择手动安装Linux版本开发,和之前在Linux下完成ST系类一样,我们只需要获取ESP系列的库文件,在Linux先编译完成,最后再用到ESP的硬件进行连接调试

        打开指令中心,切换到ubuntu,在wsl文件夹下,将下面指令全部运行,我们这里悬着ubuntu的版本,检查下是否安装了python 3.0。

        步骤总结第一步是确保你的 Linux 环境有支持 ESP-IDF 全部功能的必需工具和库,第二步按照python,因为idf里面有python小插件辅助编程。第三步直接下载idf。第四步调用.sh文件,用来添加path路径,作用就是让自己按照的idf可以在任何文件夹下进行调用,需要再在输入头文件路径

下面我们下载ESP-IDF,我们先自己兴建文档,在输入下载git命令

————————————————

如果你不会魔法这里解决

我已知的方法有三种:

        1.在Ubuntu里面直接替换源网站,比如替换清华源

        2.通过gitee来把github上的库给自己私有化一个gitee的库,如图下,然后直接下载自己的私有库

        3.第三种就是通过官方自己提供的工具来进行镜像定义,这着重介绍这一种,我们通过gitee上esp官方自己提供的esp-gitee-tools工具仓库,下载好后,调用里面的脚本来完成!!

——————————————

我们先搜索gitee,国内的镜像网站,可以不用魔法,进入搜索esp-idf,一路找下去有个镜像仓库

下面已经提到了将esp-idf工具镜像了

开始实际操作

        1.创建一个空的文件夹来存放 esp-idf SDK 和设置 jihu 镜像环境所需的 esp-gitee-tools 工具

cd esp

mkdir my-esp32c3-boot

cd my-esp32c3-boot

       2. 克隆 esp-gitee-tools 工具


git clone https://gitee/EspressifSystems/esp-gitee-tools.git

        3.运行 jihu-mirror.sh 脚本,设置 jihu 镜像环境

cd esp-gitee-tools

./jihu-mirror.sh set

运行此指令后,以后克隆任意 Github espressif 或 esp-mirror espressif 下的仓库和组件都会自动镜像 URL 链接到 jihu 链接上。例如:

我们先CD回我们创建的文件夹下面,然后执行esp官网的下载指令,可以看到下载速度块很多了

cd ../
git clone -b v5.3.3 --recursive https://github/espressif/esp-idf.git

​​​下载完成后进行工具选择

cd ~/my-esp32c3-boot/esp-idf
export IDF_GITHUB_ASSETS="dl.espressif/github_assets"
./install.sh

注意使用国内下载export指定好国内镜像后,下面的install需要加上工具名称,👇

cd ~/my-esp32c3-boot/esp-idf
export IDF_GITHUB_ASSETS="dl.espressif/github_assets"
./install.sh esp32c3


如果失败

先在主目录里面删除下载目录

 rm -rf ~/.espressif/

./install.sh esp32c3

重新执行一遍
————————————————

添加到 PATH 环境变量

工具也下载好后,直接将这串代码复制过来执行(执行目录必须是esp-idf文件夹下)

这一步是将工具添加到 PATH 环境变量,作用就是允许你在 shell 中直接调用这些工具(在Linux中软件都是安装在文件夹下,但是如果不是使用apt或者yum这类直接下载命令下载的软件,他是不会主动将路径添加到path中,如果你创建了新文件夹,自己还手动安装了软件,就会出现每次调用这个软件需要在前面加一堆路径,然后再调用,非常麻烦。添加到path目录后,直接在任何文件夹下使用软件命令都是可以的。这里的.sh文件集成了添加path的命令,直接调用即可,并让 shell 知道这些工具的存放位置,这样你就不需要每次手动输入完整的路径。你可以简单地通过命令名来使用它们。

例子:如果在自己创建的文件夹下,自己安装了一个软件,不通过apt和yum命令,就是没添加进path路径里面,同时我又在另一个文件夹需要使用这个软件,无需要如何操作呢?

下面是手动添加PATH的例子

永久性添加path-CSDN博客

——————————————

开始测试一个工程

1.将hellow word文件夹复制到当前目录

下面是pytho命令

2.选择目标文件,进入配置界面,按照顺序执行下面命令

进入配置界面

配置好后esc退出,他会让你保存配置,退出后会生成mdk文件

3.开执行,执行下面的命令

下面是生成主程序的目录位置

还给我们介绍了几种烧入方式

到这里我们就完成了环境的配置,后面会转到vscode里面开始配置工程,voscode会把command文件解析,生成对应的vscode文件,优化项目,不然打开会非常卡

compile_commands.json 文件通常是由构建系统生成的,特别是当你使用 CMake 时。这个文件包含了项目中的所有编译命令及其参数,方便像 VSCode 这样的编辑器提供智能提示、跳转、自动完成等功能。它是一个包含项目中所有编译命令的 JSON 文件。

都是camke生成的文件有什么不同

compile_commands.json文件主要起到的是让vscode更好的编辑内容,优化空间,makefile是编译连接阶段的作用

ps:这里肯定有人疑问,为什么用vscode需要添加编译器,.ld连接脚本,手写makefile,这里直接调用idf.py就行?

因为都给你打包好了

——————————

蓝牙(BLE)协议栈

1.先看看不同蓝牙版本区分

经典蓝牙BLE版本区别:【图文讲解】_蓝牙版本-CSDN博客

2.下面这个博客对于BLE(低功耗蓝牙)介绍的很好

BLE低功耗蓝牙技术详解