Skip to content

Commit d3d0be4

Browse files
committed
Update middleware.
1 parent a1386a0 commit d3d0be4

File tree

18 files changed

+1710
-9
lines changed

18 files changed

+1710
-9
lines changed

docs/basic_coding/core/core-assert.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,14 @@ static void SizeLimitCheck(size_t limit, size_t size);
5555
## 用例示例
5656
5757
```cpp
58-
LibXR::Assert::RegisterFatalErrorCB(
59-
LibXR::Callback<const char*, uint32_t>::Create([](bool in_isr, const char* file, uint32_t line) {
60-
printf("Fatal error at %s:%u (ISR=%d)\n", file, line, in_isr);
61-
}, nullptr));
58+
auto err_cb = LibXR::Assert::Callback::Create(
59+
[](bool in_isr, Arg arg, const char *file, uint32_t line)
60+
{
61+
// do something
62+
},
63+
arg);
64+
65+
LibXR::Assert::RegisterFatalErrorCB(err_cb);
6266
6367
ASSERT(buffer != nullptr);
6468
ASSERT_ISR(interrupt_flag == true);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
id: middleware-coding
3+
title: 中间件
4+
sidebar_position: 3
5+
---
6+
7+
# 中间件
8+
9+
本模块汇总了 LibXR 中用于系统服务、通信管理、终端交互等场景的中间件组件,设计强调线程安全、资源约束适配与平台无关性,涵盖如下内容:
10+
11+
## 模块特性
12+
13+
- **统一封装**:提供事件、日志、主题发布、虚拟终端等核心中间件功能。
14+
- **多种调用模型**:支持同步、异步、队列、回调等操作方式,适配不同场景。
15+
- **高性能实现**:内部大量使用无锁链表/队列等数据结构,保障并发性能。
16+
- **适配嵌入式限制**:支持 Flash 最小写入单元限制、内存受限设备上的键值存储等。
17+
18+
## 快速导航
19+
20+
- [Application 框架](./app-framework.md)
21+
- [Logger 日志系统](./logger.md)
22+
- [Event 事件系统](./event.md)
23+
- [Topic 发布订阅机制](./message.md)
24+
- [Database 键值数据库](./database.md)
25+
- [RamFS 内存文件系统](./ramfs.md)
26+
- [Terminal 命令终端](./terminal.md)
27+
28+
更多接口说明与设计思想,请参考各页面的详细说明。
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
id: app-framework
3+
title: Application 框架
4+
sidebar_position: 1
5+
---
6+
7+
# Application 框架
8+
9+
`Application` 框架是 LibXR 中的核心中间件之一,负责管理设备注册与应用模块调度,是 XRobot 系统集成与运行控制的基础。
10+
11+
## 模块组成
12+
13+
- **HardwareContainer**:硬件容器类,支持设备对象的注册、查找、别名管理。
14+
- **Application**:应用模块抽象基类,需实现 `OnMonitor()` 方法。
15+
- **ApplicationManager**:模块调度器,用于统一管理多个 Application 实例并执行周期性任务。
16+
17+
---
18+
19+
## HardwareContainer:硬件设备注册与查找
20+
21+
```cpp
22+
template <typename T>
23+
struct Entry {
24+
T& object;
25+
std::initializer_list<const char*> aliases;
26+
};
27+
28+
HardwareContainer container({
29+
Entry<UART>{uart1, {"uart1", "console"}},
30+
Entry<Motor>{gpio1, {"gpio1", "LED"}}
31+
});
32+
```
33+
34+
支持:
35+
36+
- 多别名注册:同一个对象可注册多个别名。
37+
- 类型安全查找:支持模板化查找 `Find<T>("alias")`。
38+
- 查找失败断言:`FindOrExit<T>({...})` 可在未找到时报错退出。
39+
40+
---
41+
42+
## Application / ApplicationManager:统一应用模块管理
43+
44+
```cpp
45+
class MyApp : public Application {
46+
public:
47+
void OnMonitor() override {
48+
// 用户定义的周期任务逻辑
49+
}
50+
};
51+
52+
MyApp app;
53+
manager.Register(app);
54+
manager.MonitorAll(); // 周期调用所有模块的 OnMonitor()
55+
```
56+
57+
支持:
58+
59+
- 注册任意数量的模块;
60+
- 使用 `LockFreeList` 无锁结构存储模块;
61+
- 可用于实现定时任务调度、模块状态轮询等。
62+
63+
---
64+
65+
## 与 XRobot 的集成意义
66+
67+
XRobot 系统的自动生成工具会为每个模块自动生成注册代码,统一调用 `HardwareContainer``ApplicationManager`,完成设备注册与主循环调度的构建。
68+
69+
这使得所有模块可插拔化接入,支持快速扩展与平台无关运行。
70+
71+
---
72+
73+
更多示例与使用方式,请参考 `xrobot_main.cpp` 或模板生成代码。
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
---
2+
id: database
3+
title: 闪存数据库
4+
sidebar_position: 5
5+
---
6+
7+
# Database 闪存数据库
8+
9+
LibXR 提供了两种轻量级的嵌入式键值数据库实现:`DatabaseRawSequential``DatabaseRaw<N>`
10+
它们均继承自抽象接口类 `Database`,用于嵌入式 Flash 等顺序写入存储介质,具备主备冗余、断电保护、类型安全封装,适配不同的存储对齐约束。
11+
12+
---
13+
14+
## 主要功能
15+
16+
- 支持主/备块数据冗余与校验,断电后可自动恢复;
17+
- 提供统一接口 `Database` 与模板封装 `Database::Key<T>`,支持类型安全读写;
18+
- 两种实现模式:
19+
- `DatabaseRawSequential`:顺序写入,支持任意数据长度;
20+
- `DatabaseRaw<N>`:页对齐写入,适用于 NOR Flash 等要求写入对齐的场景;
21+
- 所有数据操作通过 `Save()` 写入,`Restore()` 清空,支持完整恢复流程。
22+
23+
---
24+
25+
## 使用示例
26+
27+
### 创建数据库对象
28+
29+
```cpp
30+
LinuxBinaryFileFlash<2048> flash("/tmp/flash.bin", 512, 8);
31+
Database& db = *(new DatabaseRawSequential(flash));
32+
```
33+
34+
或使用页对齐版本:
35+
36+
```cpp
37+
LinuxBinaryFileFlash<2048> flash2("/tmp/flash2.bin", 512, 16);
38+
Database& db = *(new DatabaseRaw<16>(flash2));
39+
```
40+
41+
### 定义类型安全的键
42+
43+
```cpp
44+
int value = 42;
45+
Database::Key<int> key(db, "my_key", value);
46+
47+
// 写入新值
48+
key = 123;
49+
50+
// 读取回变量
51+
key.Load();
52+
printf("value = %d\n", static_cast<int>(key));
53+
```
54+
55+
---
56+
57+
## 类型安全封装:Key
58+
59+
模板类 `Database::Key<T>` 提供类型安全的键值封装,构造时会尝试从数据库中加载键值,若不存在则添加新键。
60+
61+
```cpp
62+
struct Config { uint32_t baudrate; uint8_t mode; };
63+
Database::Key<Config> cfg(db, "uart_cfg", {9600, 1});
64+
65+
// 写入配置
66+
cfg = {115200, 0};
67+
68+
// 加载配置
69+
cfg.Load();
70+
```
71+
72+
- 支持所有 **可平铺内存的 POD 类型**(如结构体、数组、基本类型);
73+
- 赋值操作 `key = value` 会自动更新数据库;
74+
- 可通过 `key.Load()` 显式从数据库刷新内容。
75+
76+
---
77+
78+
## 方法一览(基类接口)
79+
80+
以下为抽象接口 `Database` 及其模板类 `Key<T>` 提供的完整方法:
81+
82+
| 方法/操作 | 功能描述 |
83+
|----------------------------------|----------------------------------------------------------------|
84+
| `Database::Add(KeyBase&)` | 添加键值(仅在数据库不存在该键时调用) |
85+
| `Database::Set(KeyBase&, RawData)` | 更新键值内容,要求名称和大小一致 |
86+
| `Database::Get(KeyBase&)` | 从数据库加载键值到内存 |
87+
| `Key<T>::Set(const T&)` | 设置键值并写入数据库 |
88+
| `Key<T>::Load()` | 从数据库加载键值至变量 |
89+
| `Key<T>::operator=(const T&)` | 设置键值(等效于 `Set()`|
90+
| `Key<T>::operator T()` | 类型转换操作,返回当前变量值(不自动加载) |
91+
92+
---
93+
94+
## 工作机制概述
95+
96+
尽管不同实现的底层机制有所区别,但统一遵循如下设计原则:
97+
98+
- 使用主块和备块交替写入,确保写入过程可恢复;
99+
- 所有键值存储以原始名值对序列化,并带有校验位;
100+
- `Init()` 内部自动判断有效块并尝试恢复数据;
101+
- `Restore()` 可主动清空主备数据并初始化空数据库;
102+
- 每个派生类自动处理页对齐、可用空间等底层逻辑,用户无需关心。
103+
104+
---
105+
106+
## 注意事项
107+
108+
- 请优先使用 `Database::Key<T>` 类型封装进行读写;
109+
- 写入仅在调用 `key = val``key.Set(val)` 时发生;
110+
- 对所有键值数据类型要求为 POD 且可拷贝存储;
111+
- 若存储已满或写入失败,`Set()` 会返回对应错误码;
112+
- 若需手动释放数据库对象,注意释放派生类指针。
113+
114+
---
115+
116+
## 应用场景
117+
118+
- 嵌入式设备参数存储;
119+
- 状态断点续存;
120+
- 多模块配置持久化;
121+
- 无动态内存环境下的安全键值存储;
122+
123+
---
124+
125+
## 示例测试
126+
127+
详见 [`test_database.cpp`],展示了键值读写、结构体支持、掉电恢复等场景的完整用例。

docs/basic_coding/middleware/event.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
---
2+
id: event
3+
title: 事件系统
4+
sidebar_position: 3
5+
---
6+
7+
# Event 事件系统
8+
9+
`Event` 类是 LibXR 中用于事件驱动机制的核心中间件,支持事件注册、事件触发、中断安全调用与事件绑定,是构建嵌入式任务协作的重要工具。
10+
11+
## 模块功能
12+
13+
- 基于 **事件 ID** 注册多个回调;
14+
- 支持 **线程/中断上下文触发**
15+
- 可通过 `GetList()` 实现 **中断上下文安全事件触发**
16+
- 支持 **事件桥接绑定**,用于跨模块事件流转;
17+
- 内部采用 **红黑树 + 无锁链表** 实现高效、并发安全存储。
18+
19+
---
20+
21+
## 快速使用
22+
23+
### 注册事件回调
24+
25+
```cpp
26+
int counter = 0;
27+
LibXR::Event evt;
28+
auto cb = LibXR::Event::Callback::Create(
29+
[](bool, int *cnt, uint32_t event) {
30+
(*cnt)++;
31+
ASSERT(event == 0x10);
32+
},
33+
&counter);
34+
35+
evt.Register(0x10, cb);
36+
```
37+
38+
### 触发事件
39+
40+
```cpp
41+
evt.Active(0x10); // 普通线程上下文触发
42+
```
43+
44+
### 中断上下文触发(需提前获取回调链表)
45+
46+
```cpp
47+
// 在非回调中获取事件链表
48+
auto list = evt.GetList(0x1234);
49+
// 在回调中触发
50+
evt.ActiveFromCallback(list, 0x1234);
51+
```
52+
53+
### 事件绑定
54+
55+
```cpp
56+
evt_dst.Bind(evt_src, 0xA, 0xB); // 当 evt_src 的事件 0xA 触发时,会激活 evt_dst 的事件 0xB
57+
```
58+
59+
---
60+
61+
## 类定义结构
62+
63+
- `Event::Register(event, cb)`:注册回调;
64+
- `Event::Active(event)`:非中断触发;
65+
- `Event::ActiveFromCallback(list, event)`:中断上下文安全触发;
66+
- `Event::GetList(event)`:获取并缓存事件链表;
67+
- `Event::Bind(src, id_src, id_dst)`:实现事件桥接;
68+
- 内部使用 `RBTree<uint32_t>` 管理事件映射,事件对应回调使用 `LockFreeList` 存储。
69+
70+
---
71+
72+
## 示例:测试事件绑定与触发
73+
74+
```cpp
75+
int arg = 0;
76+
auto cb = Event::Callback::Create([](bool, int* a, uint32_t e) {
77+
*a += 1;
78+
}, &arg);
79+
80+
Event e1, e2;
81+
e1.Register(0x1234, cb);
82+
e1.Active(0x1234); // arg += 1
83+
e2.Bind(e1, 0x4321, 0x1234);
84+
e2.Active(0x4321); // arg += 1
85+
```
86+
87+
---
88+
89+
## 应用场景
90+
91+
- 按键/传感器中断触发事件;
92+
- 多任务协作中的状态通知;
93+
- 与 Topic/Message 联动构建事件-消息系统。
94+
95+
---
96+
97+
更多信息请查阅 `event.hpp` 源码。

0 commit comments

Comments
 (0)