3.自定义工程目录配置CMakeLists

问题背景

        熟悉stm32keil开发的都知道,我们在编写不同的外设时,通常都会单独编写一个app文件夹或者是user文件夹之类的来存放不同外设功能的源文件和头文件。

        在前面一节2.构建第一个工程并烧录到ESP32开发板-CSDN博客中,我们是使用了一个乐鑫的官方所提供的一个hello world工程模板,这个工程里面我们表面上是用到了GPIO功能和USART功能,其他的一些功能我们暂时还没有用到,或者说暂时还没有包含其他功能模块。

        那么如果我一开始使用了模板是generic_gpio这个模板工程,在项目设计的前期实现我只需要gpio功能就够了,所以我就直接使用的是generic_gpio模板,后来我有需要使用到定时器功能,可能generic_gpio模板里面并没有包含这个功能,我们难道再去打开一个timer外设的模板工程吗,显然是比较麻烦的。

        虽然第二节我提到了我们一般会使用官方模板而不是自己新建一个空工程,但是那只是初期新建工程的时候是用官方模板,当我们新建工程完毕以后,我们需要对官方提供的模板进行修改,添加自己的文件目录以存放之后所使用的其他外设文件。因为官方的外设模板工程里面只有main文件夹下一个主函数的文件,我们总不可能把所有的外设实现函数统统写到这个主函数文件里面。

解决方案

        事实上官方已经提前想到了这个问题,乐鑫官方对 components 路径的介绍:“可选的 “components” 目录中包含了项目的部分自定义组件,并不是每个项目都需要这种自定义组件,但它有助于构建可复用的代码或者导入第三方(不属于 ESP-IDF)的组件。或者,您也可以在顶层 CMakeLists.txt 中设置 EXTRA_COMPONENT_DIRS 变量以查找其他指定位置处的组件。有关详细信息,请参阅 重命名 main 组件。如果项目中源文件较多,建议将其归于组件中,而不是全部放在 “main” 中。

        我们从官方的说明中可以获得两个方法来构建自己的工程文件

  • 1 在顶层目录下的 components 路径下添加组件。
  • 2 在顶层目录下的 CMakeLists.txt 中设置 EXTRA_COMPONENT_DIRS 变量以查找其他指定位置处的组件。

两种方法的实现原理:

我们观察顶层CMakeLists文件可以发现里面已有三行语句,其中第二行语句为include($ENV{IDF_PATH}/tools/cmake/project.cmake)

而配置项目、检索组件等任务都是 $ENV{IDF_PATH}/tools/cmake/project.cmake 决定的。

组件默认的搜索目录为 IDF_PATH/components、 PROJECT_DIR/components、和 EXTRA_COMPONENT_DIRS。

  • ESP-IDF内部组件 IDF_PATH/components
  • 扩展组件 EXTRA_COMPONENT_DIRS
  • 项目组件 PROJECT_DIR/components

IDF_PATH/components 用于系统组件。我们一般不会将文件放在这里面。

PROJECT_DIR/components、和 EXTRA_COMPONENT_DIRS 对应上面两种添加组件的方法。

在 PROJECT_DIR/components 中添加组件

步骤:

  1. 首先新建 PROJECT_DIR/components 路径。
  2. 在PROJECT_DIR/components 中添加我们自定义的组件,比如我添加了 led_key
  3. 将组件相关的头文件和源文件放到 led_key中,并新建 CMakeLists.txt 文件。
  4. 在 CMakeLists.txt 中添加源文件与头文件的路径。格式为:
idf_component_register(SRCS "led_key.c"INCLUDE_DIRS "."REQUIRES driver)

        相信前两个SRC和INCLUDE_DIRS都很好理解,分别是包含源文件和头文件的路径,那么后一个QEQUIRES到底是干什么的,为啥要后面跟上driver?

        这里我先解释第一个问题,QEQUIRES可以理解为添加依赖。在说第二个问题之前我们先来看看现在的文件目录是个什么情况:

然后看下源文件和头文件里面的内容:

led_key.c

#include "led_key.h"void LED_Init(void)
{gpio_config_t io_config;io_config.intr_type = GPIO_INTR_DISABLE;io_config.mode = GPIO_MODE_OUTPUT;io_config.pin_bit_mask = 1<<2;io_config.pull_down_en = GPIO_PULLDOWN_DISABLE;io_config.pull_up_en = GPIO_PULLUP_DISABLE;gpio_config(&io_config);//	esp_rom_gpio_pad_select_gpio (GPIO_NUM_2);//	gpio_set_direction(GPIO_NUM_2,GPIO_MODE_OUTPUT);
}void KEY_Init(void)
{gpio_config_t io_config;io_config.intr_type = GPIO_INTR_POSEDGE;io_config.mode = GPIO_MODE_INPUT;io_config.pin_bit_mask = 1<<0;io_config.pull_down_en = GPIO_PULLDOWN_DISABLE;io_config.pull_up_en = GPIO_PULLUP_DISABLE;gpio_config(&io_config);
}void led_blink( void * pvParameters )
{while(1){gpio_set_level(GPIO_NUM_2,0);vTaskDelay(1000 / portTICK_PERIOD_MS);//FreeRTOS延时函数--毫秒级gpio_set_level(GPIO_NUM_2,1);vTaskDelay(1000 / portTICK_PERIOD_MS);}
}void gpio_isr_handler(void* arg)
{static int flag = 0;flag ^= 1;gpio_set_level(GPIO_NUM_2,flag);
}

led_key.h

#ifndef __LED_KEY__
#define __LED_KEY__#include "driver/gpio.h"#define ESP_INTR_FLAG_DEFAULT 0void LED_Init(void);
void KEY_Init(void);
void led_blink( void * pvParameters );
void gpio_isr_handler(void* arg);#endif

        看完文件结构和文件内容之后,我们大体可以明白为什么要添加一个driver依赖了,因为我们在led_key.h里面包含了driver/gpio.h,而如果我们不去进行依赖的包含,在编译的时候就会报出这样的错误:

fatal error: driver/gpio.h: No such file or directory

这就是由于依赖问题没有解决导致,我们编写的led_key.h文件没有指定依赖,那么编译器将不知道去哪里找这个driver/gpio.h文件。

在自定义的 EXTRA_COMPONENT_DIRS 中添加组件

        有时候我们不想用官方所提供的存放组件集的组件目录components,我们仍然希望创建单独的组件目录,这时候就需要在最顶层CMakeLists文件里面添加一语句用于设置外部组件的路径

# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(EXTRA_COMPONENT_DIRS "./src")
project(myProject)

        比方说我们创建了一个叫做src的外部组件,就需要在最顶层CMakeLists文件添加set(EXTRA_COMPONENT_DIRS "./src"),

        创建自己存放组件集的组件目录,之后在组件目录下创建组件,不能直接创建组件目录,什么意思呢,就是我们要创建一个led的程序,需要在src下面再创建一个led的文件夹作为组件目录,再在led组件目录里面新建led.c源文件。src是一个组件集的目录。

        接下来的操作就和在PROJECT_DIR/components 中添加组件的操作一样了。其实这样做无非是吧官方提供的组件集文件名字替换为了自己起的组件集名字,然后由于顶层CMakeLists默认包含components组件集所以不需要我们添加,而我们自己创建的非components组件集属于外部组件,那么就需要在顶层说明一下外部组件集的路径了。

        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/276824.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【联邦学习贡献评估-参与方贡献评估方案的介绍】

在明确如何度量参与方组合数据价值的基础上, 本篇介绍如何进一步度量参与方在联邦合作中的贡献, 具体介绍如下 4 种参与方贡献评估方案. 个体法 将参与方自身数据的价值度量或者相关变体作为该参与方的贡献. 个体法可以基于任何 数据价值度量指标进行, 特别地, 有个体信誉、个…

Python面试笔记

Python面试笔记 PythonQ. Python中可变数据类型与不可变数据类型&#xff0c;浅拷贝与深拷贝详解Q. 解释什么是lambda函数&#xff1f;它有什么好处&#xff1f;Q. 什么是装饰器&#xff1f;Q. 什么是Python的垃圾回收机制&#xff1f;Q. Python内置函数dir的用法&#xff1f;Q…

SpringBoot整合Activiti7——实战之请假流程(普通)

文章目录 代码实现xml文件部署流程启动流程查询任务填写请假单部门审批 请假流程&#xff1a;开始-填写请假单-部门审批-结束 代码实现 xml文件 <?xml version"1.0" encoding"UTF-8"?> <definitions xmlns"http://www.omg.org/spec/BPMN/…

服务器段的连接端口和监听端口编程实现

new ServerSocket(int)是开启监听端口&#xff0c;并不是连接端口。真正的连接端口是随机开辟的空闲端口&#xff0c;当连接创建完成后&#xff0c;监听关口可以继续等待下一次连接请求&#xff0c;处于空闲等待状态。 编程实现方式 1 、主线程一直处于阻塞等待状态&#xff0c…

编程高级陷阱-破坏原有生态

今天聊点有意思的&#xff0c;昨天写了一个链表翻转&#xff0c;说一说里面大家会遇到的坑&#xff0c;具体可以看 教你三指针拿捏链表翻转-CSDN博客 有这样一个场景&#xff0c;给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回…

汇总全网免费API,持续更新(新闻api、每日一言api、音乐。。。)

Public&FreeAPI 网址&#xff1a;apis.whyta.cn &#xff08;推荐&#xff09; UomgAPI 网址&#xff1a;https://api.uomg.com 教书先生 网址&#xff1a;https://api.oioweb.cn/ 山海API https://api.shserve.cn/ 云析API铺 https://api.a20safe.com/ 韩小韩…

提交数据加快百度搜索引擎收录

百度站长工具做了更新&#xff0c;百度收录的地址分享如下&#xff0c;新站点提交后&#xff0c;可以加快百度收录。 普通收录_加快网站内容抓取&#xff0c;快速提交数据工具_站长工具_网站支持_百度搜索资源平台普通收录工具可实时向百度推送数据&#xff0c;创建并提交site…

【Git】Github 上commit后,绿格子contribution却不显示?不知道怎么弥补?解决方法在这里

github 上commit后&#xff0c;绿格子&#xff08;contribution&#xff09;却不显示 问题描述 今天一直在github上面commit代码&#xff0c;但是github中并没有显示自己的contribution&#xff08;没有绿色的格子&#xff09;&#xff0c;全是空白&#xff0c;网上一查是因为…

tcp/ip协议2实现的插图,数据结构8 (30 - 32章)

(201) 201 三十0 中断优先级补充 (202) 202 三十1 TCP的用户需求 函tcp_usrreq一 (203) 203 三十2 TCP的用户需求 函tcp_usrreq二 (204) 204 三十3 TCP的用户需求 函tcp_usrreq三 (205) 205 三十4 TCP的用户需求 函tcp_usrreq四 (206) 206 三十5 TCP的用户需求 函tcp_usrreq五 …

Python爬虫:原理与实战

引言 在当今的信息时代&#xff0c;互联网上的数据如同浩瀚的海洋&#xff0c;充满了无尽的宝藏。Python爬虫作为一种高效的数据抓取工具&#xff0c;能够帮助我们轻松地获取这些数据&#xff0c;并进行后续的分析和处理。本文将深入探讨Python爬虫的原理&#xff0c;并结合实战…

AHU 汇编 实验二

一、实验名称&#xff1a;实验二 不同寻址方式的灵活运用 二、实验内容&#xff1a;定义数组a[6]&#xff0c;用多种寻址方式访问对应元素&#xff0c;实现&#xff08;a[0]a[1]&#xff09;*(a[2]-a[3])/a[4],将结果保存在内存a[5]中&#xff0c;用debug查询结果。 实验过程&a…

19 OpenCV 霍夫曼变换检测圆

文章目录 cv::HoughCircles算子参数示例 cv::HoughCircles 因为霍夫圆检测对噪声比较敏感&#xff0c;所以首先要对图像做中值滤波。 基于效率考虑&#xff0c;Opencv中实现的霍夫变换圆检测是基于图像梯度的实现&#xff0c;分为两步&#xff1a; 检测边缘&#xff0c;发现可能…

空气源热泵、地源热泵和水源热泵三种热泵的优缺点和选型比较

空气源热泵 空气源热泵是由电动机驱动的,利用空气中的热量作为低温热源,经过空调冷凝器或蒸发器进行热交换,然后通过循环系统,提取或释放热能,利用机组循环系统将能量转移到建筑物内用户需求。 1、适用范围广:适用温度范围在-7至40℃,并且一年四季全天候使用,不受阴、…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:PluginComponent)

提供外部应用组件嵌入式显示功能&#xff0c;即外部应用提供的UI可在本应用内显示。 说明&#xff1a; 该组件从API Version 9开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。本组件为系统接口。 子组件 无 接口 PluginComponent(value:…

【调参】如何为神经网络选择最合适的学习率lr-LRFinder-for-Keras

【调参】如何为神经网络选择最合适的学习率lr-LRFinder-for-Keras_学习率选择-CSDN博客文章浏览阅读9.2k次&#xff0c;点赞6次&#xff0c;收藏55次。keras 版本的LRFinder&#xff0c;借鉴 fast.ai Deep Learning course。前言学习率lr在神经网络中是最难调的全局参数&#x…

Soft Robotics 变结构手掌和变刚度手指的仿人软体手的人机交互操作-武科大ESIR课题组师兄成果

一、引言 在当今的机器人技术领域&#xff0c;人类对机器人的需求日益增长&#xff0c;涉及到工业生产、医疗护理、服务业等各个领域。然而&#xff0c;由于任务的多样性和复杂性&#xff0c;单独依靠自主机器人操作往往难以满足实际需求。为了解决这一问题&#xff0c;人机协作…

详细分析Java中Stream流和for循环的差异之处

目录 前言1. 基本知识2. Demo 前言 事情起因是遍历大数据的时候&#xff0c;数据卡顿很严重 对于Java的基本知识推荐阅读&#xff1a;java框架 零基础从入门到精通的学习路线 附开源项目面经等&#xff08;超全&#xff09; 1. 基本知识 在Java中&#xff0c;Stream API提供…

perl 用 XML::LibXML DOM 解析 Freeplane.mm文件,生成测试用例.csv文件

Freeplane 是一款基于 Java 的开源软件&#xff0c;继承 Freemind 的思维导图工具软件&#xff0c;它扩展了知识管理功能&#xff0c;在 Freemind 上增加了一些额外的功能&#xff0c;比如数学公式、节点属性面板等。 在云计算中&#xff0c;解析XML元素和属性是一种常见的操作…

基础:TCP是什么?

1. TCP 是什么&#xff1f; TCP&#xff08;Transmission Control Protocol 传输控制协议&#xff09; 是一种面向连接的、可靠的、基于字节流的传输层通信协议&#xff0c;由IETF的RFC 793 [1]定义。 TCP旨在适应支持多网络应用的分层协议层次结构。连接到不同但互连的计算机…

第十四届校模拟赛第一期(一)

“须知少时凌云志&#xff0c;自许人间第一流” 鄙人11月八号有幸参加学校校选拔赛&#xff0c;题型为5道填空题&#xff0c;5道编程题&#xff0c;总时间为4小时。奈何能力有限&#xff0c;只完成了5道填空和3道编程大题&#xff0c;现进行自省自纠&#xff0c;分享学习&#…