<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[lhbweilai的博客]]></title><description><![CDATA[]]></description><link>https://blog.csdn.net/lhbweilai</link><language>zh-cn</language><generator>https://blog.csdn.net/</generator><copyright><![CDATA[Copyright &copy; lhbweilai]]></copyright><item><title><![CDATA[QT（简单了解C++）]]></title><link>https://blog.csdn.net/lhbweilai/article/details/169069984</link><guid>https://blog.csdn.net/lhbweilai/article/details/169069984</guid><author>lhbweilai</author><pubDate>Tue, 27 Oct 2026 15:26:26 +0800</pubDate><description><![CDATA[C++ （c plus plus）是一种静态类型的、编译式的、通用的、大小写敏感的、不规则的编程语言，支持过程化编程、面向对象编程和泛型编程。C++ 被认为是一种中级语言，它综合了高级语言和低级语言的特点。C++ 是由 Bjarne Stroustrup 于 1979 年在新泽西州美利山贝尔实验室开始设计开发的。C++ 进一步扩充和完善了 C 语言，最初命名为带类的 C，后来在 1983 年更名为 C++。C++ 是 C 的一个超集，事实上，任何合法的 C 程序都是合法的 C++ 程序。]]></description><category></category></item><item><title><![CDATA[分析FreeRTOS内核对象API的源码实现（八）]]></title><link>https://blog.csdn.net/lhbweilai/article/details/168965992</link><guid>https://blog.csdn.net/lhbweilai/article/details/168965992</guid><author>lhbweilai</author><pubDate>Sun, 25 Oct 2026 17:11:56 +0800</pubDate><description><![CDATA[与中断相关的硬件可以划分为三类：外设、中断控制器、CPU 本身。外设：当外设需要请求 CPU 时，产生一个中断信号，该信号连接至中断控制器。中断控制器：中断控制器是 CPU 众多外设中的一个，它一方面接收其他外设中断信号的输入，另一方面，它会发出中断信号给 CPU。可以通过对中断控制器编程实现对中断源的优先级、触发方式、打开和关闭源等设置操作。在 Cortex-M 系列控制器中常用的中断控制器是 NVIC（内嵌向量中断控制器 Nested Vectored Interrupt Controller）。]]></description><category></category></item><item><title><![CDATA[分析FreeRTOS内核对象API的源码实现（七）]]></title><link>https://blog.csdn.net/lhbweilai/article/details/168561865</link><guid>https://blog.csdn.net/lhbweilai/article/details/168561865</guid><author>lhbweilai</author><pubDate>Fri, 23 Oct 2026 19:06:20 +0800</pubDate><description><![CDATA[FreeRTOS 从 V8.2.0 版本开始提供任务通知这个功能，每个任务都有一个 32 位的通知值，在大多数情况下，任务通知可以替代二值信号量、计数信号量、事件组，也可以替代长度为 1 的队列（可以保存一个 32位整数或指针值）。相对于以前使用 FreeRTOS 内核通信的资源，必须创建队列、二进制信号量、计数信号量或事件组的情况，使用任务通知显然更灵活。按照 FreeRTOS 官方的说法，使用任务通知比通过信号量等 ICP 通信方式解除阻塞的任务要快 45%，并且更加省 RAM 内存空间（使用 GCC ]]></description><category></category></item><item><title><![CDATA[分析FreeRTOS内核对象API的源码实现（六）]]></title><link>https://blog.csdn.net/lhbweilai/article/details/168030843</link><guid>https://blog.csdn.net/lhbweilai/article/details/168030843</guid><author>lhbweilai</author><pubDate>Thu, 22 Oct 2026 16:43:27 +0800</pubDate><description><![CDATA[NULL2101234566789调用xTaskGetTickCount()函数，获取当前系统时间xOptionalValue。pxHigherPriorityTaskWoken 为 NULL（即“申请任务切换回执清单”），该参数在中断中发送命令才起作用。用户指定超时阻塞时间，单位为系统节拍周期(即 tick)。]]></description><category></category></item><item><title><![CDATA[分析FreeRTOS内核对象API的源码实现（五）]]></title><link>https://blog.csdn.net/lhbweilai/article/details/168455012</link><guid>https://blog.csdn.net/lhbweilai/article/details/168455012</guid><author>lhbweilai</author><pubDate>Mon, 19 Oct 2026 23:27:19 +0800</pubDate><description><![CDATA[xEventGroup：事件组控制块，即我们准备要操控这个事件组uxBitsToSet：事件标志位（可以理解为“世界状态位”，也就说传进来的这个数值代表了某个或者多个事件发生了，这个位对应的事件是程序员决定的）*pxListItem：用来代表挂载在该事件组的等待事件发生链表的某个任务节点pxNext：指向等待事件发生链表中的下一个任务节点，即判断完一个任务是否等待该事件后，用pxNext指向这个任务的下一个任务，实现循环遍历。]]></description><category></category></item><item><title><![CDATA[分析FreeRTOS内核对象API的源码实现（四）]]></title><link>https://blog.csdn.net/lhbweilai/article/details/168241573</link><guid>https://blog.csdn.net/lhbweilai/article/details/168241573</guid><author>lhbweilai</author><pubDate>Sat, 17 Oct 2026 13:46:57 +0800</pubDate><description><![CDATA[（2）如果控制块结构体是用于消息队列：uxMessagesWaiting 用来记录当前消息队列的消息个数；如果控制块结构体被用于互斥量的时候，这个值就表示有效互斥量个数，这个值是 1则表示互斥量有效，如果是 0 则表示互斥量无效。（3）如果控制块结构体是用于消息队列：uxLength 表示队列的长度，也就是能存放多少消息；如果控制块结构体被用于互斥量的时候，uxLength 表示最大的信号量可用个数，uxLength 最大为 1，因为信号量要么是有效的，要么是无效的。]]></description><category></category></item><item><title><![CDATA[分析FreeRTOS内核对象API的源码实现（三）]]></title><link>https://blog.csdn.net/lhbweilai/article/details/167589114</link><guid>https://blog.csdn.net/lhbweilai/article/details/167589114</guid><author>lhbweilai</author><pubDate>Wed, 14 Oct 2026 22:33:28 +0800</pubDate><description><![CDATA[队列又称消息队列，是一种常用于任务间通信的数据结构，队列可以在任务与任务间、中断和任务间传递信息，实现了任务接收来自其他任务或中断的不固定长度的消息，任务能够从队列里面读取消息，当队列中的消息是空时，读取消息的任务将被阻塞，用户还可以指定阻塞的任务时间 xTicksToWait，在这段时间中，如果队列为空，该任务将保持阻塞状态以等待队列数据有效。当队列中有新消息时，被阻塞的任务会被唤醒并处理新消息；当等待的时间超过了指定的阻塞时间，即使队列中尚无有效数据，任务也会自动从阻塞态转为就绪态。消息队列是一种异步的]]></description><category></category></item><item><title><![CDATA[分析FreeRTOS内核对象API的源码实现（二）]]></title><link>https://blog.csdn.net/lhbweilai/article/details/167398408</link><guid>https://blog.csdn.net/lhbweilai/article/details/167398408</guid><author>lhbweilai</author><pubDate>Sun, 11 Oct 2026 20:27:45 +0800</pubDate><description><![CDATA[（9）xTaskResumeAll()的回执，如果返回pdTURE意思就是：在调度器挂起期间已经切换过一次任务了，返回pdFALSE意思就是调度器挂起期间没有切换过任务（也就是没有中断发生，也不用补tick，期间由xTaskResumeAll()统一全部任务切换申请，并执行一次任务切换）]]></description><category></category></item><item><title><![CDATA[分析FreeRTOS内核对象API的源码实现（一）]]></title><link>https://blog.csdn.net/lhbweilai/article/details/167225727</link><guid>https://blog.csdn.net/lhbweilai/article/details/167225727</guid><author>lhbweilai</author><pubDate>Fri, 09 Oct 2026 16:49:06 +0800</pubDate><description><![CDATA[首先如果要开启静态创建任，需要到FreeRTOSConfig.h文件将configSUPPORT_STATIC_ALLOCATION	这个宏定义为1既然选择了静态分配，就需要我们手动为空闲任务和定时器任务提供任务控制块（TCB）与任务堆栈内存。空闲任务和定时器任务虽然由 FreeRTOS 内核在调度器启动时自动创建，但它们所需的内存必须由用户提前准备好。因此，我们需要实现与这两个回调函数。它们的形参都是二级指针，作用就是把main.c中预先定义好的任务堆栈空间和 TCB 地址，传递给tasks.c中。]]></description><category></category></item><item><title><![CDATA[深挖FreeRTOS内核实现（四）]]></title><link>https://blog.csdn.net/lhbweilai/article/details/167177010</link><guid>https://blog.csdn.net/lhbweilai/article/details/167177010</guid><author>lhbweilai</author><pubDate>Thu, 08 Oct 2026 13:52:04 +0800</pubDate><description><![CDATA[在本章之前，FreeRTOS 还没有支持多优先级，只支持两个任务互相切换，从本章开始，任务中我们开始加入任务优先级的功能（注意这里是任务优先级而不是中断优先级，所有的任务优先级都是低于最低的中断优先级的）。在 FreeRTOS 中，数字优先级越小，逻辑优先级也越小，这与隔壁的 RT-Thread 和 μC/OS 刚好相反。就绪列表 pxReadyTasksLists[ configMAX_PRIORITIES ]是一个数组，数组里面存的是就绪任务的 TCB（准确来说是 TCB 里面的 xStateListI]]></description><category></category></item><item><title><![CDATA[深挖FreeRTOS内核实现（三）]]></title><link>https://blog.csdn.net/lhbweilai/article/details/167130797</link><guid>https://blog.csdn.net/lhbweilai/article/details/167130797</guid><author>lhbweilai</author><pubDate>Tue, 06 Oct 2026 20:14:52 +0800</pubDate><description><![CDATA[为什么定义这么多宏：三层分工FreeRTOS 要跑在几十种内核上（M3、M4、RISC-V……），每种内核关中断的指令都不一样。taskENTER_CRITICAL() ← 用户层：你写程序只管拨这个"总机号码"= portENTER_CRITICAL() ← 移植层：换内核时只改这一层= vPortRaiseBASEPRI() ← 底层：msr basepri, 191（真正办事的汇编）类比：总机号码 → 内部转接台 → 具体办事员。你永远拨同一个号码；]]></description><category></category></item><item><title><![CDATA[深挖FreeRTOS内核实现（二）]]></title><link>https://blog.csdn.net/lhbweilai/article/details/166996041</link><guid>https://blog.csdn.net/lhbweilai/article/details/166996041</guid><author>lhbweilai</author><pubDate>Mon, 05 Oct 2026 21:43:03 +0800</pubDate><description><![CDATA[既然创建了任务，那自然也要给每个任务创建一个TCB用来描述该任务的信息，我们在另外一个文件定义该TCB结构体：FreeRTOS.h/*StackType_t就是uint32_t*//* 栈顶 *//* 任务节点 *//* 任务栈起始地址 *//* 任务名称，字符串形式 */} tskTCB;(1)：栈顶指针，作为 TCB 的第一个成员。(2)：任务节点，这是一个内置在 TCB 控制块中的链表节点，通过这个节点，可以将任务控制块挂接到各种链表中。]]></description><category></category></item><item><title><![CDATA[深挖FreeRTOS内核实现（一）]]></title><link>https://blog.csdn.net/lhbweilai/article/details/166904648</link><guid>https://blog.csdn.net/lhbweilai/article/details/166904648</guid><author>lhbweilai</author><pubDate>Sat, 03 Oct 2026 23:05:24 +0800</pubDate><description><![CDATA[首先分析链表的结构体可以看到，对比之前的链表，这个链表结构体多了两个成员和记录轮转遍历的当前位置。它的工作方式是：每次轮转调度时从它出发沿 pxNext 走一格，取到新位置后自己也跟过去。xListEnd/* mini节点结构体定义，作为双向链表的结尾因为双向链表是首尾相连的，头即是尾，尾即是头 *//* 辅助值，用于帮助节点做升序排列 *//* 指向链表下一个节点 *//* 指向链表前一个节点 *//* 最小节点数据类型重定义 */我们可以把这个xListEnd更具象地比作。]]></description><category></category></item><item><title><![CDATA[STM32的一些知识补充]]></title><link>https://blog.csdn.net/lhbweilai/article/details/166693994</link><guid>https://blog.csdn.net/lhbweilai/article/details/166693994</guid><author>lhbweilai</author><pubDate>Wed, 30 Sep 2026 21:12:31 +0800</pubDate><description><![CDATA[一般情况下，我们在 MDK 中编写工程应用后，调试时都是把程序下载到芯片的内部 FLASH 运行测试的，代码的 CODE 及 RW-data 的内容被写入到内部 FLASH 中存储。但在某些应用场合下却不希望或不能修改内部 FLASH 的内容，这时就可以使用 RAM 调试功能了，**它的本质是把原来存储在内部 FLASH 的代码 (CODE 及 RW-data 的内容) 改为存储到 SRAM 中 (内部 SRAM 或外部 SRAM 均可)，芯片复位后从内部 SRAM 中加载代码并运行。]]></description><category></category></item><item><title><![CDATA[从底层了解STM32八大功能（下）]]></title><link>https://blog.csdn.net/lhbweilai/article/details/166369041</link><guid>https://blog.csdn.net/lhbweilai/article/details/166369041</guid><author>lhbweilai</author><pubDate>Sun, 27 Sep 2026 16:23:23 +0800</pubDate><description><![CDATA[CAN 是控制器局域网络 (Controller Area Network) 的简称，它是由研发和生产汽车电子产品著称的德国 BOSCH 公司开发的，并最终成为国际标准（ISO11519），是国际上应用最广泛的现场总线之一。CAN 总线协议已经成为汽车计算机控制系统和嵌入式工业控制局域网的标准总线，并且拥有以CAN 为底层协议专为大型货车和重工机械车辆设计的 J1939 协议。近年来，它具有的高可靠性和良好的错误检测能力受到重视，被广泛应用于汽车计算机控制系统和环境温度恶劣、电磁辐射。]]></description><category></category></item><item><title><![CDATA[结合手册调试各个功能的寄存器+最后通过寄存器编写SPI的初始化和读写函数]]></title><link>https://blog.csdn.net/lhbweilai/article/details/165890725</link><guid>https://blog.csdn.net/lhbweilai/article/details/165890725</guid><author>lhbweilai</author><pubDate>Tue, 22 Sep 2026 15:02:16 +0800</pubDate><description><![CDATA[可以看到执行完GPIO_SetBits(GPIOF,GPIO_Pin_6)函数，ODR寄存器的值变成0x00000040，对应的就是输出寄存器的bit6，这就是通过给BSSRRL赋值做到的，我们到BSSRRL定义看看偏移地址0x18，手册如下：可以看到低16位即BSy，置1就会对相应的ODRx位进行置位，而BSRR 高 16 位是 BRy：写 1 是清零。所以 GPIO_SetBits 用低 16 位（BSRRL），GPIO_ResetBits 用高 16 位（BSRRH）。结合ODR寄存器来看。]]></description><category></category></item><item><title><![CDATA[从底层了解STM32八大功能(中)]]></title><link>https://blog.csdn.net/lhbweilai/article/details/165759737</link><guid>https://blog.csdn.net/lhbweilai/article/details/165759737</guid><author>lhbweilai</author><pubDate>Sat, 19 Sep 2026 11:57:32 +0800</pubDate><description><![CDATA[它的物理层有如下特点：(1) 它是一个支持多设备的总线。“总线”指多个设备共用的信号线。在一个 I2C 通讯总线中，可连接多个 I2C 通讯设备，支持多个通讯主机及多个通讯从机。(2) 一个 I2C 总线只使用两条总线线路，一条双向串行数据线 (SDA) ，一条串行时钟线 (SCL)。数据线即用来表示数据，时钟线用于数据收发同步。(3) 每个连接到总线的设备都有一个独立的地址，主机可以利用这个地址进行不同设备之间的访问。(4) 总线通过上拉电阻接到电源。]]></description><category></category></item><item><title><![CDATA[从底层了解STM32八大功能（上）]]></title><link>https://blog.csdn.net/lhbweilai/article/details/164429155</link><guid>https://blog.csdn.net/lhbweilai/article/details/164429155</guid><author>lhbweilai</author><pubDate>Thu, 17 Sep 2026 23:52:33 +0800</pubDate><description><![CDATA[前言：在之前的学习中，我一直有一个困惑：我能看懂代码，也能跟着教程把程序跑一遍，但这就算学会嵌入式了吗？我想，肯定不是的。软件工程师最重要的能力，是当程序出错时，能快速发现问题并排查出原因，也就是调试 Bug 的能力。但说实话，目前我还没有建立起这样的意识。所以，我决定重新学习 STM32 的八大功能。这一次，不再是简单地跟着视频跑一遍，而是 20% 学、80% 调试，最后通过一个小测试来检验成果。我相信，基于之前的学习基础，我能很快掌握。在之前的学习中，我直接使用了固件库为我们封装好的库函数，但我一直没有]]></description><category></category></item><item><title><![CDATA[工业互联（三）——USB设备编程（二）]]></title><link>https://blog.csdn.net/lhbweilai/article/details/164270496</link><guid>https://blog.csdn.net/lhbweilai/article/details/164270496</guid><author>lhbweilai</author><pubDate>Thu, 03 Sep 2026 19:27:16 +0800</pubDate><description><![CDATA[Azure RTOS 平台是运行实时解决方案的集合，包括 Azure RTOS ThreadX、Azure RTOS NetX 和 NetX Duo、Azure RTOS FileX、Azure RTOS GUIX 和 Azure RTOS USBX![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/4860a1cedeb34d17975bf1d1db9f046c.png)]]></description><category></category></item><item><title><![CDATA[工业互联网（二）——USB 设备编程（一）]]></title><link>https://blog.csdn.net/lhbweilai/article/details/164230605</link><guid>https://blog.csdn.net/lhbweilai/article/details/164230605</guid><author>lhbweilai</author><pubDate>Tue, 01 Sep 2026 22:04:49 +0800</pubDate><description><![CDATA[USB 本身是一个很庞大、复杂的体系，本课程的重点在于工业互联，USB 是其中的一个小小知识点。本章课程的目的能理解 USB 的一些概念，能使用 USB 传输数据，本节主要介绍 USB 概念，最后移植 USBX 实现 USB 串口功能。在学习之前，先记住几个术语，这在后面的代码会经常看到主机控制器驱动程序设备控制器驱动程序底层USB外设控制驱动程序通信设备类。]]></description><category></category></item></channel></rss>