ETLCPP/etl
GitHub: ETLCPP/etl
专为嵌入式系统设计的 C++ 模板库,提供无动态内存分配的固定容量容器和丰富的嵌入式开发工具。
Stars: 2897 | Forks: 504
#  Embedded Template Library (ETL)

[](https://img.shields.io/github/release-date/jwellbelove/etl?color=%231182c3)
[](https://en.wikipedia.org/wiki/C%2B%2B#Standardization)
[](https://opensource.org/licenses/MIT)
















[](https://www.codacy.com/manual/jwellbelove/etl?utm_source=github.com&utm_medium=referral&utm_content=ETLCPP/etl&utm_campaign=Badge_Grade)
[](https://www.etlcpp.com/sponsor.html)
[项目文档](https://www.etlcpp.com/)
## 动机
C++ 是一种强大的嵌入式系统开发语言,其模板提供了极大的灵活性和类型安全性。虽然 C++ 标准库提供了丰富且经过充分测试的功能,但它通常不太适合具有严格确定性行为和资源受限的环境。
在许多嵌入式应用中,动态内存分配是不被鼓励甚至完全禁止的,这使得标准的 STL 容器和许多其他组件变得不切实际或无法使用。
我们需要的是一个专为嵌入式系统设计的模板库——允许开发人员在编译时定义容器的固定大小或最大尺寸。此外,由于许多嵌入式工具链仍然缺乏对 C++03 之后标准的完整支持,因此能够使用一个回移植了 C++ 标准库后续版本精选功能的库是非常有价值的。
## 关于 ETL
Embedded Template Library (ETL) 并不打算完全取代 C++ Standard Template Library (STL),而是作为专门针对嵌入式系统的补充解决方案。
其设计目标包括:
- 提供一组在编译时定义固定或最大尺寸的容器。
- 提供与 STL 非常相似的 API,以实现熟悉且一致的使用方式。
- 保持与 C++98 的兼容性,同时在可能的情况下实现后续标准 (C++11/14/17/20/23) 中引入的许多功能。
- 确保确定性行为,这在实时和资源受限的环境中至关重要。
- 引入 STL 中缺少但在嵌入式环境中有用的额外组件和实用工具。
ETL 完全避免动态内存分配;从不使用堆。所有非侵入式容器都具有固定容量,允许在编译时完全确定内存需求。这使得 ETL 非常适合对可预测性、性能和内存控制至关重要的低资源嵌入式应用。
该库与任何支持 C++03 或更高版本的编译器兼容。
关于如何将 ETL 集成到您的项目中的帮助可以在这里找到。
## ETL 的主要特性
- 积极维护:自 2014 年起在 GitHub 上开发和维护。
- 开源:MIT 许可。
- 无 STL 依赖:设计为独立于 C++ Standard Template Library 运行。
- 无动态内存分配:所有存储都在编译时或栈上分配;完全避免使用堆。
- RTTI 和虚函数:不需要运行时类型信息 (RTTI)。仅在严格必要时才少量使用虚函数。
- 仅头文件库:所有功能都通过头文件提供;不需要单独编译。
- 固定容量容器:提供具有固定或最大容量的 STL 风格容器,以及额外的非标准容器类型。
- 缓存效率:容器使用连续内存布局以获得最佳缓存性能。
- 紧凑的代码库:共享基类(基于类型)有助于减少整体容器代码大小。
- 编译时功能:
- 模板化编译时常量
- 基于模板的设计模式基类(例如,Visitor、Observer)
- 类型安全的智能枚举
- 类型安全的 typedef 和常量
- 嵌入式系统框架:
- 消息路由
- 有限状态机
- 任务调度
- C++11 回移植:实现了许多 C++11 功能(类型特征、算法、容器)以便在 C++03 环境中使用。
- 实用工具:
- CRC 计算(8、16、32 和 64 位)
- 校验和与哈希函数
- 变体类型(类型安全的联合体)
- 广泛的模板支持实用工具
- 健壮的错误处理:可配置的错误检查,使用断言、异常、错误处理程序或不检查;由用户选择。
- 充分测试:
- 超过 10,000 个单元测试
- 使用 Visual Studio 2022、GCC 12 和 Clang 14 进行测试
- 通过 GitHub Actions 进行持续集成。
- 可读性强且文档完善:清晰、可维护的源代码和文档。
- 支持:提供免费电子邮件支持。Slack 群组可用。付费支持按需提供。
- 归档:ETL 的快照保存在 Arctic Code Vault 中,用于长期数字保存。
任何帮助移植库以在不同平台和编译器下工作的帮助将不胜感激。
我特别感兴趣的是那些使用 Keil、IAR、Green Hills、TI Code Composer 等工具,以及裸机或 RTOS 和 DSP 的用户。
请参阅 (https://www.etlcpp.com) 获取最新信息。
## 安装此库
您可以在[这里](https://www.etlcpp.com/setup.html)找到安装步骤。
### CMake
使用此库的一种方法是将其放入您的项目目录中,
然后使用 `add_subdirectory` 使库可用
```
add_subdirectory(etl)
add_executable(foo main.cpp)
target_link_libraries(foo PRIVATE etl::etl)
```
如果 ETL 库被用作 Git submodule,则可能需要额外的配置才能正确解析 ETL 版本,方法是允许在库根目录之外查找 Git 文件夹。
```
set(GIT_DIR_LOOKUP_POLICY ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR)
add_subdirectory(etl)
```
如果您想使用 CMake 安装此库,可以执行以下步骤。在 Linux 上,
安装库可能需要超级用户权限,因此可能需要在最后一条命令前添加 `sudo`:
```
git clone https://github.com/ETLCPP/etl.git
cd etl
git checkout
cmake -B build .
cmake --install build/
```
安装库后,您可以使用 [find_package](https://cmake.org/cmake/help/latest/command/find_package.html) 来使用该库。
将 `` 替换为您所需的主版本号:
```
find_package(etl )
add_executable(foo main.cpp)
target_link_libraries(foo PRIVATE etl::etl)
```
或者,您可以使用 [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html),
将 `` 替换为基于 git 标签安装的版本:
```
Include(FetchContent)
FetchContent_Declare(
etl
GIT_REPOSITORY https://github.com/ETLCPP/etl
GIT_TAG
)
FetchContent_MakeAvailable(etl)
add_executable(foo main.cpp)
target_link_libraries(foo PRIVATE etl::etl)
```
## 配置文件定义
在项目中使用 ETL 时,通常会定义一个 `etl_profile.h` 来
根据项目需求调整 ETL。如果 `etl_profile.h` 在包含路径中可用,
ETL 将自动找到它。如果不可用,ETL 将使用默认值工作。
### 示例
```
#ifndef __ETL_PROFILE_H__
#define __ETL_PROFILE_H__
#define ETL_TARGET_DEVICE_GENERIC
#define ETL_TARGET_OS_NONE
#define ETL_NO_STL
#endif
```
## 平台特定实现
虽然 ETL 通常是一个自包含的仅头文件库,但由于项目的特殊性,
某些接口需要在每个项目或平台中实现,或者至少在实际使用这些接口时实现:
| ETL 头文件 | 需要实现的平台特定 API | 使用时需要 |
|------------|--------------------------------|-------------------------------------|
| `chrono.h` | `etl_get_high_resolution_clock()` | `etl::high_resolution_clock::now()` |
| | `etl_get_system_clock()` | `etl::system_clock::now()` |
| | `etl_get_steady_clock()` | `etl::steady_clock::now()` |
| `print.h` | `etl_putchar()` | `etl::print()` |
| | | `etl::println()` |
### 示例
```
#include
#include
extern "C"
{
etl::chrono::high_resolution_clock::rep etl_get_high_resolution_clock()
{
return etl::chrono::high_resolution_clock::rep(static_cast(getSystemTimeNs()));
}
etl::chrono::system_clock::rep etl_get_system_clock()
{
return etl::chrono::system_clock::rep(static_cast(getSystemTimeNs()));
}
etl::chrono::system_clock::rep etl_get_steady_clock()
{
return etl::chrono::system_clock::rep(static_cast(getSystemTimeNs()));
}
void etl_putchar(int c)
{
putByteToStdout(static_cast(c));
}
}
```
如果未定义相应的宏(例如在 `etl_profile.h` 中),
则应用以下默认值:
| 宏 | 默认值 |
|-----------------------------------------------|----------------------------|
| `ETL_CHRONO_SYSTEM_CLOCK_DURATION` | `etl::chrono::nanoseconds` |
| `ETL_CHRONO_SYSTEM_CLOCK_IS_STEADY` | `true` |
| `ETL_CHRONO_HIGH_RESOLUTION_CLOCK_DURATION` | `etl::chrono::nanoseconds` |
| `ETL_CHRONO_HIGH_RESOLUTION_CLOCK_IS_STEADY` | `true` |
| `ETL_CHRONO_STEADY_CLOCK_DURATION` | `etl::chrono::nanoseconds` |
## Arduino 库
此仓库的内容可作为 Arduino IDE 中的库使用(在 IDE 库管理器中搜索 "Embedded Template Library")。Arduino 库仓库位于 ```https://github.com/ETLCPP/etl-arduino```,请参阅那里了解更多详情。
标签:AVR, Bash脚本, C++, C++标准库, ESP32, ETL, IoT, JavaCC, MIT许可, STL替代, 内存安全, 固件开发, 头文件库, 实时系统, 容器, 嵌入式开发, 嵌入式系统, 嵌入式软件, 微控制器, 数据擦除, 数据结构, 无动态内存分配, 模板库, 算法, 资源受限环境, 零开销抽象