自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(100)
  • 收藏
  • 关注

原创 FreeRTOS task 源码解析

FreeRTOS 本质上就是有很多的 List 组成,所以学习之前最好要对 FreeRTOS 中的链表要有所了解,可以参考:FreeRTOS 列表 List 源码解析源码都在 task.c 中一、基本结构和变量1、TCB_t首先来看一下一个任务的结构:typedef struct tskTaskControlBlock {

2024-11-11 15:52:19 1076 3

原创 BLE 协议之 GATT

GATT):通用属性, 低功耗蓝牙的设备之间的通信协议。GATT 使用 ATT 协议, 定义了一套服务框架,用于发现、读写、通知、广播信息的配置。角色的定义Client:主要向服务器发送命令和请求,接收服务器的响应Server:接收命令和请求,发送响应Service服务是完成特定功能或特性的数据和相关行为的集合。在 BLE 从机中,通过有多个服务,例如电量信息服务、系统信息服务等,每个service中又包含多个特征值。每个具体的特征值才是 BLE 通信的主题。

2024-11-07 16:11:20 1261 1

原创 BLE 协议之 ATT

ATT) ,BLE 属性协议,它是处于L2CAP协议层与GATT之间的一层属性操作协议,用于在一对蓝牙设备之间发现、读取、写入属性。这一层的关键词是Attribute属性一个属性就是一条数据,属性是 BLE 数据提供单元,也是蓝牙空中传播数据的最上层,BLE 开发过程中接触最多的就是这一层。属性协议允许称为服务器的设备向称为客户端的对等设备公开一组属性及其相关值。服务器公开的这些属性可以被客户端发现、读取和写入,并且 可以由服务器指示和通知。属性类型,通过UUID表示属性类型指定属性表示什么含义。

2024-11-05 18:44:25 1513 1

原创 Git 查错记录

本文记录本人了最近在 Git 开发遇到的一些问题。

2024-11-03 20:18:13 1180 2

原创 【STM32】通过 DWT 实现毫秒级延时

在 FreeRTOS 中,SysTick被用于作为调度器的一部分进行任务调度,那么如果我需要使用软件模拟通信,例如软件 I2C,需要使用 delay,就无法使用 SysTick 实现的 delay。因此,这里提供一种基于 DWT 实现的 delay。

2024-11-02 11:03:57 1356 3

原创 BLE 协议之 L2CAP

一条是无连接的广播通道,天高任鸟飞另一条是基于连接的数据通道,是一个点对点()的逻辑通道。广播通道暂且不提,这个数据通道(后面简称逻辑通道,只有一条,而要利用它传输数据的上层应用却不止一个(例如上图中的 ATT 和 SMP),怎么复用?所能传输的有效 payload 长度最大只有 251bytes,怎是否意味着上层应用每次只能传输少于这个长度的数据?(显然不能!仅提供了简单的应答和流控机制,如果传输的数据出错怎么办?协议信道复用(

2024-11-01 18:49:31 1265 1

原创 BLE 协议之传输层

该图展示了两个设备之间的数据传输路径。Host 通过HCI Driver和Controller硬件上的交换数据和命令,这就是 HCI 的功能。HCI提供了一种统一接口用来访问,控制Controller,传输层是透明的,独立于底层传输技术,并且无需关系Host传输给Controller的数据是什么内容.在HOST与Controller之间,以Command与Event命令方式进行传输。Host发送Command信息到ControllerController将和Params以Event的形式返回给Host。

2024-10-25 08:42:04 1496 13

原创 STM32 调试之栈回溯和 CmBacktrace 的使用

上图将通用寄存器分为 low register 和 high registers 就是根据指令集来说的,对于 Thumb 指令,是 16 位的,只能访问到 low register,也就是 R0-R7,而对于 32 位的 Arm 指令,是所有的指令都可以访问到。在不同的模式下,R0-R12、SP、LR 是各有一份的,所以这样算下来,总共是 32 个寄存器,但是在不同的模式下,并不能完全看到这 32 个寄存器的状态,只能看到其中的一部分。栈中数据和前面提到的寄存器是对应的,现在 SP 指针指向了地址。

2024-10-24 00:35:16 4361 5

原创 动态链接过程分析

静态链接得到的可执行程序,被操作系统加载之后就可以直接执行。因为在链接的时候,链接器已经把所有目标文件中的代码、数据等 Section,都组装到可执行文件中了。并且把代码中所有使用的外部符号(变量、函数),都进行了重定位(即:把变量、函数的地址,都填写到代码段中需要重定位的地方),因此可执行程序在执行的时候,不依赖于其它的外部模块即可运行。这里的前提是可执行文件是可写的。而对于动态链接来说,在编译阶段,仅仅是在可执行文件或者动态库中记录了一些必要的信息。

2024-10-23 09:12:52 2871 6

原创 静态链接过程分析

这样,通过两个重定位操作,main.c的两个外部符号就解决了地址重定位问题。中间圈出的两个数据和前面计算的是一样的!以上就是静态链接过程中地址重定位的基本过程,与动态链接相比,静态链接还是相对简单很多。

2024-10-22 12:18:54 3053 12

原创 ESP32-IDF 非易失存储 NVS

NVS(,非易失存储),意思是掉电后能依然能持久化保存数据。在我们应用 NVS 时,一般用于存储一些配置数据、状态数据等,一般不会用来存储存放大量的数据量。在嵌入式系统中,NVS 主要是在 Flash 进行键值对的存储。举个例子,假设我们要把东西存到 Flash 中,按照底层的操作习惯,我们要先指定一个地址,然后对这个地址执行擦除操作,然后才能写入;读取的时候也需要根据这个地址,然后指定读取长度。如果我们要存的项比较多,又在代码中比较分散,我们对 Flash 的地址就很难管理。

2024-10-21 00:18:18 4203 27

原创 ESP32-IDF 分区表

使用时要添加头文件。每片 ESP32-C3 的 flash 可以包含多个应用程序,以及多种不同类型的数据(例如校准数据、文件系统数据、参数存储数据等)。因此,我们在 flash 的 默认偏移地址 0x8000 处烧写一张分区表。分区表的长度为 0xC00 字节,最多可以保存 95 条分区表条目。MD5 校验和附加在分区表之后,用于在运行时验证分区表的完整性。分区表占据了整个 flash 扇区,大小为 0x1000 (4 KB)。因此,它后面的任何分区至少需要位于 (默认偏移地址) + 0x1000 处。

2024-10-20 08:18:19 5222 5

原创 ESP32-IDF 通用定时器 GPTimer

*!/*!/*!/*!struct {/*!/*!} flags;/*!clk_src:时钟源direction:计数方向(如递增、递减):计数器分辨率(工作频率),以 Hz 为单位,因此,每个计数滴答的步长等于()秒:GPTimer 中断优先级,如果设置为 0,驱动程序将尝试分配优先级相对较低的中断 (1,2,3)flags:设置为 1,定时器中断号可以与其他外设共享:设置为 1,驱动程序会在进入睡眠模式前备份并在恢复时恢复 GPTimer 的寄存器。

2024-10-19 08:33:28 4682 18

原创 ESP32-IDF USART 专题

typedef struct { int baud_rate; /*!< UART baud rate*/ uart_word_length_t data_bits; /*!< UART byte size*/ uart_parity_t parity; /*!< UART parity mode*/ uart_stop_bits_t stop_bits; /*!< UART s

2024-10-18 09:59:03 4330 10

原创 ESP32-IDF GPIO 专题

API 参考路径。ESP-IDF由多个组件组成,组件中包含专门为 ESP 芯片编写的代码或第三方库(即第三方组件)。对于某些第三方库,ESP-IDF提供专用的包装器和接口,以简化对第三方库的使用,或提高其与ESP-IDF其他功能的兼容性。某些情况下,第三方组件将直接呈现底层库的原始 API。

2024-10-17 08:58:05 5230 17

原创 CMake 教程(三)添加库的使用要求

目标参数的使用要求可以更好地控制库或可执行文件的链接和包含行,同时还能在 CMake 内部更好地控制目标的传递属性。中的代码,以使用现代 CMake 方法。我们将让我们的库定义自己的使用要求,以便在必要时将它们传递给其他目标。,并输入目标库的名称。在大型项目中,手动指定库依赖关系的传统方法很快就会变得非常复杂。请注意,使用这种技术,我们的可执行目标要使用我们的库,唯一要做的就是调用。的任何人都需要包含当前源代码目录,而。再按照上一节的方法来编译运行,效果一致。的使用要求,我们可以安全地从顶级。

2024-10-16 14:20:47 3908 8

原创 CMake 教程(二)添加库

在第一节中,我们已经了解和实现了通过 CMake 来创建一个基本项目。本节我们将通过两个实例来学习如何在项目中创建和使用库。

2024-10-15 17:45:00 6161 8

原创 CMake 教程(一)初识 CMake

要启动项目,我们使用project()命令来设置项目名称。每个项目都需要此调用,并且应在之后立即调用。正如我们稍后将看到的,此命令还可用于指定其他项目级别信息,例如语言或版本号。[VERBATIM]

2024-10-14 21:36:44 6736 20

原创 Cortex-M 内核的 OS 特性

PendSV典型使用场合是在上下文切换时(在不同任务之间切换)。上下文切换的本质就是保存当前执行现场 A,切换到另一个任务 B 里面。切换回来时又要恢复执行现场 A(将一系列的寄存器入栈、出栈)。由于PendSV的特点就是支持缓期执行,所以 RTOS 可以利用它这个特点,进行任务调度过程的上下文切换。而为什么要使用缓期执行的特点来进行上下文切换呢?简单的说就是任何 RTOS,都需要尽量不打断外设中断。执行一个系统调用系统滴答定时器 SYSTICK 中断,触发了任务的调度。

2024-10-13 13:08:07 8073 16

原创 DMA 详解

DMA,直接存储器访问)顾名思义,就是绕开 CPU 直接访问 Memory。在计算机中,相比 CPU,Memory 和外设的速度是非常慢的,因而在 Memory 和 Memory (或者 Memory 和外设)之间搬运数据,非常浪费 CPU 的时间,造成 CPU 无法及时处理一些实时事件。因此,工程师们就设计出来一种专门用来搬运数据的器件——DMA 控制器(DMAC),协助 CPU 进行数据搬运。

2024-10-10 18:35:39 7637 10

原创 STM32 位带操作

如果你学过 51,是否还记得你是如何点亮的 led?// 控制到 P2.0 脚LED1 = 0;// 输出一个低电平通过简单的两句话就可以点亮一个 led 了。这就是位带()操作,支持位带操作后,可以使用普通的加载/存储指令来对单一的比特进行读写。而我们也知道,在 STM32 中并不能直接操作寄存器的某一个 Bit 位,而只能通过字来读写寄存器,例如:那能否实现 51 类似的 GPIO 控制功能,能够直接操作位?

2024-10-08 14:44:37 9445 24

原创 Cortex-M3/M4/M7 芯片 Fault 分析原理与实战

HardFault(硬件错误)是一类在嵌入式系统开发中较为常见的系统异常,优先级仅低于复位和 NMI(不可屏蔽中断)。当系统运行过程中遇到了某些错误时程序就会跳转至函数中,引发程序故障进而影响程序的正常运行。HardFault(硬件故障):默认异常,由于异常处理过程中的错误或由于任何其他异常机制无法管理异常而触发。MemManage(内存管理故障):检测内存管理单元(MPU)中定义的区域的内存访问违规;例如,在一个只有读/写访问权限的内存区域中执行代码。BusFault。

2024-10-07 19:38:58 11435 14

原创 基于 STM32F407 的 SPI Flash下载算法

本文将介绍如何使用 MDK 创建STM32F407的SPI Flash下载算法。其中,SPI Flash芯片使用的是W25Q128,其相关操作源码可以参考STM32 通过 SPI 驱动 W25Q128,本文所使用的驱动 SPI Flash 的 API 和里面是一样的。单片机的 Flash 下载算法是一个 FLM 文件,FLM 通过编译链接得到,其内部包含一系列对 FLASH 的操作,包括初始化、擦除、写、读、校验等等操作。想要制作下载算法,先要了解下载算法的工作原理。下载工具(比如jlink。

2024-10-06 17:09:25 11911 20

原创 分散加载文件 scatter files

当链接器创建镜像文件时,它会创建一些 ARM 预定义的与域或者节相关的符号。这些符号就代表了链接器创建创建镜像的依据。链接器定义了一些 ARM 保留的符号,我们可以在需要时访问这些符号。这些符号是包含$$字符序列的符号以及所有其他包含$$字符序列的外部名称。我们可以导入这些符号地址,并将它们作为汇编语言程序的可重定位地址使用,或者将它们作为 C 或 C++ 源代码中的extern符号来引用。如果使用--strict编译器命令行选项,则编译器不接受包含的符号名称。要重新启用支持,请在编译器命令行中包含。

2024-10-02 14:39:55 14200 12

原创 ROM、RAM 和 Flash 的区别

在计算机的组成结构中,有一个很重要的部分,就是存储器。存储器是用来存储程序和数据的部件,对于计算机来说,有了存储器,才有记忆功能,才能保证正常工作。存储器的种类很多,按其用途可分为主存储器和辅助存储器,主存储器又称内存储器(简称内存),辅助存储器又称外存储器(简称外存)。外存通常是磁性介质或光盘,像硬盘,软盘,磁带,CD 等,能长期保存信息,并且不依赖于电来保存信息,但是由机械部件带动,速度与CPU相比就显得慢的多。

2024-10-02 10:12:17 12333 4

原创 基于 STM32F407 的串口 IAP

STM32 芯片启动过程。从地址取出 MSP(主堆栈寄存器)的值从地址取出 PC(程序计数器)的值然后取出第一条指令执行不过,STM32 比较特殊,它对地址做了一个重定向(由 MCU 启动配置决定的),一般它是将地址映射到从地址取出 MSP(主堆栈寄存器)的值从地址取出 PC(程序计数器)的值然后取出第一条指令执行为什么要设置到,而不直接使用?

2024-10-01 16:39:05 15541 15

原创 hex 文件和 bin 文件剖析

二进制文件()是一种以二进制形式存储的计算机文件,其中的数据以字节为单位进行编码。二进制文件可以包含任意类型的数据,如图像、音频、视频、可执行文件等。与之相对的是文本文件,文本文件使用字符编码(如 ASCII 或 Unicode)表示数据。十六进制文件(Hex File)是一种特殊的二进制文件,其中的数据以十六进制表示。每个十六进制数对应 4 个二进制位,因此可以更直观地查看和编辑二进制数据。十六进制文件常用于存储和传输机器码(即可执行文件),特别是在处理嵌入式系统中常见的固件或软件升级时。

2024-09-30 11:03:05 17165 20

原创 浅析 Keil 中的 sct 文件

当工程按默认配置构建时,MDK 会根据我们选择的芯片型号,获知芯片的内部 FLASH 及内部 SRAM 存储器概况,生成一个以工程名命名的后缀为*.sct的分散加载文件(),链接器根据该文件的配置分配各个节区地址,生成分散加载代码,因此我们通过修改该文件可以定制具体节区的存储位置。可以设置源文件中定义的所有变量自动按地址分配到外部 SDRAM,这样就不需要再使用关键字按具体地址来指定了;

2024-09-29 15:29:08 16337 14

原创 FreeRTOS 内存管理源码解析

heap_1.c所实现的内存管理方法十分简单,其可以使用函数来申请内存,一旦申请成功了,便无法被释放。其实现大致可以用一句话概括,在堆空间剩余时,按需分割出内存,并记录已用的内存大小。heap_1.c使用的内存管理算法虽然简单,但对于许多嵌入式应用场景是适用且有效的。与heap_1.c不同,heap_2.c允许使用函数来释放申请的内存,其算法原理是将空闲堆分为若干个大小不等的内存块,并将其按大小排序,使用单向链表连接起来。申请内存时,便从这些链表中寻找最小可满足申请需求的内存块进行分配。

2024-09-28 13:29:24 17338 28

原创 Git 基本操作

由上图所示,分支 cherry 的 commit bf221cb05,被复制到分支 master,并创建了 1 个新的提交 93cfeef。如果你的远程仓库已经是创建好的,并且要提交的分支上有内容的话(push 时会提示远程库与本地库不一致造成的错误,如下图),要先。当我们不想要之前提交的修改时,就会用到这个命令。软重置会将 HEAD 移至指定的提交(或与 HEAD 相比的提交的索引),而不会移除该提交之后加入的修改!Git 管理项目时,文件流转的三个工作区域:Git 的工作目录,暂存区域,以及本地仓库。

2024-09-26 15:53:21 18937 20

原创 STM32 时钟树(基于 STM32F407)

STM32 内部也是由多种多样的电路模块组合在一起实现的。当一个电路越复杂,在达到正确的输出结果前,它可能因为延时会有一些短暂的中间状态,而这些中间状态有时会导致输出结果会有一个短暂的错误,这叫做电路中的“毛刺现象”,如果电路需要运行得足够快,那么这些错误状态会被其它电路作为输入采样,最终形成一系列的系统错误。

2024-09-25 15:32:02 21630 26

原创 STM32 map 文件浅析

map文件是编译器链接时生成的一个文件,它主要包含了交叉链接信息。通过.map文件,我们可以知道整个工程的函数调用关系、FLASH和RAM占用情况及其详细汇总信息,能具体到单个源文件(.c/.s)的占用情况,根据这些信息,我们可以对代码进行优化。

2024-09-24 21:48:08 22127 23

原创 LVGL 控件之消息框(lv_msgbox)

lv_objlv_btnlv_label和部件,示意图如下所示:消息框充当弹出窗口。它们由一个内容区域构建而成,该区域有一个辅助工具用于添加文本,一个可选的头部(可以包含标题、关闭按钮和其他按钮),以及一个可选的底部配有按钮。文本将被自动折行为多行,并且高度将被自动设置。如果手动设置了高度,内容将变为可滚动的。消息框可以是模态的(阻止对屏幕其余部分的单击) 或者不是模态的。

2024-09-24 19:31:30 1771 5

原创 STM32 通过软件模拟 I2C 驱动 24Cxx 系列存储器

下表是AT24CXXX 的容量AT24C01,AT24C02,AT24C04,AT24C08,AT24C16,AT24C32,AT24C64,AT24C128,AT24C256… 不同的 xxx 代表不同的容量。AT24CXXXbit容量Byte容量AT24C011Kbit128ByteAT24C022Kbit256ByteAT24C044Kbit512ByteAT24C088Kbit1024ByteAT24C1616Kbit2048ByteAT24C3232Kbit。

2024-09-23 12:34:28 22912 43

原创 STM32 通过 SPI 驱动 W25Q128

// ctl_spi.h#ifndef __CTL_SPI_H#define __CTL_SPI_Hvoid spi_init(void);uint8_t spi_read_write_byte(uint8_t tx_data);#endif /* __CTL_SPI_H */

2024-09-21 13:33:00 24173 28

原创 BLE 协议之链路层

在BLE 协议之物理层一文中,我简单介绍了 BLE 的物理层。接下来就是链路层(Link Layer)了,它主要的功能,就是在这些上收发数据,与此同时,不可避免的需要控制 RF 收发相关的参数。通道共享仅仅提供了有限的 40 个,而 BLE 中参与通信的实体的数量,肯定不是这个数量级。Link Layer需要解决的共享问题抽象出逻辑链路:通信是两个实体之间的事情,对这两个实体来说,它们希望看到一条为自己独享的传输通道(就是我们所熟悉的 逻辑链路,这也是Link Layer需要解决的可靠传输。

2024-09-20 12:42:30 24201 22

原创 LVGL 控件之仪表盘(lv_meter)

仪表盘部件可以非常灵活地展示数据,其功能包括显示弧形(arcs)、指针(needles)、刻度线(ticks lines)以及标签(labels)。这意味着它可以模拟各种仪表盘样式。:主体背景;:仪表的刻度;:仪表指针;:圆弧。

2024-09-19 19:11:07 26550 12

原创 STM32 芯片启动过程

下面主要讲解从上电复位到 main 函数的过程。初始化中断向量表配置系统时钟调用 C 库函数_main初始化用户堆栈,然后进入main函数至此,启动过程圆满结束!

2024-09-18 16:56:24 30750 27

原创 BLE 协议之物理层

物理层()是 BLE 协议栈最·底层,它规定了 BLE 通信的基础射频参数,包括信号频率、调制方案等。BLE 工作频率是 2.4GHz,它使用 GFSK 频率调制,并使用跳频机制来解决频道拥挤问题。1M Sym/s 的无编码物理层2M Sym/s 的无编码物理层1M Sym/s 的编码物理层其中 1M Sym/s 的无编码物理层与 BLE v4 系列协议的物理层兼容,另外两种物理层则分别扩展了通信速率和通信距离。

2024-09-17 10:34:45 28318 28

原创 结构体内存对齐

int a;char b;char c;char b;int a;char c;思考一下node1和node2的大小分别为多少?我是在 Windows 下 MinGW32 的 GCC 测试的一样的成员属性,但node1只有 8K,而node2的大小却有 12K。由此可见,结构体对齐,实质上就是内存对齐。

2024-09-16 11:54:29 27193 22

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除