- 博客(42)
- 收藏
- 关注
原创 嵌入式代码中滥用全局变量的弊端及优化实践
嵌入式开发中滥用全局变量会带来数据篡改、并发竞争、内存浪费和测试困难等问题。本文通过代码示例分析了这些隐患,并提出了优化方案:1)模块化封装数据,提供受控访问接口;2)使用互斥锁保护多任务共享资源;3)将临时数据改为局部变量或动态内存;4)通过参数传递替代全局状态依赖。优化遵循最小作用域、单一职责和显式优于隐式原则,可提高代码的封装性、安全性和可测试性,特别适合资源受限的嵌入式系统开发。
2026-02-06 11:27:56
585
原创 裸机多任务实战:单片机并行处理的四大利器
本文介绍了四种实用的裸机多任务处理技巧,适用于资源受限的嵌入式开发场景。首先分析了简单轮询的缺陷,随后详细讲解了时间片轮询、任务表驱动、状态机和中断+标志位四种解决方案。通过智能温控器案例展示了实际应用,并提供了裸机与RTOS的选型指南。这些方法能有效解决多任务调度问题,在保证响应速度的同时降低系统开销,特别适合任务数量少、资源紧张的项目开发。文章强调应根据项目需求选择最合适的技术方案。
2026-01-28 11:01:43
386
原创 嵌入式UI刷新:观察者模式实战
本文探讨了嵌入式开发中UI刷新的优化方案,提出了从传统Push模式到观察者模式、MVC/MVVM架构的演进思路。传统方式存在耦合度高、维护困难的问题,而观察者模式通过"订阅-通知"机制实现解耦。MVC架构进一步明确了Model、View、Controller的分工,MVVM则通过数据绑定简化开发。文章以温控器为例展示了实际应用,并针对嵌入式系统的资源限制提供了性能优化建议。这种架构转变使代码更清晰、可扩展,适用于多模块共享数据的场景,为嵌入式系统设计提供了进阶思路。
2026-01-26 13:39:13
902
原创 嵌入式开发:告别malloc的三大致命隐患
摘要:本文剖析了嵌入式系统中使用标准malloc的三大缺陷:时间不可预测、内存碎片化和线程不安全。通过一个实际案例揭示了内存碎片导致设备死机的根本原因,并提出对象池(Object Pool)作为高效替代方案。对象池采用固定大小内存块和侵入式链表设计,实现了O(1)时间复杂度的内存分配/释放,完全消除内存碎片,且无需额外存储开销。相比malloc,对象池在实时性、内存利用率和线程安全方面具有显著优势,特别适合资源受限的嵌入式系统。文章还给出了对象池的具体实现代码,并讨论了其适用场景和扩展应用。
2026-01-26 13:13:04
707
原创 程序员进阶指南:从基础到卓越的代码能力提升路径
本文系统阐述了程序员代码能力提升的路径与策略。首先强调夯实编程语言基础的重要性,提出"语法入门-语法深化-综合实践"的渐进学习方法。其次指出规范编码的必要性,包括命名规范、代码复用和设计原则的应用。在实践层面,建议通过开源贡献、代码审查、算法训练和项目开发来提升实战能力。最后提出构建知识体系的三种方式:技术博客、个人知识库和行业交流。文章指出代码能力的提升是一个"基础-规范-实践-总结"的闭环过程,强调持续学习与深度思考的重要性,建议程序员在技术快速迭代的背景下保持专
2025-11-19 10:07:41
538
原创 在 Ubuntu 环境下配置 Git 的 SSH 免密登录
本文介绍了在Ubuntu系统下配置Git SSH免密登录的完整流程。主要内容包括:检查现有SSH密钥、生成RSA密钥对、设置密钥文件权限、复制公钥到Git服务器、测试SSH连接以及修改Git仓库远程地址为SSH协议。文章详细说明了每一步操作的具体命令和注意事项,并提供了常见问题解决方法。通过这套流程,用户可以实现本地与Git服务器之间的安全免密认证,提高Git操作效率。重点强调了对私钥的保护和正确设置文件权限的必要性,确保SSH认证能够正常工作。
2025-11-19 10:06:31
1229
原创 VScode常用快捷键
VS Code常用快捷键速查表:包含通用操作、文件编辑、代码编辑、多光标、调试、搜索导航等12大类快捷键。Windows/Linux使用Ctrl组合键,Mac使用Cmd组合键。主要功能包括:命令面板(Ctrl+Shift+P)、文件操作(Ctrl+N/O/S)、代码编辑(Ctrl+Z/C/V)、格式化(Shift+Alt+F)、调试(F5/F10/F11)、版本控制(Ctrl+Shift+G)等。特别整理了多光标操作和禅模式(Ctrl+K Z)等高效功能。适合开发者快速查阅提升编码效率。
2025-11-17 20:11:32
1144
原创 Git 多模块项目管理
本文介绍了三种使用Git管理多模块项目的方法:拆分独立仓库、Git子模块和Git子树合并。重点推荐将项目拆分为独立仓库的方法,通过为每个模块建立单独Git库实现独立开发、测试和部署,提高协作效率。文章详细说明了各方法的实施步骤和适用场景,并举例说明智能门锁项目的模块化管理。同时强调了版本控制、自动化构建测试以及文档沟通在项目管理中的重要性,为团队开发多模块项目提供了系统的Git管理方案。
2025-11-17 20:10:56
1120
原创 C/C++ 中 void* 深度解析:从概念到实战
不懂 void*,很难称得上是合格的 C/C++ 开发者——这句话并非夸张。在 C/C++ 体系中,void* 是从新手迈向进阶的核心“桥梁”:新手常因它的“无类型”特性觉得抽象难懂,而资深开发者却能借助它实现灵活的内存管理、泛型编程和底层交互。若回避 void*,不仅难以开发通用库、进行系统级编程,甚至会在面试中的基础原理题上折戟。本文将从概念、特性、用途到实战规范,全面拆解 void*,让其从“抽象符号”变为可熟练运用的工具。void* 作为 C/C++ 中的“通用指针”,其核心价值在于“
2025-10-31 20:26:23
822
1
原创 自动注册初始化函数的实现方式
本文介绍了一种嵌入式系统中的自动注册初始化函数实现方法。传统方式是在main()函数中手动调用各模块初始化函数,存在维护困难和依赖管理问题。改进方案通过编译器属性__attribute__((section))将函数指针存入特定段,链接器自动聚合这些段,系统启动代码遍历执行。具体实现使用APP_INIT_EXPORT宏,使编译器、链接器和启动脚本协同工作,实现初始化函数的自动注册和执行。这种方法通过编译时确定性和空间换取了运行时灵活性,便于模块化开发和维护。调试时可查看map文件验证函数注册情况。
2025-10-29 15:05:05
263
原创 如何使用 MQTT 报文实现发布订阅功能
摘要:本文详细介绍了MQTT协议中发布订阅功能的实现过程。通过MQTTX工具演示了连接Broker、订阅主题和发布消息的完整流程,重点解析了Connect报文中的关键配置项(ClientID、用户名密码、KeepAlive、CleanSession)以及Connack报文的响应机制。同时说明了Subscribe/Suback报文交互和Publish报文中的主题名、QoS等级、保留标志等核心概念,帮助读者理解MQTT协议的基本通信原理和消息传输机制。
2025-10-28 16:51:08
913
原创 BK7258 使用 APP 调试 Doorbell 工程设备全指南
本文介绍了如何利用BekenIoT App调试BK7258智能门铃设备。该App提供设备管理、快捷配网和摄像头控制等功能,支持iOS和Android平台。调试步骤包括:进入debug模式选择设备型号(如BK7258_DL_09),配置网络、视频、LCD和音频参数,完成扫描配网后连接设备。功能界面提供摄像头、LCD显示、音频等调试选项,并显示实时帧率等信息。通过这套流程,开发者可快速掌握BK7258门铃设备的调试方法,为后续开发工作打好基础。
2025-09-10 14:49:34
1002
原创 ESP32C3和ESP32S3的区别有哪些?该怎么选型?
ESP32-C3和ESP32-S3是乐鑫科技的两款Wi-Fi+蓝牙微控制器。C3采用RISC-V单核处理器(160MHz),功耗低,适合简单物联网设备;S3采用Xtensa双核处理器(240MHz),支持USB、摄像头等丰富接口,适合高性能应用。选型关键点:C3适合低成本、低功耗场景(如传感器节点),S3适用于复杂计算、多媒体处理(如语音识别、图像显示)。两者均支持Wi-Fi/BLE,但S3射频性能更强,开发成本也更高。根据项目需求平衡性能、功耗和成本即可选择。
2025-08-30 17:22:48
2746
原创 嵌入式产品开发全流程:从需求到落地的完整指南
本文系统介绍了嵌入式产品开发的全流程,从需求定义到市场认证的完整路径。开发过程分为三大阶段:需求与设计阶段重点明确功能、性能、成本和应用场景需求,完成软硬件架构设计;开发与调试阶段实现硬件PCB设计制作、软件分层开发及系统联调;试产与认证阶段通过小批量试产验证生产工艺,完成产品认证获取市场准入资格。整个流程环环相扣,强调量化指标、模块化设计和问题闭环,为开发团队提供了一套从技术实现到产品落地的系统方法论。文章最后指出各阶段常见风险点,并倡导从业者交流优化开发实践。
2025-08-29 13:41:38
1255
原创 ESP32 中使用LVGL显示FATFS中的图片无法显示的解决办法
摘要:在LVGL V9.2图像处理中,频繁出现日志 image_decoder_get_info: Image decoder didn't set strid导致设备重启的问题。通过分析发现,问题源于局部变量使用、内存分配及数据指针设置不当。解决方案采用全局变量存储图像数据,正确初始化lv_draw_buf_t结构体,并确保图像数据指针正确指向。关键改进包括:全局缓冲区分配、静态draw_buf声明、完整文件读取验证,以及使用LVGL V9新API进行图像解码和显示设置,最终解决了日志泛滥和系统崩溃问题。
2025-08-29 11:43:54
544
原创 ESP32-S3 驱动 RGB 屏幕:画面飘移与撕裂问题
本文针对ESP32-S3驱动RGB屏幕时的画面漂移与撕裂问题,提出多维度解决方案。硬件层面优化总线带宽和缓存配置,包括提升Flash/PSRAM工作频率、调整缓存参数等;软件层面建议采用XIPPSRAM+RGBBouncebuffer组合方案,并对NVS操作和大文件处理进行代码优化。同时给出动态时钟调节、手动刷屏等应用层解决策略,有效平衡系统性能与显示效果。方案适用于Wi-Fi操作、Flash写入等复杂场景,具有RGB屏幕的普适参考价值。
2025-08-18 13:56:35
1574
原创 如何在LVGL之外的线程更新UI内容
在LVGL线程之外的线程,更新UI内容时,会导致程序崩溃。导致LVGL卡死现象,进而程序崩溃,主要原因就是在LVGL的线程外更新了LVGL对象导致的,接下来分析并解决该问题!
2025-05-19 20:19:52
1544
3
原创 LVGL 8.3版本 多任务环境下使用LVGL
LVGL图形库在多线程环境中的安全使用说明:LVGL默认不是线程安全的,仅允许在事件处理和定时器回调中安全调用API。多线程环境下必须使用互斥锁保护所有LVGL相关操作,包括定时器处理函数lv_timer_handler的调用。建议避免在中断中直接调用LVGL函数(除lv_tick_inc和lv_disp_flush_ready外),推荐在中断中设置标志位,在定时器中处理实际逻辑。文中提供了伪代码示例,展示如何通过加锁机制确保多线程安全访问LVGL对象。
2025-01-09 16:59:24
2032
原创 网络程序通信的流程---socket与TCP的简单认识
IP地址是互联网协议地址(Internet Protocol Address)的缩写,用于在IP网络中唯一标识一个设备。它通常由四个数字组成,每个数字在0-255之间,用点号分隔。IP地址分为IPv4和IPv6两种版本,其中IPv4是目前广泛使用的版本。端口是计算机上用于接收和发送数据的接口。每个端口都有一个唯一的端口号,用于标识和区分不同的服务或应用程序。常见的端口号有HTTP(80)、HTTPS(443)、FTP(21)等。1.通过ip地址找到网络中的设备2.通过端口号找到对应进程的端口。
2024-06-19 09:33:03
675
原创 力扣刷题日记--2288.价格减免 难度中等
那么该单词就表示一个价格。我们提取后续的字符,转换成整数,计算折扣(即乘上 1−discount1001 - \dfrac{\textit{discount}}{100}1−100discount),保留两位小数,再转换回字符串,并添加开头的 $ 即可。- "$1" 减免 50% 为 "$0.50" ,所以 "$1" 替换为 "$0.50"。- "$2" 减免 50% 为 "$1" ,所以 "$1" 替换为 "$1.00"。表示价格的单词分别是 "$3"、"$5"、"$6" 和 "$9"。
2024-06-19 09:08:39
1109
原创 我对程序员的职业理解
在一次紧急项目中,他运用刚刚学习的微服务架构知识,快速重构了一部分系统,显著提升了系统的稳定性和响应速度,得到了团队和管理层的认可。1. 持续学习与自我提升:技术日新月异,保持好奇心和学习热情,积极跟进新技术、新工具,不断提升自己的技能水平,是程序员应持之以恒的态度。6. 代码规范与可维护性:遵循良好的编码规范,编写清晰、可读性强的代码,注重代码结构和模块化设计,确保项目的可维护性和扩展性。10. 终身学习:认识到学习是一个持续的过程,不断挑战自我,探索未知领域,拓宽知识边界,保持职业生涯的活力和竞争力。
2024-06-13 10:55:24
1493
原创 2024年,计算机相关专业还值得选择吗?
计算机行业的发展态势既充满挑战也孕育着无限机遇,要求从业者不断学习新技能,紧跟技术前沿,同时也强调了伦理、可持续性与社会责任的重要性。综上所述,计算机相关专业虽然竞争激烈,但凭借其广泛的应用前景和持续的技术创新,仍然是一个充满机遇的领域。关键在于个人是否具备相应的兴趣、能力和持续学习的决心。如果你是今年的高考生,通过自我评估和实践探索,你可以更明智地决定是否踏上这条充满挑战与机遇的道路。
2024-06-13 10:42:36
1278
原创 字符串、HEX 十六进制互转工具
最近,在搞BLE相关的项目,需要用到字符串转16进制通过广播包发送出去,但是在网上找了好久都没有找到相应要的工具,终于在我坚持不懈的寻找下,发现了这款免费的转换工具!有需要的自取,使用起来也很方便!我就不一 一列举啦,有兴趣的去首页发掘吧!在网站首页 还有很多实用的工具!
2024-06-12 16:31:10
2272
原创 蓝牙广播包 分析 蓝牙ble接收广播数据
标准的UUID:由SIG发布,采用UUID基数+16位UUID的形式,如心率服务的UUID是0x180D,使用的UUID基数是:00000000-0000-1000-8000 - 00805F9B34FB。厂商自定义的UUID:同样采用UUID基数+16位UUID的形式,由厂商定义,如BLE串口的UUID是0x0001,使用的UUID基数是:6E400001-B5A3-F393-E0A9-E50E24DCCA9E。下图是标准UUID传输的示意图。
2024-06-12 16:21:48
7165
原创 正则表达式的学习与使用
正则表达式是一种强大的模式匹配和字符串搜索工具。它使用特定的语法规则表示一种模式,可以用于在文本中查找、替换或提取特定的字符串。
2024-06-04 17:13:18
1024
原创 LVGL--> Flex(弹性布局)
Flex(弹性布局)Overview(概述)Flexbox(或简称 Flex)是的一个子集。它可以将项目排列成行或列(轨道),处理环绕,调整项目和轨道之间的间距,处理 grow 以使项目填充剩余空间的最小/最大宽度和高度。要使对象 flex 容器调用 lv_obj_set_layout(obj, LV_LAYOUT_FLEX)。请注意,LVGL 的 flex 布局功能需要通过 lv_conf.h 中的 LV_USE_FLEX 全局启用。
2024-05-25 10:52:43
3828
2
原创 LVGL Event——事件
可以向一个对象添加更多事件,如下所示:如果传入的用户数据不一样,一个对象可以绑定同一个事件回调函数多次。例如:这些事件将按照添加的顺序被调用。更多的对象可以使用相同的 事件回调。任何自定义事件代码都可以通过 uint32_t MY_EVENT_1 = lv_event_register_id();注册并且可以使用 lv_event_send(obj, MY_EVENT_1, &some_data) 发送到任何对象。
2024-05-21 20:40:07
6092
1
原创 用#define宏替换和typedef那个方式更好?
总结一下,`#define` 主要用于定义常量和宏替换,而 `typedef` 主要用于创建数据类型别名。`typedef` 是一个关键字,用于创建新的数据类型别名。它是在编译之前进行文本替换的。这样在代码中使用 `SQUARE(x)` 将会被替换为 `((x) * (x))`。这样就可以用 `Age` 来代替 `int` 类型。`#define` 和 `typedef` 是在 C/C++ 语言中用于定义类型别名的关键字,它们有一些区别。这将在编译前将所有出现的 `PI` 替换为 `3.14159`。
2023-10-13 20:02:33
287
原创 快速入门排序算法——桶排序(简化版)
快速入门排序算法——桶排序这是简化后易于理解的桶排序,是一个非常快的排序算法,其实这不是真正的桶排序(那会比这个复杂的多),但是简单易懂,对于想要入门排序算法的小白,这是一个非常好的起点。
2023-06-02 10:03:33
171
嵌入式软件工程师自我提升策略
2024-06-12
嵌入式芯片BK7258由上海博通研发,部分说明文档,或许能帮到你!
2024-05-27
BK-UART串口API的分析与使用
2023-11-08
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅