我正在做一个需要为几个 esp32 开发固件的项目。所有微控制器共享一个处理 wifi 和 mqtt 的公共代码,但是它们都有不同的行为,这是在特定组件中定义的。我的项目结构是这样的:
- CMakeLists.txt
- Makefile
- sdkconfig
- main
- CMakeLists.txt
- main.c
- components
- wifi_fsm
- wifi_fsm.h
- wifi_fsm.c
- CMakeLists.txt
- mqtt_fsm
- mqtt_fsm.h
- mqtt_fsm.c
- CMakeLists.txt
- entity_1
- entity_1.h
- entity_1.c
- CMakeLists.txt
- entity2
- entity2.h
- entity2.c
- CMakeLists.txt
...
每个实体都定义了一些具有标准名称的函数,这些函数实现了实体本身的特定逻辑,并在共享代码(main、wifi_fsm、mqtt_fsm)中调用。
void init_entity(); // called in main.c
void http_get(char *buf); // called in wifi_fsm
void http_put(char *buf);
void mqtt_msg_read(char *buf); // called in mqtt_fsm
void mqtt_msg_write(char *buf);
我的想法是有一个条件语句来随意包含特定行为,以便根据包含的实体,编译器将对上述函数的调用链接到特定包含库中的函数。因此,在开始时,main.c
我只是添加了以下几行,目的是必须更改唯一定义的预处理器符号以针对不同的实体行为进行编译。
#define ENTITY_1
#ifdef ENTITY_1
#include "entity_1.h"
#elif defined ENTITY_2
#include "entity_2.h"
#elif ...
#endif
#include "wifi_fsm.h"
#include "mqtt_fsm.h"
void app_main(void)
{
while(1){
...
}
}
一方面,编译器显然工作正常,可以成功编译而没有错误或警告,这意味着包含链可以正确工作,否则会引发标准函数的重复名称错误。另一方面,它总是按字母顺序链接到第一个实体,例如执行组件 entity_1 的 init_entity() 中包含的代码。如果我重命名 entity_1 中的标准函数,那么它会链接到 entity_2。
如果上述方法错误,我可能会使用指向标准调用的指针链接到每个实体中的特定函数,但我想首先了解我的方法有什么问题。
响应 Bodo 的请求进行编辑(CMakeFile.txt 的内容)
项目:
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(proj)
主要的:
set(COMPONENT_REQUIRES )
set(COMPONENT_PRIV_REQUIRES )
set(COMPONENT_SRCS "main.c")
set(COMPONENT_ADD_INCLUDEDIRS "")
register_component()
零件:
set(COMPONENT_SRCDIRS "src")
set(COMPONENT_ADD_INCLUDEDIRS "include")
set(COMPONENT_REQUIRES log freertos driver nvs_flash esp_http_server mqtt)
register_component()