🎧 New: AI-Generated Podcasts Turn your study notes into engaging audio conversations. Learn more

ESP32-C3物联网工程开发实战.pdf

Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...

Full Transcript

版权信息 COPYRIGHT 书名:ESP32-C3物联网工程开发实战 作者:乐鑫科技 出版社:电子工业出版社 出版时间:2022年9月 ISBN:9787121442971 字数:620千字 版权方:电子工业出版社有限公司 版权所有·侵权必究 内容简介 ESP32-C3是搭载了开源指令集RISC-V...

版权信息 COPYRIGHT 书名:ESP32-C3物联网工程开发实战 作者:乐鑫科技 出版社:电子工业出版社 出版时间:2022年9月 ISBN:9787121442971 字数:620千字 版权方:电子工业出版社有限公司 版权所有·侵权必究 内容简介 ESP32-C3是搭载了开源指令集RISC-V的32位低功耗、低成本、安全的物 联网芯片,本书也是该芯片原厂乐鑫科技的官方作品。本书从物联网工程开 发的必备知识入手,循序渐进地介绍了硬件设计、外设驱动、ESP-IDF开发环 境搭建、Wi-Fi网络配置、本地和云端控制、OTA升级原理、电源管理、低功 耗优化、设备安全功能、固件版本管理和量产测试等方面的内容。物联网工 程开发涉及的知识点很多,本书根据所涉及的知识点将全书分为4篇,分别是 准备篇(第1~4章)、硬件与驱动开发篇(第5~6章)、无线通信与控制篇 (第7~11章)、优化与量产篇(第12~15章),可帮助读者更好地掌握相关 的知识点。 本书既可作为高等院校相关专业的教材或教学参考书,也可供相关领域 的工程技术人员阅读。对于物联网开发的爱好者来说,本书还是一本深入浅 出的读物。 为了便于读者实践,本书提供了相关代码,读者可登录华信教育资源网 免费注册后下载。关注乐鑫科技的公众号可获得更多关于物联网开发的新资 讯。 序言 写在前面 世界信息化的进程正在迅猛发展。 继互联网之后,物联网的浪潮已然到来。作为数字经济时代的新型基础 设施,物联网得到了我国政府的高度重视和政策支持。乐鑫信息科技(上 海)股份有限公司(简称乐鑫科技或乐鑫)自2008年创立以来,一直肩负着 “科技民主化”的重要使命,致力于构建“万物智联”的世界,让“连接”成为开发 者触手可得的技术。 自研芯片的道路就像一场马拉松,需要不断突破科技边界。乐鑫科技深 耕物联网领域的软硬件产品研发,先后发布了ESP32、ESP32-C、ESP32-S、 ESP32-H等系列芯片。从早期被认为“改变物联网游戏规则”的ESP8266芯片, 到ESP32系列芯片开始增加Bluetooth® LE和AI算法功能并实现了最高240 MHz 的双核处理,再到ESP32-S3系列芯片增加的AI硬件加速器,乐鑫科技不断在 软件技术上进行投入,围绕AIoT的核心,覆盖工具链、编译器、操作系统、 应用框架、AI算法、云产品、App等,实现了AIoT领域的软硬件一体化解决 方案闭环。 截至2022年7月,乐鑫科技的IoT芯片累计出货量已超过8亿颗,在Wi-Fi MCU领域遥遥领先,赋能了全球数亿的智能产品。乐鑫科技一直秉承着精益 求精的精神,每次发布的新产品总能以高集成度和低成本引爆物联网市场。 ESP32-C3芯片的发布,是乐鑫科技底层自研技术积累的结晶,也是一个新里 程碑式的事件。ESP32-C3芯片搭载了自研的基于开源指令集RISC-V的32位单 核处理器,时钟频率高达160 MHz,内置400 KB的SRAM,集成了2.4 GHz的 Wi-Fi和支持长距离的Bluetooth 5(LE),具有行业领先的射频性能和低功耗 特性,可满足常见的物联网产品功能需求,同时安全性能也大幅度提升。本 书以成熟的ESP32-C3为硬件基础,阐述物联网项目开发等技术知识。 聚焦平台能力,回馈生态社区 乐鑫科技不仅仅是一家半导体公司,更是一家物联网平台型公司,始终 坚持在技术领域寻求突破和创新。与此同时,乐鑫科技以开放的心态,将自 研的操作系统和软件框架开源分享到社区,形成了独树一帜的生态环境。众 多的工程师、创客及技术爱好者,积极开发新的软件应用,自由交流并分享 使用心得。每时每刻都可以在各类平台看到开发者的奇思妙想,如YouTube、 Bilibili视频平台,以及GitHub、Gitee等代码托管平台。有的开发者还自发编 写了关于乐鑫科技产品的图书,已逾100本,涉及的语种有中文、英文、德 文、法文、日文等十多种。 正是来自社区伙伴的支持和信任,鼓励着乐鑫科技不断创新。乐鑫科技 的创始人兼CEO张瑞安先生曾说:“我们在寻找答案,去解决人们目前生活中 需要解决的问题。我们致力向社会贡献商业实践、工具、文档、写作以及想 法。”乐鑫科技是一家非常重视阅读和想法的公司,而物联网技术的不断升 级,对工程师综合素质的要求越来越高,如何才能帮助更多人快速掌握物联 网芯片、操作系统、软件框架、应用方案以及云服务产品呢?授人以鱼不如 授人以渔,于是在一次头脑风暴会议中,我们在想是否能写一本书,将知识 点系统性地梳理出来呢?想法一拍即合,我们迅速在公司聚集了资深工程师 们,并整合了技术团队关于嵌入式编程、物联网硬件和软件开发的相关经 验,撰写了本书。在写作过程中,我们尽量客观公正、抽丝剥茧,用轻松简 明的语言讲述物联网的纷繁和魅力。我们认真总结了常见的问题,倾听了社 区的反馈和建议,希望能清晰地回答在开发过程中遇到的诸多疑问,为相关 技术人员和决策者提供实用的物联网开发指南。 本书的结构 本书以工程师为中心视角,循序渐进地阐述了物联网工程开发的必备知 识,全书分为4篇,具体如下: 准备篇:包括第1~4章,本篇主要介绍物联网体系结构、典型的物联 网工程项目框架、ESP RainMaker® 物联网云平台和ESP-IDF开发环境的搭建, 为物联网工程开发夯实基础。 硬件与驱动开发篇:包括第5~6章,本篇以ESP32-C3芯片为基础,论 述了如何设计最小硬件系统和驱动开发,实现了调光、调色的控制以及无线 通信功能。 无线通信与控制篇:包括第7~11章,本篇主要阐述基于ESP32-C3芯 片的智能化Wi-Fi网络配置方案、本地控制协议和云端控制协议、设备的本地 控制和远程控制,并给出了智能手机App的开发、固件更新、版本管理等方 案。 优化与量产篇:包括第12~15章,本篇为提高篇,主要从电源管理、 低功耗优化、增强安全等角度介绍物联网产品的优化,并介绍了量产的固件 烧录和测试、如何通过ESP Insights远程监察平台来诊断设备固件的运行状态 和日志。 关于源代码的使用 读者可以实践本书中的程序示例,既可手工输入代码,也可使用本书配 套的源代码。本书注重理论和实践的结合,几乎每章都在最后给出了智能照 明工程实战案例,并已开源。欢迎读者前往esp32.com、GitHub和Gitee中与本 书相关的版块下载源码并进行讨论。本书的开源代码遵循Apache 2.0许可证的 条款。 写在最后 本书为乐鑫科技的官方出品,主要编写人员是公司的资深工程师。本书 适合计算机相关行业的管理者、研发人员,高等院校相关专业的师生以及物 联网领域的爱好者阅读,希望本书成为大家如良师益友般的工作手册、工具 书和床头书。 本书在编写过程中,借鉴和参考了国内外专家、学者、技术人员的相关 研究成果,我们尽可能按学术规范予以说明,但难免会有疏漏之处,在此谨 向有关作者表示深深的敬意和谢意。此外,书中引用了互联网上的资讯,在 此向原作者和刊发机构致谢,对于不能一一注明引用来源的资讯作者深表歉 意。 本书的顺利出版,经过了很多轮的内部讨论,听取了试读者和出版社编 辑的建议反馈,再次感谢各位的帮助,使本书得以尽早与读者见面。 最后,也是最重要的,感谢乐鑫科技每一位为产品的诞生和普及而付出 心血的同仁。 物联网工程开发涉及的知识面非常广泛,限于本书篇幅,以及笔者的水 平和经验,疏漏之处在所难免,恳请广大专家和读者批评指正。若您对本书 有任何建议,请及时联系我们,联系邮箱为[email protected]。我们期待您 的反馈。 乐鑫科技团队 2022年8月8日 如何高效地阅读本书 随着信息技术的快速发展,相关的学习资料呈现爆炸式的增长。如何快速、 高效地学习新的知识、掌握新的技术,是每个工程师都面临的问题。在本书的编 写和出版过程中,为了帮助读者更高效地阅读本书,我们做了如下设计。 本书源码的获取方法 本书的相关源码已经开源,读者可以通过以下两个途径获取本书的源码,还 可以前往https://www.esp32.com/bookc3书籍讨论版块,反馈您在阅读本书过程中 的想法和问题。 排版约定 为了帮助读者更好地理解本书内容,全书将使用如下排版规则: 关于文本框 项目源码: 项目源码 :本书注重理论和实践相结合,因此几乎每章最后一节都配有 智能照明程实战项目,对应的工程步骤和源码地址将记录在类似的文本框中。 扩展阅读: 扩展阅读 :书中类似文本框中的内容属于扩展阅读内容,供读者进行知识 扩展,以便读者更加深入地理解相关的技术。 小贴士: 小贴士 :实用小贴士,书中类似文本框中的内容往往是代码成功运行的非常 关键的信息和提醒。 关于本书中的命令 本书中的大多数命令是在Linux系统下执行的,字符“$”是提示符。如果命令 需要超级用户的权限来执行命令,则提示符用“#”来替代。Mac系统下命令提示符 为“%”,如4.2.3节(在Mac系统下安装ESP-IDF开发环境)。 关于本书的字体 为了符合大多数读者的阅读习惯,本书正文的中文采用宋体,英文和数字等 采用Times New Roman。 等宽字体:不仅用于文件内容、命令输出,还用于正文中出现的代码示例、 组件、函数、变量、代码文件名、代码目录或字符串等。其中,代码和文件内容 增加了行号。书中采用的是Courier New等宽字体。 等宽粗体 :在示例中用于表示需要用户输入的命令或文字,按下回车键可输 入的命令。书中采用的是Courier New等宽粗体。 英文字体:表示协议名称、专名词、缩写词的英文单词采用Times New Roman英文字体。 示例1: 通过云平台完成固件更新是更为普遍的方案,本节将借助ESP RainMaker从 云端向设备推送OTA升级信息。ESP RainMaker同样使用的是esp_https_ota组件, ESP RainMaker SDK 中 整 合 了 OTA 升 级 部 分 的 代 码 , 通 过 调 用 esp_rmaker_ota_enable()函数即可启用OTA升级。需要注意的是,ESP RainMaker 提供了两种OTA升级方式,此处需要选择通过主题形式接收OTA升级消息。订阅 与OTA升级相关的主题后,可以通过这些主题接收MQTT消息并解析出固件的 URL,同时通过这些主题推送当前更新的进度及最终状态。ESP RainMaker OTA 升级功能的代码位于esp-rainmaker/components/esp_rainmaker/src/ota目录下,该目 录下与固件下载相关的代码位于源文件esp_rmaker_ota.c中。 示例2: 下 面 的 命 令 可 生 成 CA 证 书 所 需 的 CSR , 读 者 按 照 提 示 输 入 即 可 , Organization Name可随意输入(这是因为只是在本地使用CSR)。 01 准备篇 第1章 浅谈物联网 在20世纪末,随着计算机网络和通信技术的兴起,互联网以迅雷不及掩耳 之势融入了人们的生活。随着互联网技术不断成熟,又延伸出了物联网的概 念。物联网的英文为Internet of Things(IoT),从字面意义来看,物联网就是 物物相连的互联网。如果说互联网打破了空间和时间的限制,极大地拉近了“人 与人”之间的距离,物联网则让“物”成为重要的参与者,极大地拉近“人与物” “物与物”的距离。 2021年发布的“十四五”规划和《物联网新型基础设施建设三年行动计划 (2021—2023年)》,为物联网产业注入了新动力。在可预见的未来内,物联 网必定成为信息产业的驱动力。而什么是物联网呢?要想准确地给出物联网的 定义并不是容易的事情,因为物联网的涵义和外延都在不停发展变化中。早在 1995年,比尔·盖茨在其著作《The Road Ahead》中就率先提出了物联网的概 念。简单来说,物联网利用互联网让物体相互交换信息,最终达到“万物互联” 的终极目标,这是早期对物联网概念的阐述,也是对未来科技的幻想。随着经 济和科技的快速发展,20多年前的幻想正在走进现实中。从各类智能设备、智 能家居、智慧城市、车联网、可穿戴设备等,到物联网技术成为“元宇宙”的支 撑,新的概念还在源源不断地涌现。本章首先对物联网的体系结构进行介绍, 再对最常见的物联网应用——智能家居进行阐述,以便帮助读者建立对物联网 的清晰认知。 1.1 物联网的体系结构 物联网涉及多项技术,这些技术在不同的行业有不同的应用需求和形态。 为了梳理物联网的体系结构、关键技术和应用特点,需要建立统一的体系结构 和标准的技术体系。本书将物联网的体系结构简单地分为感知控制层、网络 层、平台层、应用层。 1 .感知控制层 感知控制层是实现物联网全面感知的核心层,也是物联网体系结构中最基 础的一层,其主要功能是实现对信息的采集、识别和控制。感知控制层由具有 感知、识别、控制和执行等能力的多种设备组成,负责对物质属性、行为态 势、设备状态等各类数据进行获取与状态辨识,完成对现实物理世界的认知和 识别。感知控制层还能对设备状态等进行控制。 在感知控制层中,最常见的设备就是各类传感器,这些传感器起到对信息 采集和识别的重要作用。传感器好比人类的感觉器官,如光敏传感器好比人类 的视觉、声敏传感器好比听觉、气敏传感器好比嗅觉,而压敏、温敏等传感器 好比触觉,有了“感官”的物体就慢慢变得“活”起来,并实现了对物理世界的智 能感知、识别和操作。 2 .网络层 网络层的主要功能是实现信息的传输和通信,既负责将从感知控制层获得 的数据传输到指定的地方,还负责将应用层下发的控制命令传输到感知控制 层,是连接感知控制层和平台层的重要通信桥梁。物联网中的“网”字有以下两 个含义:物接入互联网和互联网传输。 1)物接入互联网 互联网实现了人与人之间的互联互通,但在互联网中人与物或物与物之间 无法互联。在物联网出现前,大部分的物是不具有联网能力的。随着技术的不 断发展,物联网将物连接到了互联网,实现了人与物、物与物的互联。目前, 物接入互联网通常使用两种方式:一种是有线网络接入;另一种是无线网络接 入。 有线网络接入方式包括以太网、串行通信(如RS-232、RS-485)和USB 等。无线网络接入方式采用的是无线通信,无线通信又分为短距离无线通信和 长距离无线通信。 短距离无线通信主要包括ZigBee、Bluetooth® 、Wi-Fi、NFC(Near-Field Communication)、RFID(Radio Frequency Identification)等。长距离无线通信 主 要 包 括 eMTC ( enhanced Machine Type Communication ) 、 LoRa 、 NB- IoT(Narrow Band Internet of Things)、2G、3G、4G、5G等。 2)互联网传输 确定物接入互联网的方式,相当于确定了数据的物理传输链路,之后还需 要确定使用哪些通信协议来传输数据。与互联网的终端相比,目前大部分物联 网终端的可用资源较少,如处理性能、存储容量、网络速率等,因此在物联网 应用中需要选择占用资源更少的通信协议。现在广泛使用的通信协议有两种: MQTT ( Message Queuing Telemetry Transport ) 和 CoAP ( Constrained Application Protocol)。 3.平台层 平台层主要指物联网云平台。当所有的物联网终端联网后,数据需要汇总 在一个物联网云平台上,实现对终端状态数据的计算、存储。平台层主要为物 联网应用提供支撑,提供海量设备的接入与管理能力,可以将物联网终端连接 到物联网云平台,支撑终端数据采集上云,以及从云端向终端下发命令,从而 进行远程控制。平台层作为承接设备与行业应用的中间服务,在整个物联网体 系结构中起着承上启下的作用,承载了抽象化的业务逻辑和标准化的核心数据 模型,不仅可以实现设备的快速接入,还可以提供强大的模块化能力,能够满 足行业应用场景下的各类需求。平台层主要包含设备接入、设备管理、安全管 理、消息通信、监控运维和数据应用等功能模块。 设备接入:实现终端与物联网云平台的连接、通信。 设备管理:包含设备创建、设备维护、数据转换、数据同步、设备分 布等功能。 安全管理:从安全认证和通信安全两个方面来保证物联网数据传输的 安全。 消息通信:包括3种信息传输方式,即终端向物联网云平台发送数据、 物联网云平台将数据发送到服务器端或其他物联网云平台,以及服务器端的远 程控制设备。 监控运维:涉及监控诊断、固件更新、在线调试、日志服务等。 数据应用:涉及数据的存储、分析和应用。 .应用层 4 应用层利用平台层处理后的信息来管理应用程序,应用层使用数据库、分 析软件等工具对平台层的数据进行过滤和处理。应用层的结果和数据可用于真 实的物联网应用,如智慧医疗、智能农业、智能家居和智能城市等。 当然,物联网的体系结构还可以再细分出更多的层次,但无论分为多少个 层次,其背后的原理都万变不离其宗。了解物联网的体系结构有助于加深对物 联网技术的理解和构建功能完整的物联网工程。 1.2 物联网应用之智能家居 物联网的应用已经渗透到了各行各业,和人们生活最息息相关的物联网应 用就要数智能家居了。很多传统家居已经使用了一件或多件物联网设备,许多 新建住宅从一开始就采用物联网技术进行设计。图1-1展示了一些常见的智能家 居设备。 图1-1 常见的智能家居设备 目前,智能家居发展阶段可以简单地划分为智能产品阶段、场景互联阶段 和智能阶段,如图1-2所示。 图1-2 智能家居的发展阶段 第一个阶段为智能产品阶段。与传统家居不同,在智能家居中,物联网设 备通过感知技术接收信号,通过Wi-Fi、Bluetooth LE(低功耗蓝牙)和ZigBee 等无线通信技术联网,用户可以通过多种多样的方式来控制智能产品,如智能 手机App、语音助手、智能音箱控制等。 第二个阶段为场景互联阶段。这个阶段不再是简单控制某个智能产品,而 是使两个或者多个智能产品进行互联互通,在一定程度上实现自动化,最终形 成一个自定义的场景模式。例如,当用户按下任意场景模式按键时就可以按预 先设定的场景模式开启灯光、窗帘、空调等智能家居设备。当然,其前提条件 是要设置好联动的逻辑,包括触发条件和执行动作。想象一下,当室内的温度 低于10 ℃时,触发空调制热模式;在早上7点时,播放用于唤醒用户的背景音 乐,伴随着音乐自动打开智能窗帘,电饭煲或面包机通过智能插座自动开始工 作;在起床洗漱的同时,早餐就准备好了,不耽误上班的时间,生活变得更加 方便了。 第三个阶段为智能阶段。随着接入的智能家居设备的增多,产生的各类数 据也会增多。借助于云计算、大数据和人工智能,智能家居就如同安装了“更加 智慧的大脑”,已经不需要主人频繁发出命令了。智能家居会从之前的交互中收 集数据并学习主人的行为模式和喜好,自动处理事务,包括提供用于决策的建 议。 现在,大多数智能家居正处于场景联动阶段。随着智能产品渗透率和智能 化的提高,通信协议之间壁垒正在被不断打破。在未来,智能家居一定能够实 现真正的“智能”,正如电影《钢铁侠》中智能系统贾维斯(Jarvis),不仅能帮 主人控制各种设备、处理日常事务,还具有超强的计算能力和思考能力。在智 能阶段,人们将获取数量更多、质量更高的服务体验。 第2章 物联网工程项目的介绍和实战 第1章简要阐述了物联网的体系结构,介绍了感知控制层、网络层、平台 层、应用层的作用和相互关系,以及智能家居的发展阶段。和学习游泳一 样,学习物联网,仅仅了解理论知识是远远不够的,还需实际“下水”,动手实 现物联网工程项目才能真正掌握物联网技术。除此之外,当工程项目走向产 品的量产阶段时,还需要考虑网络连接、配置、物联网云平台交互、固件管 理和升级、量产管理、安全配置等多方面因素。 在开发一个完整的物联网工程项目时,我们需要注意哪些方面呢?第1章 中提到了智能家居是最常见的物联网应用场景之一,而智能灯又是智能家居 中最基础且最实用的家电之一,可以应用在家庭、酒店、体育馆、医院、道 路等场所,因此本书以搭建智能照明工程为切入点,逐步对该工程项目的基 本组成、可实现功能等进行阐述,并给出相对完整的工程项目开发指导。希 望读者们以此项目为参考,做到举一反三,构建丰富多彩的物联网应用。 2.1 典型的物联网工程项目介绍 从开发的角度来看,可以将物联网工程项目简单地分为物联网设备的软 件开发和硬件开发、用户端应用程序开发、物联网云平台开发等基础功能模 块。明确基础功能模块是十分重要的,本节将对相关内容进行介绍。 2.1.1 常见物联网设备的基本模块 物联网设备的软件开发和硬件开发主要包括以下基本模块: 数据采集。作为物联网体系结构的底层,感知控制层中的物联网设备通 过所用芯片及其外设,将不同的传感器和设备连接起来,可实现数据采集、 运行控制等功能。 用户绑定与初始化配置。在大多数物联网设备中,用户绑定与初始化配 置是在一个操作流程中完成的,如可通过配置Wi-Fi网络来建立用户和设备之 间的绑定关系。 与物联网云平台交互。为了实现对物联网设备的监控、控制功能,还需 要将物联网设备连接到物联网云平台,通过与物联网云平台的交互来实现运 行控制、状态上报等功能。 设备控制。设备通过与物联网云平台建立网络连接,可实现和云端的通 信,完成设备注册、绑定、控制等功能。用户可以通过物联网云平台或本地 通信协议,在智能手机App上完成产品的状态查询与操作。 固件更新。物联网设备还可以根据设备厂商的需求完成固件更新。通过 接收云端发送的固件更新命令,可以实现固件更新和版本管理。通过固件更 新功能可不断完善物联网设备的功能,修复缺陷,提升用户体验。 2.1.2 用户端应用程序基本模块 用户端应用程序(如智能手机App)主要包括以下基本模块: 账户体系与授权。支持账户与设备授权。 设备控制。智能手机App通常具有控制设备的功能,用户可轻松便捷地通 过智能手机连接物联网设备,通过智能手机App随时随地控制、管理物联网设 备。其实,在实际的智能家居中,设备主要是通过智能手机App来进行控制 的,这样不仅可以实现设备的智能化管理,还可以节省人力的支出,所以设 备控制是必需的功能,如设备功能属性控制、场景控制、时间设定、远程控 制、设备联动等。智能家居的用户还可以根据个人需求来设置个性化的场 景,对照明、家电、门禁等进行控制,让用户的家居生活更加舒适、便利, 如定时开关空调、远程关闭空调、打开门锁时玄关灯联动开启、一键开启“影 院”模式等。 消息通知。该功能可将物联网设备运行状态的各项数据实时地反馈到智 能手机App上,当物联网设备出现异常时,可远程向智能手机App发送报警信 息。 售后客服。智能手机App可以提供产品的售后服务,从而及时为用户解决 物联网设备故障和技术操作等相关问题。 特色功能。为了满足不同用户的需求,还可增加一些实用的功能,如摇 一摇、NFC、GPS等。GPS功能可根据地点、距离来设定场景执行的精度;摇 一摇功能则可通过摇一摇来设定设备或场景所要完成的命令。 2.1.3 常见的物联网云平台简介 物联网云平台是一个集成了设备管理、数据安全通信和消息管理等功能 的一体化平台。根据面向的群体和是否开放,物联网云平台可分为公有物联 网云平台(简称公有云)和私有物联网云平台(简称私有云)。 公有物联网云平台通常指由物联网云平台提供商为企业或个人提供的共 享物联网云平台。公有物联网云平台由物联网云平台提供商运维,通过互联 网实现和企业或个人的共享。公有物联网云平台可能是免费或低成本的,可 在整个开放的公有网络中提供服务,如阿里云、腾讯云、百度云、AWS IoT、 Google IoT等。公有物联网云平台作为一个支撑平台,能够整合上游的服务提 供商和下游的终端用户,打造新的价值链和生态系统。 私有物联网云平台是为了企业单独使用而构建的,因而可提供对数据、 安全性和服务质量的最有效控制。私有物联网云平台的服务和基础结构由企 业单独进行维护,配套的硬件和软件也专供企业使用。企业可以自定义云服 务的功能以满足其业务的需求。目前,部分智能家居厂商已经拥有私有物联 网云平台,并基于私有物联网云平台开发智能家居应用。公有物联网云平台 和私有物联网云平台各有优势,在这里不做详细介绍。 要实现完整的通信连接,至少需要完成设备端的嵌入式开发、业务服务 器和物联网云平台的开发及配置、智能手机App的开发等。面对如此庞大的工 程,公有物联网云平台通常会提供设备端和智能手机App的软件开发工具包来 加快开发的过程。公有物联网云平台和私有物联网云平台主要提供物联网设 备接入、设备管理、设备影子、运维功能等。 (1)物联网设备接入。物联网云平台不仅需要提供设备接入的相关接 口,可选择的协议有MQTT、CoAP、HTTPS、WebSocket等;同时还需要提供 设备安全认证的功能,以防止伪造和非法设备的接入,从而有效降低设备被 攻破的安全风险。安全认证的功能通常提供了不同的设备认证机制,在设备 量产时,需要根据所选择的设备认证机制预分配设备证书,并将设备证书烧 录到设备中。 (2)设备管理。物联网云平台提供的设备管理功能,不仅可以帮助厂商 实时了解其设备的激活状态、在线状态,还可以提供设备的添加删除、检 索、分组添加删除、固件更新和版本管理等功能。 (3)设备影子。物联网云平台可以为每台设备创建持久虚拟版(设备影 子),通过互联网传输协议,智能手机App或其他设备可获取并同步设备影子 的状态。设备影子保留了每台设备的最后上报状态和期望的未来状态,即使 设备处于离线状态,也可以通过相关API获取设备的最后上报状态或设置的期 望未来状态。设备影子提供始终可用的API,使得构建与设备进行交互的智能 手机App变得更加轻松。 (4)运维功能。运维功能包括三个方面:展示物联网设备和消息的一些 统计值;日志管理提供了设备行为、上/下行消息流、消息内容等的查询功 能;设备调试提供物联网云平台对设备的调试功能,可以设置属性及下发命 令,查看物联网云平台和设备报文的交互。 2.2 实战:智能照明工程 本书在每章的理论讲解之后都会介绍智能照明工程的实战,方便读者在 学习完理论知识后进行实践学习。智能照明工程以乐鑫科技提供的ESP32-C3 和ESP RainMaker物联网云平台为基础,完成智能照明产品中的无线模组硬 件、基于ESP32-C3的智能设备嵌入式软件、智能手机App、ESP RainMaker物 联网云平台交互等的设计与开发。 项目源码 : 为 了 便 于 读 者 开 发 或 学 习 , 本 书 提 供 了 项 目 源 码 , 读 者 可通过GitHub或Gitee获取项目源码。 2.2.1 工程框架 为了更好地理解本书介绍的智能照明工程,本节介绍智能照明工程的框 架,该工程由以下三个部分组成: (1)基于ESP32-C3的智能照明产品设备端。负责完成与物联网云平台的 交互,控制LED灯珠的开关、亮度和色温。 (2)智能手机App(包括运行Android和iOS的平板电脑App等)。通过智 能手机App完成智能照明产品的网络配置,并能通过智能手机App轻松地控制 和查询智能照明产品的状态。 (3)以ESP RainMaker为基础的物联网云平台(为了简化,将物联网云 平台和业务服务器看成一个整体)。读者可在第3章中查看ESP RainMaker的 详细介绍。 将智能照明工程对应到物联网的体系结构,可得到智能照明工程的参考 结构,如图2-1所示。 图2-1 智能照明工程的参考结构 2.2.2 工程功能 智能照明工程由三个部分组成,其功能如下: (1)智能照明产品设备端。设备网络配置、连接等功能;LED PWM控 制,如开关、亮度、色温等;自动化或场景功能,如定时开关等;Flash的加 密和安全启动功能;固件更新和版本管理功能。 (2)智能手机App。提供设备网络配置、设备绑定功能;智能照明产品 控制,如开关、亮度、色温等;自动化或场景设置,如定时开关等;本地控 制和远程控制;用户注册、登录等。 (3)ESP RainMaker物联网云平台。提供物联网设备接入功能;提供智 能手机App可访问的设备操作API;固件更新和版本管理。 2.2.3 硬件准备 在了解智能照明工程的框架和功能后,有兴趣实战的读者,还需要准备 以下硬件:智能灯具、智能手机、Wi-Fi路由器、一台可满足开发环境安装要 求的计算机。 (1)智能灯具。智能灯具是一种新型灯泡,其外形与一般的乳白色白炽 灯泡相同。智能灯具由电容降压式稳压电源、无线模组(内置ESP32-C3)、 LED控制器及红(R)、绿(G)、蓝(B)三基色LED阵列组成。接通电源 后,经电容降压、二极管整流、稳压后输出的15 V直流电压可为LED控制器和 三基色LED阵列提供电源。LED控制器能按一定的时间间隔自动发出高电平和 低电平,控制三基色LED阵列的导通(点亮)与截止(熄灭),从而让其发 出青、黄、绿、紫、蓝、红和白色光。无线模组负责连接Wi-Fi路由器,接收 和上报智能灯具的状态,并发送命令控制LED。 在前期开发过程中,读者可以通过ESP32-C3-DevKitM-1开发板外接三色 LED灯珠模拟一个智能灯具(见图2-2)。特别说明的是,这种方式并不是实 现智能灯具的唯一方式,本书介绍的智能照明工程硬件设计中仅包含无线模 组(内置ESP32-C3),并不包含一个完整的智能灯具硬件设计。 图2-2 通过ESP32-C3-DevKitM-1开发板外接三色LED灯珠模拟一个智能灯具 除此之外,乐鑫还有基于ESP32-C3的ESP32-C3-Lyra音频灯控开发板。该 开发板有麦克风、扬声器接口,支持RGB彩色灯带的控制,可实现超高性价 比的音频播报机、炫酷的智能音乐律动灯带等产品。ESP32-C3-Lyra音频灯控 开发板外接40个LED的灯带如图2-3所示。 图2-3 ESP32-C3-Lyra音频灯控开发板外接40个LED的灯带 (2)智能手机。可以选择Android或iOS系统的智能手机,该智能照明工 程开发完成后将包含一个可在智能手机上安装的软件,用于控制、设置智能 照明产品。 (3)Wi-Fi路由器。通过Wi-Fi路由器把有线网络信号和移动网络信号转 换成无线网络信号,可用于支持Wi-Fi技术的相关计算机、智能手机、Pad、无 线设备等的无线联网。例如,家中的宽带只需要连接一个Wi-Fi路由器,就可 以 实 现 Wi-Fi 设 备 的 无 线 联 网 。 Wi-Fi 路 由 器 支 持 的 主 流 协 议 标 准 为 IEEE 802.11n , 传 输 速 率 为 300 Mbit/s , 最 高 可 达 600 Mbit/s , 可 向 下 兼 容 IEEE 802.11b和IEEE 802.11g。ESP32-C3支持IEEE 802.11b/g/n,因此可选用单频 (2.4 GHz)或双频(2.4 GHz和5 GHz)的Wi-Fi路由器。 (4)一台可满足开发环境安装要求的计算机。可以选择安装Linux、 Mac、Windows等操作系统的计算机。本书将在第4章介绍开发环境的搭建。 2.2.4 开发步骤 智能照明工程的开发步骤如图2-4所示。 图2-4 智能照明工程的开发步骤 硬件设计。物联网工程的开发离不开物联网设备的硬件设计,一个完整 的智能照明工程,会有一个可在市电环境下工作的灯具。不同的设备制造商 会生产不同样式和不同驱动类型的灯具,但是无线模组部分通常都具有相同 的功能。为了简化智能照明工程的开发过程,本书仅介绍无线模组的硬件设 计和软件开发。 物联网云平台配置。使用物联网云平台,需要在管理后台进行项目配 置,如创建产品、创建设备、设备属性等配置。 物联网设备嵌入式软件开发。根据乐鑫科技提供的设备端SDK(ESP- IDF)完成智能照明产品的相关功能,如连接物联网云平台、LED驱动开发、 固件更新等。 智能手机App开发。基于Android和iOS系统分别开发智能手机App,完成 用户的注册和登录、设备控制等功能。 物联网设备优化。在物联网设备功能基本开发完成后,可以着手进行相 关的优化工作,如功耗优化。 量产测试。根据产品的功能和相关规范进行相关的量产测试,如设备功 能测试、老化测试、射频测试等。 智能照明工程的开发不一定要严格按照上述的步骤进行,不同的工作也 可以同时进行。例如,物联网设备嵌入式软件开发和智能手机App开发可以同 时进行。一些步骤也可能需要重复进行,如物联网设备优化和量产测试。 2.3 本章总结 本章系统地阐述了一个物联网工程的基本组成,并对物联网工程的基础 功能模块进行了概述。在介绍完理论知识后进入到了本书的实战案例,即构 建智能照明工程,并给出了项目框架、项目功能、硬件准备、开发步骤等内 容。通过本章介绍的实战项目,读者可以举一反三,对任何一个物联网工程 开发都能做到胸有成竹,在开发中少走弯路。 第3章 ESP RainMaker 介绍 物联网为改变人们的生活方式提供了无限可能,但物联网工程的开发过程也 充满了挑战。在公有云中,终端厂商可以通过以下两种方案实现产品功能: 基于方案商云平台的实现方案。终端厂商只需要完成产品的硬件设计,随后 使用方案商提供的通信模组完成硬件对接,按照指引设定产品功能即可。这是一 种快速且高效的方法,免去了服务器端与应用端的开发、运维等工作。该方法可 以让终端厂商专注于硬件设计,无须考虑云端的实现。但不足之处是,基于方案 商云平台的实现方案(如设备固件与App)一般不会开源,产品功能会受限于方 案商云平台,无法进行个性化的自定义,同时用户及设备数据属于方案商云平 台。 基于云产品的实现方案。终端厂商完成硬件设计后,不仅需要使用公有云提 供的单个或多个云产品实现云端功能,还需要完成硬件与云端的对接。以接入 AWS(Amazon Web Services)为例,至少需要使用的AWS产品有Amazon API Gateway、AWS IoT Core、AWS Lambda,通过使用这些AWS产品可以实现设备 接入、远程控制、数据存储、用户管理等基本功能。这就不仅要求终端厂商对云 产品有非常深入的了解与丰富的实践经验,才能灵活运用和配置这些云产品,还 需要终端厂商考虑云端初期的建设成本与后期的维护成本,对于公司精力和资源 投入都是很大的挑战。 相比公有云,私有云通常是针对特定项目和产品进行搭建的,私有云开发者 在协议设计、业务逻辑实现上有最大程度的自由性,终端厂商可以随意制定产 品、设计方案,轻松整合并赋能用户数据。乐鑫科技将公有云的高安全性、高可 拓展性、高可靠性等特点与私有云的优势结合起来,推出了基于亚马逊云平台的 深度集成私有云方案——ESP RainMaker,用户只需要一个AWS账号便可部署 ESP RainMaker,完成私有云的搭建。 3.1 什么是ESP RainMaker ESP RainMaker是一个完整的AIoT平台,使用多个成熟的AWS产品进行构 建,可提供设备云接入、设备升级、管理后台、第三方登录、语音集成、用户管 理等多个量产产品所需的服务。通过使用AWS提供的无服务器应用程序的托管存 储库SAR(Serverless Application Repository),可以将ESP RainMaker快速部署到 终端厂商AWS账号中,从而节省时间并降低部署的复杂程度。ESP RainMaker使 用的SAR由乐鑫科技管理与维护,可帮助开发者降低云端维护成本,加速AIoT产 品 的 开 发 , 构 建 安 全 稳 定 且 可 定 制 化 的 AIoT 解 决 方 案 。 图 3-1 所 示 为 ESP RainMaker方案架构。 图3-1 ESP RainMaker方案架构 乐鑫科技提供了可用于方案评估的ESP RainMaker公共服务器,该服务器将 免费开放给所有的ESP开发爱好者、创客及教育工作者。开发者在使用ESP RainMaker公共服务器时无须AWS账号与部署,可支持苹果、谷歌、GitHub等账 号 的 登 录 , 利 用 该 服 务 器 可 以 快 速 构 建 自 己 的 物 联 网 应 用 产 品 原 型 。 ESP RainMaker公共服务器完成了第三方应用(Alexa、Google Home)的对接,并集 成了语音控制能力(RainMaker物联网设备的语音控制能力通过技能的形式对接 第三方实现,语义识别由第三方提供,RainMaker物联网设备只响应具体动作, 已支持的语音命令可在第三方平台查看),同时乐鑫科技提供了公版的 RainMaker智能手机App(RainMakerApp),方便用户通过智能手机对产品进行 控制。 3.2 ESP RainMaker 的实现原理 ESP RainMaker的结构如图3-2所示。 ESP RainMaker 由 4 个 部 分 构 成 : Claiming 服 务 ( Claiming Service ) , 为 RainMaker设备提供动态获取设备证书的能力;RainMaker云(RainMaker Cloud, 也称为云后端),提供消息过滤、用户管理、数据存储、第三方对接等服务; RainMaker设备侧代理程序(RainMaker Agent),为RainMaker设备提供连接到 RainMaker云的能力;客户端(RainMaker Client),提供RainMaker App和CLI脚 本两种形式的客户端,用于完成网络配置、用户创建、用户设备关联和控制等功 能。 ESP RainMaker提供了一套完整的工具,用于支持开发者的开发与量产,包 括: 图3-2 ESP RainMaker的结构 (1)RainMaker SDK。SDK用于构建固件,建立在ESP-IDF之上,提供了设 备侧代理程序源码及相关C API。开发人员只需编写应用程序逻辑,其余的留给 RainMaker处理即可。 扩展阅读 :通过https://bookc3.espressif.com/rm/c-api-reference,可获取更多关 于C API的说明。 (2)RainMaker App。ESP RainMaker提供了公版RainMaker App,通过该 App不仅可以完成设备网络配置,还可以轻松地控制和查询智能照明产品的状态 等。针对不同操作系统,乐鑫科技提供了iOS版和Android版的RainMaker App, 详见第10章。 (3)REST API。可用于构建用户自己的应用程序,类似于ESP RainMaker提 供的RainMaker App。通过链接https://swaggerapis.rainmaker.espressif.com/,可获 取更多关于REST API的说明。 (4)Python API。提供了一个基于Python的CLI来实现所有类似于智能手机 App的功能(CLI附带在RainMaker SDK中)。 扩 展 阅 读 : 通 过 https://bookc3.espressif.com/rm/python-api-reference, 可 获 取 更多关于Python API的说明。 (5)Admin CLI。针对私有部署提供更高等级的管理员CLI,用于批量生成 设备证书。 3.2.1 Claiming 服务 RainMaker设备与云后端之间的所有通信都是通过MQTT+TLS进行的,ESP RainMaker中的Claiming服务是指设备从Claiming服务获取连接云后端设备证书的 过程,Claiming服务仅适用于乐鑫科技提供的公共RainMaker服务,对于私有部 署,设备证书需要通过Admin CLI批量生成。ESP RainMaker支持三种类型的 Claiming服务。 自身Claiming(Self Claiming)。设备在连接到网络后通过预先编程在eFuse 中的密钥完成设备证书的验证及获取。 主 机 Claiming ( Host Driven Claiming ) 。 在 用 户 开 发 的 主 机 中 通 过 登 录 RainMaker账号获取设备证书。 协助Claiming(Assisted Claiming)。在配置网络时由智能手机协助完成设备 证书的获取。 3.2.2 RainMaker 设备侧代理程序 RainMaker设备侧代理程序的主要功能是提供连接能力、协助应用层处理云 上/下行数据。该代理程序由RainMaker SDK构建,基于成熟的ESP-IDF开发框架 开发,使用了ESP-IDF中的RTOS、NVS、MQTT等组件。图3-3所示为RainMaker SDK的结构。 图3-3 RainMaker SDK的结构 RainMaker SDK的具体功能如下: (1)连接功能,包括: ①配合Claiming服务进行设备证书的获取。 ②使用安全的MQTT协议连接云后端,提供远程连接能力,满足远程控制、 消息上报、用户管理、设备管理等需求,默认使用ESP-IDF中的MQTT组件实 现,同时提供一个抽象层,以便对接其他的协议栈。 ③使用wifi_provisioning组件实现Wi-Fi连接与配网,使用esp_https_ota组件实 现OTA升级,使用esp_local_ctrl组件实现本地发现与连接,这些能力通过简单的 配置即可实现。 (2)数据处理功能,包括: ①存储Claiming服务下发的设备证书以及运行RainMaker时需要存储的数据, 默认使用nvs_flash组件提供的接口进行存储,对外提供API供开发者直接使用。 ②使用回调机制处理云上/下行数据,自动解封数据给应用层,方便开发者处 理。例如,物联网设备需要定义一些物模型用于描述设备及实现功能(定时、倒 计时、语音控制),RainMaker SDK提供了丰富的接口方便创建物模型数据。对 于定时之类的基础交互功能,RainMaker SDK提供了免开发的方案,仅需要在开 发时启用该功能即可,RainMaker设备侧代理程序能够直接处理这些数据,并通 过相关的MQTT主题发送到云端,通过回调机制反馈云后端对这些数据的更改。 3.2.3 云后端 云后端是基于AWS无服务器计算(Amazon Serverless Computing)构建的, 使用AWS Cognito(身份管理系统)、Amazon API Gateway(API网关)、AWS Lambda(无服务器计算服务)、Amazon DynamoDB(NoSQL数据库)、AWS IoT Core(物联网接入核心,提供MQTT接入和规则过滤)、Amazon Simple Email Service(SES简易邮件服务)、Amazon CloudFront(快速交付网络)、 Amazon Simple Queue Service(SQS消息队列)、Amazon S3(桶存储服务)实 现,旨在实现最佳的可扩展性和安全性。使用ESP RainMaker,开发者无须在云 中编写代码,即可实现设备的管理,设备上报的消息以透明传输的形式提供给应 用客户端或其他第三方服务。 云后端使用的AWS云产品及功能如表3-1所示,更多云产品和功能正在开发 中。 表3-1 云后端使用的AWS云产品及功能 3.2.4 客户端 RainMaker的客户端(如App和CLI)与云后端通信是通过REST API实现的, 开发者可以在乐鑫科技提供的Swagger文档中找到REST API的详细信息及使用说 明。RainMaker的手机应用客户端提供iOS和Android版本,可以实现设备的配 网、控制、分享,以及创建与启用定时倒计时任务、连接至第三方平台。 RainMaker的手机应用客户端可以根据设备上报的配置自动加载UI及图标,完整 展示设备物模型。例如,使用RainMaker SDK提供的例程构建智能灯,在完成配 网后将自动加载球泡灯的图标及UI,通过UI可以更改球泡灯颜色、亮度,再通过 技能(亚马逊平台技能指Alexa Smart Home Skill,谷歌平台技能指Google Smart Home Actions)绑定ESP RainMaker账号后,就可以实现第三方应用对球泡灯的控 制。图3-4分别为Alexa、Google Home、ESP RainMaker App上球泡灯的图标与UI 示例。 图3-4 Alexa、Google Home、ESP RainMaker App上球泡灯的图标与UI示例 图3-4 Alexa、Google Home、ESP RainMaker App上球泡灯的图标与UI示例(续) 3.3 实战:ESP RainMaker开发要点 在完成设备驱动层开发后,开发者的主要工作是利用RainMaker SDK提供的 API创建设备物模型及处理下行数据,同时根据产品的定义与需求启用ESP RainMaker基础服务。 本书的9.4节将介绍LED智能灯在RainMaker中的实现,在调试阶段可以使用 RainMaker SDK 中 的 CLI 工 具 完 成 与 LED 智 能 灯 的 通 信 ( 开 发 者 也 可 以 通 过 Swagger工具调用REST API完成通信)。本书的第10章将在智能手机App的开发 中介绍REST API的使用。LED智能灯的OTA升级功能将在本书的第11章中介绍。 如果开发者启用了ESP Insights远程监察平台功能,则ESP RainMaker管理后台将 提供ESP Insights数据的展示,这一部分内容将在本书的第15章中介绍。 ESP RainMaker提供了私有部署服务,与乐鑫科技提供的公共服务器相比, 二者的区别在于: (1)Claiming服务。私有部署必须使用Admin CLI来生成设备证书。因为自 身Claiming需要单独的身份验证服务器,使用主机Claiming或协助Claiming的设备 将获得管理员权限,这在私有部署中是不可取的。公共服务器因为需要对所有的 开发者开放固件更新功能,所以必须赋予开发者管理员权限。 (2)应用程序。私有部署需要为应用程序单独进行配置与编译,确保使用 账户体系不互通。 (3)第三方登录与语音集成。需要使用开发者的第三方账户进行配置。 小贴士 : 通 过 链 接 https://customer.rainmaker.espressif.com, 开 发 者 可 以 完 成 云 端 的部署。对固件来说,从公共服务器迁移到私有服务器仅仅需要替换设备证书, 这将极大地提高迁移效率,降低迁移和二次调试的成本。 3.4 ESP RainMaker 功能摘要 ESP RainMaker提供以下功能,这些功能可简单分为账户管理功能、对终端 用户开放的功能、对管理员用户开放的功能,在没有特别说明的情况下,这些功 能都可以在公共服务器与私有服务器上使用。 3.4.1 账户管理功能 账户管理功能允许终端用户进行注册与登录、更改密码、忘记密码等操作。 (1)注册与登录。RainMaker的注册与登录方式包括:电子邮件地址+密 码、手机号码+密码、谷歌账号、苹果账号、GitHub账号(仅限于公共服务 器)、亚马逊账号(仅限于私有服务器)。 注意:当用户使用谷歌账号或亚马逊账号注册时,RainMaker将获取用户的 电子邮件地址;当用户使用苹果账号注册时,RainMaker将获取苹果为用户配置 的、专用于RainMaker服务的虚拟地址。新用户在使用谷歌、苹果或亚马逊账号 登录RainMaker时将自动创建新的账号。 (2)更改密码。只有在使用电子邮件地址+密码或手机号码+密码的方式登 录时,用户才可更改密码。密码更改成功后,其余活动会话将退出登录。在AWS Cognito服务中,会话退出登录后将继续保持一定时长的执行状态,最长为1小 时。 (3)忘记密码。只有使用电子邮件地址+密码或手机号码+密码的方式登录 时,用户才可以找回密码。 3.4.2 对终端用户开放的功能 对终端用户开放的功能允许终端用户实现设备的远程控制与监测、设备的本 地控制与监测、设定定时、对设备创建群组、共享设备、接收推送通知、连接到 第三方,以下为功能概要。 (1)设备的远程控制与监测。包括查询某个或所有设备的配置、参数值和 连接状态;对单个或多个设备下发参数。 (2)设备的本地控制与监测。通过本地网络实现控制功能。在使用本地控 制与监测功能时,用户需要将智能手机和设备接入同一个网络。 (3)设定定时。在用户设定的时间触发设备的某个功能,设置成功后设备 无须联网,支持一次性或重复定时,可以指定单个或多个设备。 (4)对设备创建群组。支持多层次的抽象群组,可用群组的元数据创建“家- 房间”结构。 (5)设备共享。可与一个或多个用户共享一个或多个设备。 (6)接收推送通知。在以下情况终端用户将收到推送通知,如添加新设 备、删除设备、设备连接到云端、设备从云端断开连接、创建设备共享请求、接 受或拒绝设备共享请求、设备报告警告信息。 (7)连接到第三方。允许在Alexa与Google Home中通过技能登录并控制 RainMaker设备,支持的品类包括球泡灯、开关、插座、风扇、温度传感器等。 3.4.3 对管理员用户开放的功能 对管理员用户开放的功能允许管理员用户实现设备注册、设备群组、OTA升 级、查看统计数据、查看ESP Insights数据,以下为功能概要。 (1)设备注册。生成设备证书并使用Admin CLI进行注册(仅限于私有服务 器)。 (2)设备群组。根据设备信息创建抽象群组或结构群组(仅限于私有服务 器)。 (3)OTA(Over-the-Air)升级。可根据版本、型号推送固件;将固件推送 至一个或多个设备或某个群组;监控、取消、归档OTA升级任务状态。 (4)查看统计数据。可查看的统计数据包括设备注册(由管理员用户注册 的设备证书)数量、设备激活(即设备首次连接)数量、账户创建数量、用户与 设备的关联数量。 (5)查看ESP Insights数据。可查看的ESP Insights数据包括错误、警告和自 定义日志,崩溃报告和分析,重启原因,内存占用率,RSSI等指标,自定义的指 标和变量。 3.5 本章总结 本章对比了当前公有云与私有云在产品层面上的差异。乐鑫科技推出了可靠 性高、拓展性强的私有云ESP RainMaker方案。目前,ESP32系列芯片均已接入并 适配AWS,可以极大地降低使用AWS成本,开发者无须了解各种AWS云产品, 可专注于产品原型的验证。同时本章还介绍了ESP RainMaker实现原理、功能概 要,以及使用ESP RainMaker进行实战开发的要点。 扫描下载ESP RainMaker Android手机 App 扫描下载ESP RainMaker iOS手机App 第4章 开发环境的搭建与详解 本章首先介绍ESP32-C3的官方软件开发框架ESP-IDF(包含开发环境),以 及在不同计算机操作系统上搭建开发环境的方法;然后以一个典型工程为例,介 绍ESP-IDF代码工程结构、编译系统,以及相关开发工具的使用方法;最后演示 示例代码的实际编译和运行过程,详细解读不同环节的输出信息。 4.1 ESP-IDF 概述 ESP-IDF(Espressif IoT Development Framework)是乐鑫科技提供的一站式 物联网开发框架,它以C/C++为主要的开发语言,支持Linux、Mac、Windows等 主流操作系统下的交叉编译。本书提供的示例程序均是基于ESP-IDF搭建的,具 有以下特性: (1)包含ESP32、ESP32-S2、ESP32-C3等系列的SoC系统级驱动,主要包括 外设底层LL(Low Level)库、HAL(Hardware Abstraction Layer)库、RTOS支 持和上层驱动软件等。 (2)包含物联网开发必要的基础组件,主要包括HTTP、MQTT等多种网络 协议栈,可支持动态调频的电源管理框架,以及Flash加密方案和Secure Boot方案 等。 (3)提供了开发和量产过程中常用的构建、烧录和调试工具(见图4-1), 例如基于CMake的构建系统、基于GCC的交叉编译工具链、基于OpenOCD的 JTAG调试工具等。 值得注意的是,ESP-IDF代码主要遵守Apache 2.0开源协议,在遵守开源协议 的前提下,用户可以不受限制地进行个人或商业软件开发,并且免费拥有永久的 专利许可,无须开源修改后的源代码。 4.1.1 ESP-IDF 版本介绍 ESP-IDF代码在GitHub上开源,目前有v3、v4和v5三个主要版本,每个主要 版本通常包含多个不同的子版本,如v4.2、v4.3等。乐鑫科技还为每个已发布的 子版本提供30个月的bug修复、安全修复支持,因此一般还会发布子版本的修订 版本,如v4.3.1、v4.2.2等。不同版本的ESP-IDF对乐鑫芯片的支持状态如表4-1所 示,其中preview表示提供预览版本的支持,预览版本可能缺少关键的功能或文 档,supported表示提供正式版本的支持。 图4-1 在开发和量产过程中常用的构建、烧录和调试工具 表4-1 不同版本的ESP-IDF对乐鑫芯片的支持状态 主要版本的迭代往往伴随着框架结构的调整和编译系统的更新,如v3.* 到 v4.* 的主要变化是构建系统从Make逐渐迁移到CMake;子版本的迭代一般意味着 新增功能或新增芯片支持。 读者还需要注意稳定版本和GitHub分支的区别和联系,如上所述的带有v*.* 或v*.*.* 标签的版本均为稳定版本,稳定版本已通过乐鑫科技的完整内部测试, 同一版本下的代码、工具链、发布文档在固定后不再变更。而GitHub分支(如 release/v4.3分支)则几乎每天都会有新的代码提交,因此,同在该分支下的两份 代码可能是不同的,需要开发者及时更新。 4.1.2 工作流程 ESP-IDF Git 乐鑫科技ESP-IDF Git的工作流程如下: 新的改动总是在master分支(主开发分支)上进行的,master分支上的ESP- IDF版本总带有-dev标签,表示正在开发中,如v4.3-dev。master分支上的改动将 首先在乐鑫科技的内部仓库中进行代码审阅与测试,然后在自动化测试完成后推 至GitHub。 新版本一旦完成特性开发(在master分支上进行)并达到进入Beta测试的标 准,则会将这个新版本切换至一个新分支(如release/v4.3)。此外,这个新分支 还会加上预发布标签(如v4.3-beta1)。开发者可以在GitHub平台上查看ESP-IDF 的完整分支列表和标签列表。Beta版本(预发布版本)可能仍存在大量已知问 题,随着对Beta版本的不断测试,bug修复将同时增加至该版本分支和master分 支,而master分支可能也已经开始为下个版本开发新特性了。当测试快结束时, 该发布分支上将增加一个rc标签,表示候选发布(Release Candidate),如v4.3- rc1,此时该分支仍属于预发布版本。 如果一直未发现或未报告重大bug,则该预发布版本将最终增加主要版本 (如v5.0)或次要版本标记(如v4.3),成为正式发布版本,并体现在发布说明 页面中。后续,该版本中发现的bug都将在该发布分支上进行修复。在人工测试 完成后,该分支将增加一个Bugfix版本标签(如v4.3.2),并体现在发布说明页面 中。 4.1.3 选择一个合适的版本 由于ESP-IDF从v4.3版本正式开始对ESP32-C3提供支持,在撰写本书时还未 正式发布v4.4版本,因此本书使用的是v4.3.2修订版本。当读者阅读本书时,可能 已经发布了v4.4版本或更新的版本,对于版本的选择,我们建议: (1)对于入门开发者,推荐选择稳定的v4.3版本及其修订版本,与本书示例 版本保持一致。 (2)如果有量产需求,则推荐使用最新的稳定版本,以便获得最及时的技 术支持。 (3)如果需要尝试新芯片或者预研产品新功能,请使用master分支,最新版 本包含所有的最新特性,但存在已知或未知的bug。 (4)如果使用的稳定版本没有新特性,又想降低使用master分支的风险,请 使用对应的发布分支,如release/v4.4分支(ESP-IDF GitHub会先创建release/v4.4 分支,等完成全部功能的开发和测试后,再基于该分支的某一历史节点发布稳定 的v4.4版本)。 4.1.4 ESP-IDF SDK 目录总览 ESP-IDF SDK包含esp-idf和.espressif两个主要目录,前者主要包含ESP-IDF仓 库源代码文件和编译脚本,后者主要保存编译工具链等软件。熟悉这两个目录, 有助于开发者更好地利用已有的资源,加快开发过程。ESP-IDF的目录结构如下 所述。 (1)ESP-IDF仓库代码目录(~/esp/esp-idf)如图4-2所示。 ①组件目录components。该目录是ESP-IDF的核心目录,集成了大量的核心 软件组件,任何一个工程代码都无法完全脱离该目录的组件进行编译。该目录包 括对多款乐鑫芯片的驱动支持,从外设底层LL库、HAL库接口,到上层Driver、 VFS层支持,都能找到对应的组件,以供开发者进行不同层级的开发;ESP-IDF 还适配了多种标准网络协议栈,如TCP/IP、HTTP、MQTT、WebSocket等,开发 者可以使用Socket等自己熟悉的接口完成网络应用的开发。组件作为一个功能完 整的模块,可以方便地集成在应用程序中,开发者只需要专注于业务逻辑即可。 常用的组件如下: driver:包含乐鑫各系列芯片的外设驱动程序,如GPIO、I2C、SPI、 UART、LEDC(PWM)等。该组件中的外设驱动程序为用户提供了与芯片无关 的抽象接口,每个外设均有一个通用的头文件(如gpio.h),用户无须再特别处 理不同芯片的支持问题。 esp_wifi:Wi-Fi作为一个特殊外设,因此将其作为一个单独组件,该组 件包含了多种Wi-Fi驱动模式初始化、参数配置和事件处理等多个API。该组件的 部分功能以静态链接库的形式提供,ESP-IDF同时给出了详细的驱动说明文件, 方便用户快速使用。 freertos:包含了完整的FreeRTOS代码,乐鑫除了对该操作系统提供了完 整的支持,还扩展了该操作系统对双核芯片的支持,对于ESP32、ESP32-S3等双 核芯片,用户可以将任务创建在指定的内核上。 图4-2 ESP-IDF仓库代码目录 ②文档目录docs。该目录包含了ESP-IDF的相关开发文档,如快速入门手 册、API参考手册、开发指南等。 小贴士 : 该 目 录 经 过 自 动 化 工 具 的 编 译 后 , 会 部 署 在 https://docs.espressif.com/projects/esp-idf,注意请将文档切换为ESP32-C3,并选择指定 的ESP-IDF版本。 ③脚本工具tools。该目录包含了常用的编译前端idf.py、监视器终端工具 idf_monitor.py等,子目录cmake还包含了编译系统核心脚本文件,这些文件是实 现ESP-IDF编译规则的基础。在环境变量添加期间,tools目录中的内容将被添加 到系统环境变量,因此可以在项目路径下直接执行idf.py。 ④示例程序目录examples。该目录中包含了大量的ESP-IDF示例程序,以便 尽可能多地展示组件API的使用方法。按照示例类别,目录examples的子目录可 分为以下几类: get-started:入门示例子目录,包含hello world、blink等基础的示例程 序,便于读者入门学习。 bluetooth : 蓝 牙 示 例 子 目 录 , 包 含 Bluetooth LE Mesh 、 Bluetooth LE HID、BluFi等示例程序。 wifi:Wi-Fi示例子目录,包含Wi-Fi SoftAP、Wi-Fi Station等基础的示例 程序,espnow等乐鑫科技专有的通信协议示例程序,以及基于Wi-Fi的多个应用 层示例程序(如Iperf、Sniffer、Smart Config等)。 peripherals:外设示例子目录,这是一个比较大的文件夹,按照外设名称 又分为数十个子文件夹,主要包含乐鑫系列芯片的外设驱动示例程序,每个示例 程序均包含若干个示例。例如,子目录gpio中包含了GPIO和GPIO矩阵键盘两个 示例。需要注意的是,这里的示例未必都适用于ESP32-C3,例如usb/host中的示 例仅适用于包含USB Host硬件的外设(如ESP32-S3),而ESP32-C3不具有该外 设,对于这类示例,在设置目标时编译系统一般输出相应的提示。每个示例的 README文件中会列出已经适配的芯片。 protocols:通信协议示例子目录,该子目录包含了数十种通信协议的示 例程序,包括MQTT、HTTP、HTTP Server、PPPoS、Modbus、mDNS、SNTP 等,几乎涵盖了所有物联网开发所需的通信协议示例。 provisioning:配网示例子目录,该子目录包含了多种配网方式,如Wi-Fi 配网、Bluetooth LE配网等。 system:系统示例子目录,该子目录包含了系统调试示例(如堆栈追 踪、运行追踪、任务监控等),与电源管理相关的示例(如各种休眠模式、协处 理器等),以及控制台终端、事件循环、系统定时器等常用系统组件的示例。 storage:存储示例子目录,该子目录包含了ESP-IDF支持的所有文件系统 和 存 储 机 制 示 例 ( 如 Flash 、 SD 卡 等 存 储 媒 介 的 读 写 ) , 以 及 非 易 失 存 储 (NVS)、FatFS、SPIFFS等文件系统操作示例。 security:安全示例子目录,该子目录包含了与Flash加密相关的示例程 序。 (2)ESP-IDF编译工具链目录(~/.espressif)如图4-3所示。 ①软件分发目录dist。ESP-IDF工具链等软件会以压缩包的形式被分发,安装 工具在安装过程中先将压缩包下载到dist目录,再将其解压缩到指定的目录下 (安装完成后,可以清空该目录中的内容)。 图4-3 ESP-IDF编译工具链目录 ②Python虚拟环境目录python_env。由于不同版本的ESP-IDF依赖于不同版本 的Python软件包,如果这些软件包直接安装在同一台主机上则会引起软件包版本 冲突问题,因此ESP-IDF使用Python虚拟环境的方式隔离不同软件包版本冲突的 问题。基于这种机制,开发者可在主机上同时安装多个版本的ESP-IDF,只需要 在使用时导入不同的环境变量即可。 ③编译工具链目录tools。该目录主要包含编译ESP-IDF工程所需的交叉编译 工具,如CMake工具、Ninja构建工具,以及生成最终可执行程序的gcc工具链。 同时该目录还包含C/C++语言的标准库及对应的头文件,如果在程序中引用了系 统头文件,如#include ,则编译工具链将在该目录中查找该stdio.h头文 件。 4.2 ESP-IDF 开发环境安装详解 ESP-IDF开发环境支持Windows、Linux、Mac等主流操作系统,本节将一一 介绍在各系统上的开发环境安装过程。本书推荐在Linux系统上进行ESP32-C3开 发,这里将做详细介绍。由于不同平台的开发工具有极大相似性,部分说明在其 他平台上将不再赘述,因此推荐仔细阅读本节的内容。 扩展阅读 : 通 过 链 接 https://bookc3.espressif.com/esp32c3, 读 者 可 以 打 开 相 关的在线文档,以便查看本节涉及的命令。 4.2.1 在Linux系统下安装ESP-IDF开发环境 Linux系统原生自带了ESP-IDF开发环境所需的GNU开发和调试工具,其命令 行终端也更加强大易用,因此在Liunx系统上开发ESP32-C3将获得最佳的编译速 度和开发体验。开发者可以选择一个喜欢的Linux发行版本,本书推荐使用 Ubuntu或其他Debian系统。本节将以Ubuntu 20.04为例介绍ESP-IDF开发环境的安 装。 1 .安装依赖软件包 请打开一个新的终端,执行下面的命令可安装所有必要的软件包,已经安装 的软件包将被自动跳过: 小贴士 :在执行上面的命令时需要使用管理员账户和密码,输入密码时默认 不显示任何信息,按回车键即可。 软件包介绍。Git是ESP-IDF中关键的代码管理工具,在成功安装开发环境 后,可以使用命令git log来查看ESP-IDF自创建以来的每一次代码变更,除此以外 ESP-IDF还使用Git来确认版本信息,用于正确地安装对应版本的工具链。除了 Git,重要的系统工具还有Python,ESP-IDF中包含了大量使用Python语言编写的 自动化脚本。CMake、Ninja-build和Ccache等工具在以C/C++为主的工程中被广泛 使用,这些工具也是ESP-IDF默认使用的代码编译和构建工具。libusb-1.0-0和dfu- util作为主要驱动,被用于USB串口通信和固件烧录。 在成功安装软件包后,可以使用命令apt show 来查询各个软 件包的详细描述,使用命令apt show git打印Git工具的描述信息。 问:软件包下载速度太慢,应该怎么办? 答:读者可将Ubuntu系统的源切换为国内的服务器,在打开的Software& Updates ( 软 件 & 更 新 ) 界 面 中 , 将 Downloadfrom ( 下 载 服 务 器 ) 改 为 ServerforChina,如图4-4所示。 问:不支持Python版本,应该怎么办? 答:ESP-IDF的v4.3版本要求Python版本不低于v3.6。对于老版本的Ubuntu系 统,请手动下载并安装更高版本的Python,并将Python3设置为系统默认的Python 环境。通过搜索关键词update-alternatives python可以获得详细的设置过程。 2.下载ESP-IDF仓库代码 请打开一个终端,使用mkdir命令在主目录创建一个名称为esp的文件夹(当 然也可以将文件夹设置为其他名字),并使用cd命令进入该文件夹。命令如下: 图4-4 将Ubuntu系统的源切换为国内的服务器 使用git clone命令下载ESP-IDF仓库代码,命令如下: 在上面的命令中,参数-b v4.3.2表示将下载并切换到v4.3.2版本;参数-- recursive表示在主仓库下载完成后,将递归地下载ESP-IDF所有的子仓库,子仓 库信息可在.gitmodules文件中查询。 问:代码下载速度太慢,应该怎么办? 答:由于GitHub服务器访问速度较慢,可以使用国内Gitee仓库加速下载。方 法如下: (1)使用git clone命令从Gitee上下载ESP-IDF主仓库代码,命令如下: 在上面的命令中,参数-b v4.3.2表示将下载并切换到v4.3.2版本。注意,这里 不再使用参数--recursive,这是因为ESP-IDF子仓库使用的是相对路径,Gitee上可 能没有对应的子仓库地址。 (2)为了下载子仓库,下载esp-gitee-tools工具。命令如下: (3)进入esp-gitee-tools目录,添加工具所在路径,方便后期使用。命令如 下: (4)返回esp-idf目录下载子仓库代码。命令如下: 3 .安装ESP-IDF开发工具链 乐鑫科技提供的自动化脚本install.sh可自动完成工具链的下载和安装,该脚 本首先会检查当前的ESP-IDF版本和操作系统环境;然后下载并安装对应版本的 Python工具包和编译工具链,工具链的默认安装路径为~/.espressif;最后进入esp- idf目录运行install.sh即可。命令如下: 成功安装工具链后终端将显示: 至此便完成了ESP-IDF开发环境的安装。 问:工具链下载速度太慢,应该怎么办? 答:由于pip工具默是认从原始服务器下载Python工具包的,芯片的工具链也 默认从GitHub服务器下载,在国内访问以上资源的速度比较慢,可通过重定向下 载路径的方法来提升下载速度。方法如下: (1)重定向pip下载:可以在执行./install.sh命令之前先执行以下命令,将pip 服务器修改为mirrors.aliyun.com(国内的阿里云)。 (2)重定向编译工具链下载:可以在执行./install.sh命令之前先执行以下命 令,将下载服务器改为乐鑫科技的官方服务器。 4.2.2 在Windows系统下安装ESP-IDF开发环境 1.下载ESP-IDF安装工具 小贴士 :推荐在Windows 10及以上版本的系统下安装ESP-IDF开发环境,读者 可以通过https://dl.espressif.com/dl/esp-idf/下载安装包。安装工具本身也是一个开源软 件,可以通过https://github.com/espressif/idf-installer 查看源代码。 (1)在线安装工具:在线安装工具的安装包比较小,只有4 MB,其他软件 包和代码将在安装过程中下载。在线安装工具的优点是不仅可以在安装过程中按 需下载软件包和代码,并且有更多的版本可选择,还可以安装GitHub最新分支的 代码(如master分支);其缺点是在安装过程中需要保持联网状态,可能会因为 网络问题导致安装失败。 (2)离线安装工具:离线安装工具的安装包较大,有1 GB,包含了环境安 装需要的所有软件包和代码。离线安装工具的主要优点是可以在无法访问互联网 的计算机中使用,且安装的成功率比较高。需要注意的是,离线安装工具只能安 装以v*.* 或v*.*.* 标识的ESP-IDF稳定发布版本。 2.运行安装工具 下载对应版本的安装工具后(这里下载的是ESP-IDF Tools Offline 4.3.2), 双击exe文件即可进入ESP-IDF的安装界面。以下演示了如何使用离线安装工具安 装ESP-IDF的稳定版本v4.3.2。 (1)在如图4-5所示的“选择安装语言”界面的下拉列表中选择使用的语言, 这里选择“简体中文”。 图4-5 “选择安装语言”界面 (2)选择语言后单击“确定”按钮,可弹出“许可协议”界面(见图4-6),仔 细阅读安装许可协议后选择“我同意此协议”,并单击“下一步”按钮。 图4-6 “许可协议”界面 (3)在“安装前系统检查”界面(见图4-7)中检查系统配置项,这里主要检 查Windows的版本信息和已安装的杀毒软件信息,检查完成后单击“下一步”按 钮。如果系统配置项异常,则可以单击“完整日志”按钮,根据关键项检索相关的 解决方案。 小贴士 :将日志提交到https://github.com/espressif/idf-installer/issues可寻求帮助。 图4-7 “安装前系统检查”界面 (4)选择ESP-IDF安装目录,这里选择D:/.espressif,如图4-8所示,并单击 “下一步”按钮。请注意这里的.espressif是一个隐藏目录,在安装完成后,打开文 件管理器的显示隐藏的项目可查看该文件夹内的具体内容。 图4-8 选择ESP-IDF安装目录 (5)勾选需要安装的组件,如图4-9所示,建议使用默认选项,即完全安 装,然后单击“下一步”按钮。 图4-9 勾选需要安装的组件 (6)确定准备安装的组件,单击“安装”按钮即可开始自动化的安装过程, 如图4-10所示。安装过程可能持续数十分钟,安装过程进度条如图4-11所示,请 耐心等待。 图4-10 准备安装 (7)安装完成后,建议勾选“将ESP-IDF工具的可执行文件注册为Windows Defender的排除项……”,以避免杀毒软件误删文件,同时加入排除项可跳过杀毒 软件的频繁扫描,大大提高Windows系统的代码编译效率。单击“完成”按钮即可 完成开发环境的安装,如图4-12所示。读者可选择勾选“运行ESP-IDF PowerShell 环境”“运行ESP-IDF命令提示符”。在安装完后直接运行编译窗口,确保开发环境 能够正常运行。 图4-11 安装过程进度条 图4-12 安装完成 (8)在程序列表中快速打开安装的开发环境(ESP-IDF 4.3 CMD或ESP-IDF 4.3 PowerShell终端任选其一,如图4-13所示),在终端运行时会自动添加ESP- IDF的环境变量,之后就可以使用idf.py命令进行操作了。打开的ESP-IDF 4.3 CMD如图4-14所示。 图4-13 安装的开发环境 图4-14 打开的ESP-IDF 4.3 CMD 4.2.3 在Mac系统下安装ESP-IDF开发环境 在Mac系统下安装ESP-IDF开发环境的流程和Linux系统一致,仓库代码下载 和工具链安装命令也完全相同,只是安装依赖软件包的命令略不相同。 1.安装依赖软件包 pip作为Python包管理工具,将用于后续Python软件包的安装。打开终端,输 入以下命令可安装pip: 安装包管理工具HomeBrew用于安装其他依赖软件,输入下面的命令可安装 HomeBrew: 输入以下命令可安装依赖软件包: 2.下载ESP-IDF仓库代码 该部分请参考4.2.1节,与Linux系统中下载ESP-IDF仓库代码的方法相同。 3.安装ESP-IDF开发工具链 该部分请参考4.2.1节,与Linux系统中安装ESP-IDF开发工具链的方法相同。 4.2.4 VS Code 代码编辑工具的安装 ESP-IDF SDK默认不附带代码编辑工具(最新的Windows版安装工具可选择 安装ESP-IDF Eclipse),读者可使用任何文本编辑工具进行代码的编辑,代码编 辑完成后可在终端控制台使用命令进行代码的编译。 VS Code(Visual Studio Code)是一个免费的代码编辑工具,具有丰富且易 用的插件功能,支持代码跳转和高亮显示,支持Git版本管理和终端集成等。另外 乐鑫科技也为VS Code开发了专用插件Espressif IDF,方便工程配置和调试。 读者可以使用命令code在VS Code中快速打开当前文件夹,也可以使用命令 Ctrl+~ 在VS Code中打开系统默认的终端控制台。 小贴士 本 书 推 荐 使 用 VS Code 进 行 ESP32-C3 代 码 的 开 发 , 读 者 可 以 通 过 链 接 https://code.visualstudio.com/下载并安装最新的VS Code。 4.2.5 第三方开发环境简介 除了支持以C语言为主的官方开发环境ESP-IDF,ESP32-C3还支持其他主流 开发语言和大量第三方开发环境,主要包括: (1)Arduino。是一个开源硬件和开源软件平台,支持包括ESP32-C3在内的 大量微控制器。Arduino基于C++ 语言的API,由于使用简单和标准,在开发者社 区广泛流行,也被称为Arduino语言,被广泛应用在原型开发和教学领域。同时 Arduino还提供一个可扩展软件包的IDE,可以一键完成代码编译和烧录工作。 (2)MicroPython。是可在嵌入式微控制器平台上运行的Python3语言解析 器,通过简单的脚本语言即可直接调用ESP32-C3的外设资源(如UART、SPI、 I2C等)和通信功能(如Wi-Fi、Bluetooth LE),能够大大简化与硬件的交互过 程。结合Python的大量数学运算库,用户可以在ESP32-C3上轻松实现复杂的算 法,加速人工智能相关应用的开发。借助脚本语言的特性,用户不需要重复代码 的编译和烧录过程,只需要修改运行脚本即可。 (3)NodeMCU。是一个针对ESP系列芯片开发的LUA语言解析器,几乎支 持ESP芯片的所有外设功能,相比MicroPython也更加轻量。同样,NodeMCU也 有脚本语言,具有无须重复编译的优点。 除此以外,ESP32-C3还支持NuttX和Zephyr操作系统。NuttX是支持POSIX兼 容接口的实时操作系统,提高了应用软件的可移植性。Zephyr是专为物联网场景 开发的小型实时操作系统,包含了大量的物联网开发过程中需要的软件库,正逐 渐发展为完整的软件生态系统。 本书不再详细描述以上开发环境的安装过程,请读者根据需求选择开发环境 后,按照相应的安装方法完成开发环境的安装。 4.3 ESP-IDF 编译系统详解 4.3.1 编译系统基本概念 ESP-IDF工程是一个包含入口函数的主程序和多个独立功能组件的集合。例 如,一个控制LED开关的项目主要包含一个入口程序main和控制GPIO的driver组 件。如果要实现LED远程控制功能,则还需要额外添加Wi-Fi、TCP/IP协议栈等。 编译系统通过一套构建规则可对代码进行编译、链接,并生成可执行文件 (.bin)。ESP-IDF v4.0及以上版本的编译系统默认以CMake为基础搭建,编译脚 本CMakeLists.txt可用于控制代码的编译行为。ESP-IDF编译系统除了支持CMake 基础语法,还定义了一套默认的编译规则和CMake函数,用户使用简单的语句即 可完成编译脚本的编写。 4.3.2 工程文件结构 工程(Project,也称为项目)是指一个包含入口程序main、用户自定义组 件,以及构建可执行应用程序所需的编译脚本、配置文件、分区表等文件的文件 夹。工程可以被复制和传递,并可在安装了相同版本ESP-IDF开发环境的机器中 编译生成相同的可执行文件。典型的ESP-IDF工程文件结构如图4-15所示。 图4-15 典型的ESP-IDF工程文件结构 由于ESP-IDF具有跨芯片平台的特性,同时支持乐鑫的多款物联网芯片,包 括ESP32、ESP32-S系列、ESP32-C系列、ESP32-H系列等,因此在编译代码之 前,需要确定一个目标。目标既是运行应用程序的硬件设备,也是编译系统的生 成目标。 工程可以指定编译目标,也可同时兼容多种目标,在编译时由用户选择。例 如,可以通过命令idf.py set-target esp32c3将编译目标设置为ESP32-C3,期间将加 载针对ESP32-C3的默认参数和编译工具链路径,经过编译后即可为ESP32-C3生 成可执行程序。用户也可以再次运行命令set-target来设置其他目标,编译系统将 自动清理并重新进行配置。 (1)组件。组件是模块化且独立的代码,在编译系统中以文件夹的形式管 理(文件夹名默认为组件名)。通过组件的编译脚本,可以指定其编译参数和依 赖关系。在编译时组件会被编译成独立的静态库(.a文件),最终在链接阶段共 同组成应用程序。 ESP-IDF的关键功能(如操作系统、外设驱动、网络协议栈等)是以组件的 形式提供的,这些组件保存在ESP-IDF根目录下的components目录中,开发者无 须将这些组件复制到myProject的components目录中,只需要在CMakeLists.txt中使 用REQUIRES或PRIV_REQUIRES指明对它们的依赖关系即可,编译系统会自动 找到该组件并对其进行编译。 因此myProject下components目录并不是必需的,这里仅用于包含项目的部分 自定义组件,自定义组件可以是第三方库或者用户的自定义代码。除此之外,组 件也可以来自非ESP-IDF或非当前工程的任意目录,如来源于在其他目录下保存 的 开 源 项 目 。 这 时 只 需 要 在 根 目 录 的 CMakeLists.txt 中 通 过 设 置 EXTRA_COMPONENT_DIRS变量来添加该组件的查找位置即可。该目录同样会 对ESP-IDF同名组件进行覆盖。 (2)入口程序。main目录和其他组件(如component1)的文件结构是一样 的,它是一个必须存在的特殊组件。一个工程有且仅有一个main目录,该目录包 含了项目本身的源代码和用户程序的入口app_main,用户程序默认从这里开始执 行。main组件的特殊之处还有,它默认依赖于所有搜索路径中的组件,因此不必 在自己的CMakeLists.txt中使用REQUIRES或PRIV_REQUIRES指明依赖关系。 (3)配置文件。工程的根目录下包含了一个名为sdkconfig配置文件,该文 件包含了工程所有组件的配置参数。sdkconfig是由编译系统自动生成的,可通过 命令idf.py menuconfig进行修改并重新生成。menuconfig中的选项主要从工程的 Kconfig.projbuild以及组件的Kconfig导入,组件的开发者一般通过在Kconfig中添 加配置项,使组件具有灵活可配置的特性。 (4)编译目录(build)。使用命令idf.py build编译产生的中间文件和最终的 可执行程序,将默认保存在工程的build目录中。一般情况下,用户不必查看build 目录的内容,ESP-IDF预定义了操作该目录的命令,如使用命令idf.pyflash将自动 找到编译生成的二进制文件,并烧录到指定的Flash地址;使用命令idf.py fullclean 可以对整个build目录进行清理。 (5)分区表(partitions.csv)。每一个工程都会配置相应的分区表,用于划 分Flash的空间,指明可执行程序和用户数据空间的大小、起始地址等。命令 idf.py flash或者OTA升级程序据此将固件烧录到Flash的对应地址。ESP-IDF在 components/partition_table 中 提 供 了 几 套 系 统 默 认 的 分 区 表 , 如 partitions_singleapp.csv和partitions_two_ota.csv等,用户可以在menuconfig中进行 选择。 如果系统默认的分区表不能满足项目的要求,则开发者可以在项目的目录下 添加自定义的分区表partitions.csv,并在menuconfig中选择自定义的分区表。 4.3.3 编译系统默认的构建规范 (1)同名组件覆盖规则。编译系统在搜索组件时,首先搜索ESP-IDF的内部 组件,然后搜索用户的项目组件,最后搜索EXTRA_COMPONENT_DIRS中的组 件。如果这些目录中的两个或者多个目录包含相同名字的组件,最后搜索到的同 名组件将覆盖前面搜索到的同名组件。基于这种规则,可将ESP-IDF组件复制到 用户工程,再进行自定义修改,ESP-IDF代码本身可以保持不变。 (2)默认包含的通用组件。如4.3.2节所述,组件需要在CMakeLists.txt中显 式地指明和其他组件的依赖关系。对于freertos等通用组件,即使在编译脚本中不 显式地指明依赖关系,也会被默认包含在构建系统中。ESP-IDF通用组件包括 freertos、Newlib、heap、log、soc、esp_rom、esp_common、xtensa/riscv、cxx, 使用这些通用组件可避免在编写CMakeLists.txt时重复性工作,使其更加简洁。 (3)配置项覆盖规则。开发者可以通过在工程中添加一个名为 sdkconfig.defaults 的 默 认 配 置 文 件 , 给 工 程 添 加 默 认 配 置 参 数 。 例 如 , 添 加 CONFIG_LOG_DEFAULT_LEVEL_NONE=y可控制UART接口默认不打印Log数 据。除此之外,如果想针对特定目标设置特定参数,可添加名为 sdkconfig.defaults.TARGET_NAME 的 配 置 文 件 , TARGET_NAME 可 以 是 esp32s2、esp32c3等。以上配置文件将在编译期间被导入sdkconfig中,导入的顺 序是先导入通用默认配置文件sdkconfig.defaults,再导入目标的特定配置文件, 如sdkconfig.defaults.esp32c3。如果存在同名的配置项,则后者将对前者进行覆 盖。 4.3.4 编译脚本详解 在基于ESP-IDF进行工程开发时,开发者不仅需要编写源代码,而且需要编 写工程和组件的CMakeLists.txt。CMakeLists.txt是一个文本文件,也称为编译脚 本,其中定义了一系列编译对象、编译配置项和命令,用于指导源代码的编译过 程。ESP-IDF v4.3.2的编译系统是基于CMake搭建的,除了支持原生CMake函数和 命令,还定义了一系列的自定义函数,大大简化了用户编写编译脚本的工作。 ESP-IDF中的编译脚本主要包含工程编译脚本和组件编译脚本。工程的根目 录下包含的CMakeLists.txt称为工程编译脚本,用于指导整个工程的编译过程。最 基础的工程编译脚本仅包含以下三行代码: 其中,cmake_minimum_required(VERSION 3.5)必须放在首行,用于指明 工程需要的最小CMake版本号,新版本的CMake一般向后兼容老版本,当使用新 版本CMake命令时,请同时将版本号调整为最新值,否则命令可能无法被识别。 include($ENV {IDF_PATH}/ tools/cmake/project.cmake)用于导入ESP-IDF编译系统 预定义的编译配置项和命令,4.3.3节所述的编译系统默认的构建规范均包含在其 中。project(myProject)用于创建项目本身,并指定项目名称,该名称会作为最终 输出的二进制文件名称,即myProject.elf和myProject.bin。 同一个工程可能有包含main组件在内的多个组件,每个组件的顶层目录包含 的CMakeLists.txt称为组件编译脚本。组件编译脚本主要用于指定组件的依赖关 系,配置参数与编译的源代码文件、可被包含的头文件等。借助ESP-IDF的自定 义函数idf_component_register,最基础的组件编译脚本仅需要以下的代码。 其中,参数SRCS用于提供该组件中源文件列表,如果有多个文件,则使用 空格分隔;参数INCLUDE_DIRS用于提供该组件公共头文件目录列表,目录将被 添加到需要当前组件的所有其他组件的include搜索路径中;参数REQUIRES用于 标识当前组件的公共组件依赖项,组件必须显式地写明依赖于哪些组件,如 component2依赖于component1。由于main组件默认依赖于所有组件,因此对于 main组件,可省略参数REQUIRES。 除此之外,用户也可以在编译脚本中使用原生的CMake命令。例如,使用命 令set来设置变量,如set(VARIABLE "VALUE")等。 4.3.5 常用命令详解 在ESP-IDF编译代码的过程中,需要使用CMake项目配置工具、Ninja项目构 建工具和esptool烧录工具,每种工具分别在编译、构建、烧录过程中发挥不同作 用,同时也支持不同的操作命令。为了便于用户操作,ESP-IDF添加了一个统一 前端idf.py,通过idf.py可以快速和连续调用上述的命令。 在使用idf.py之前,需要确保: ESP-IDF的环境变量IDF_PATH已经添加到当前终端。 命令执行目录为工程的根目录,即包含工程编译脚本CMakeLists.txt的目 录。 idf.py的常用命令如下: idf.py --help:可显示命令列表和使用说明。 idf.py set-target :设置编译目标,如将 替换为esp32c3。 idf.py menuconfig:运行menuconfig终端图像化配置工具,可以选择或修 改配置选项,配置结果将保存在sdkconfig文件中。 idf.py build:开始编译代码,编译产生的中间文件和最终的可执行程序将 默认保存在项目的build目录。编译过程是增量式的,如果仅对一个源文件进行修 改,在下次编译时将只编译已修改的文件。 idf.pyclean:清理项目编译产生的中间文件,下次编译时会强制编译整个 项目。需要注意,清理时不会删除CMake配置和使用menuconfig修改的配置。 idf.py fullclean:删除整个build目录下的内容,包括所有CMake的配置输 出文件。在下次构建项目时,CMake会从头开始配置项目。请注意,该命令会递 归删除构建目录下的所有文件,请谨慎使用,项目配置文件不会被删除。 idf.py flash:将build生成的可执行程序二进制文件烧录到目标ESP32-C3 中。选项-p 和-b 分别用于设置串口的设备名和烧录时的 波特率,如果不指定这两个选项,将自动搜索串口并使用默认的波特率。 idf.py monitor用于显示目标ESP32-C3的串口输出。选项-p可用于设置主 机端串口的设备名,在串口打印期间,可按下组合键Ctrl+] 退出监视器。 以上命令也可以组合输入,如命令idf.py build flash monitor将依次进行代码编 译、下载、打开串口监视器等操作。 读者可访问https://bookc3.espressif.com/build-system阅读ESP-IDF编译系统章 节。 4.4 实战:Blink 示例程序编译 4.4.1 Blink 示例程序分析 本节将以Blink示例程序为例,详细分析一个实际工程的文件结构和编码规 则 。 Blink 示 例 程 序 实 现 了 LED 指 示 灯 的 闪 烁 效 果 , 该 工 程 保 存 在 目 录 examples/get-started/blink中,包含一个源文件、配置文件和若干个编译脚本。 本书中的实战项目——智能照明工程也将以该示例程序为基础,在后面的章 节中逐步添加功能,最终完成智能照明实战项目。 项目源码 :为了展示整个开发过程,所以将Blink示例程序复制到了目录 book-esp32c3-iot-projects/device_firmware/1_blink中。 blink工程的文件目录结构如图4-16所示。 blink工程仅包含一个main目录,如4.3.2节所述,该目录是一个必须包含的特 殊组件,主要用于存放app_main()函数的实现,该函数是用户程序的入口。blink 工程未包含components目录,原因是当前示例只需要使用ESP-IDF自带的组件即 可,不需要增加额外组件。blink工程包含的CMakeLists.txt用于指导编译过程,而 Kconfig.projbuild用于在menuconfig中添加该示例程序的配置项。其他不必要的文 件不会影响代码的编译,这里不再赘述,对blink工程文件的详细解读如下: 图4-16 blink工程的文件目录结构 源文件blink.c包含了一系列函数声明对应的头文件,ESP-IDF一般遵循先包 含标准库头文件,再包含FreeRTOS头文件、驱动头文件、其他组件头文件、项目 头文件的顺序。头文件的包含顺序有可能影响最终的编译结果,所以请尽量遵循 默认规范。需要注意的是,sdkconfig.h由kconfig自动生成,仅能通过命令idf.py menuconfig进行配置,对该头文件的直接修改将会被覆盖。 app_main()是一个无参数且无返回值的简单函数,该函数作为用户程序的入 口,在系统完成初始化后被调用。系统初始化的操作包括初始化Log串口、配置 单/双核、配置看门狗等必要步骤。app_main()函数的运行上下文是一个名为main 的 任 务 ( Task ) , 用 户 可 以 在 menuconfig→Componentconfig→Common ESP- related中调整该任务的堆栈大小和优先级等。对于令LED闪烁这种简单的任务, 可以直接在app_main()函数中实现所有工作代码,先初始化LED对应的GPIO,再 使用while(1)循环执行开关LED的动作。当然用户也可以在app_main()函数中使用 FreeRTOS的API创建新任务来完成令LED闪烁的任务,新任务创建成功后,可以 退出app_main()函数。main/CMakeLists.txt的内容如下: 其 中 , main/CMakeLists.txt 仅 调 用 一 个 编 译 系 统 函 数 , 即 idf_component_register。与其他大多数组件的CMakeLists.txt编写方法一致,这里 将blink.c添加到SRCS,添加到SRCS的源文件将参与编译。同时还将“.”(代表 CMakeLists.txt所在路径)添加到INCLUDE_DIRS,添加到INCLUDE_DIRS的目 录将作为头文件的搜索目录。CMakeLists.txt的内容如下: 其 中 , 根 目 录 下 的 CMakeLists.txt 主 要 包 含 了 $ENV{IDF_PATH}/tools/cmake/project.cmake,该文件是ESP-IDF提供的CMake主 配置文件,用于配置ESP-IDF编译系统的默认规则,并定义idf_component_register 等常用函数;project(blink)创建了一个名为blink的工程,最终生成的固件将以 blink.bin的形式命名。 4.4.2 Blink 示例程序的编译过程 本节以Blink示例程序为例,一步步地完成一个简单的ESP-IDF示例程序编 译。需要注意的是,本节是通过GPIO的高/低电平来驱动LED的。对于WS2812指 示灯,需要使用特殊通信协议,请参考esp-idf/examples/peripherals/rmt/led_strip中 的示例程序。 1.打开新的终端并导入ESP-IDF环境变量 对于Linux和Mac系统,使用命令cd ~/esp/esp-idf进入ESP-IDF的文件夹,使用 命令../export.sh导入ESP-IDF环境变量,该过程将同时进行开发环境的完整性检 查。 小贴士 请注意../export.sh 中空格前的.不可省略。.与source指令等价,是指在当前Shell 环境中执行脚本,可更改当前Shell中的环境变量。 对于Windows系统,可以直接在程序列表查找并打开ESP-IDF 4.3 CMD或 ESP-IDF 4.3 PowerShell,终端打开后会自动添加环境变量,如图4-17所示。 图4-17 Windows系统自动添加环境变量 2.进入blink工程根目录 开发者进入工程根目录后才能进行编译操作,这里使用命令cd examples/get- started/blink进入blink工程根目录。 3.设置编译目标为ESP32-C3 使用命令idf.py set-target esp32c3将编译目标设置为ESP32-C3,如图4-18所 示。如果该步骤被跳过,则编译目标默认为ESP32。 4.配置GPIO 使用命令idf.py menuconfig进入选项配置界面,按向上/向下按键和Enter按键 进入Example Configuration,输入数字将GPIO改为指定引脚,如图4-19所示,按 照提示进行保存即可。 图4-18 将编译目标设置为ESP32-C3 图4-19 使用menuconfig配置GPIO 5.编译代码 使用命令idf.py build进行代码编译,代码编译过程如图4-20所示,代码编译 完成后将出现如图4-21所示的提示,并打印出烧录命令。 图4-20 代码编译过程 图4-21 代码编译完成后的提示 4.4.3 Blink 示例程序的烧录过程 对于Linux系统,通过USB-UART芯片(如CP2102)将ESP32-C3接入Linux计 算 机 , 使 用 命 令 ls /dev/ttyUSB* 查 看 串 口 号 。 如 果 打 印 的 当 前 串 口 号 为/dev/ttyUSB0,则使用命令idf.py -p /dev/ttyUSB0 flash进行烧录。 对于Mac系统,通过USB-UART芯片(如CP2102)将ESP32-C3接入Mac电 脑 , 使 用 命 令 ls /dev/cu.* 查 看 串 口 号 。 如 果 打 印 当 前 串 口 号 为 /dev/cu.SLAB_USBtoUART , 则 使 用 命 令 idf.py -p /dev/cu.SLAB_USBtoUART flash进行烧录。 对 于 Windows 系 统 , 通 过 USB-UART 芯 片 ( 如 CP2102 ) 将 ESP32-C3 接 入 Windows计算机,通过设备管理器查看串口号。如果当前串口号为COM5,则使 用命令idf.py -p COM5 flash进行烧录。 在烧录完成后,控制台将出现如图4-22所示的提示。当出现以下Log时开始 执行代码,可以观察到开发板上的LED开始闪烁。 图4-22 在烧录完成后控制台出现的提示 4.4.4 Blink 示例程序的串口Log分析 固件编译和下载完成以后,在工程文件夹内执行命令idf.py monitor,将打开 一个带有彩色字体标记的监视器,该监视器可用于输出目标ESP32-C3设备的串口 Log,内容默认分为三部分:一级Bootloader信息、二级Bootloader信息和用户程 序输出。在Log的输出过程中,用户按下组合键Ctrl+] 即可退出Log输出。 (1)一级Bootloader信息:默认从UART输出,v4.3.2版本的ESP-IDF无法通 过配置关闭一级Bootloader信息的输出。一级Bootloader信息不仅包括芯片内部固 化的ROM代码版本信息,同型号芯片后续可能会进行ROM修复和功能扩充,因 此存在不同的版本;也包括芯片重启原因,如rst:0x1表示芯片上电重启,rst:0x3 表示软件触发重启,rst:0x4表示软件异常重启等,用户可以据此判断芯片的工作 状态;还包括了芯片Boot模式的信息,如boot:0xc表示SPI Flash Boot模式(正常 运 行 模 式 , 该 模 式 下 Flash 中 的 代 码 将 被 加 载 并 运 行 ) , boot:0x4 表 示 Flash Download模式(该模式下可对Flash内容进行擦除和烧录)。 (2)二级Bootloader信息:可以在menuconfig中通过将menuconfig(Top) → Bootloader config → Bootloader log verbosity设置为No output来关闭二级Bootloader 信息的输出。二级Bootloader信息主要包括ESP-IDF版本信息、Flash运行模式和速 率信息、系统分区和堆栈分配信息,以及应用程序名称和版本信息等。 (3)用户程序输出:包括所有通过printf()或ESP_LOG()函数输出的信息, 前者是C语言的标准输出函数,后者是ESP-IDF自定义的输出函数。这里推荐使 用 后 者 , 它 可 为 Log 标 记 等

Use Quizgecko on...
Browser
Browser