libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
publish.cpp
1#include <atomic>
2
3#include "libxr_mem.hpp"
4#include "message.hpp"
5#include "timebase.hpp"
6
7using namespace LibXR;
8
14
15void Topic::CheckPublishSize(TopicHandle topic, uint32_t size)
16{
17 if (topic->data_.check_length)
18 {
19 ASSERT(size == topic->data_.max_length);
20 }
21 else
22 {
23 ASSERT(size <= topic->data_.max_length);
24 }
25}
26
27RawData Topic::StorePublishedData(TopicHandle topic, void* addr, uint32_t size,
28 MicrosecondTimestamp timestamp)
29{
30 if (topic->data_.cache)
31 {
32 LibXR::Memory::FastCopy(topic->data_.data.addr_, addr, size);
33 topic->data_.data.size_ = size;
34 }
35 else
36 {
37 topic->data_.data.addr_ = addr;
38 topic->data_.data.size_ = size;
39 }
40
41 topic->data_.timestamp = timestamp;
42 return topic->data_.data;
43}
44
45void Topic::DispatchSubscriber(SuberBlock& block, MicrosecondTimestamp timestamp,
46 RawData data, bool from_callback, bool in_isr)
47{
48 switch (block.type)
49 {
50 case SuberType::SYNC:
51 {
52 auto sync = static_cast<SyncBlock*>(&block);
53 uint32_t expected = SyncBlock::WAITING;
54 auto wake_waiter = sync->wait_state.compare_exchange_strong(
55 expected, SyncBlock::WAIT_CLAIMED, std::memory_order_acq_rel,
56 std::memory_order_acquire);
57
58 if (!wake_waiter)
59 {
60 break;
61 }
62
63 LibXR::Memory::FastCopy(sync->buff.addr_, data.addr_, data.size_);
64 sync->timestamp = timestamp;
65
66 if (from_callback)
67 {
68 sync->sem.PostFromCallback(in_isr);
69 }
70 else
71 {
72 sync->sem.Post();
73 }
74 break;
75 }
77 {
78 auto async = static_cast<ASyncBlock*>(&block);
79 if (async->state.load(std::memory_order_acquire) == ASyncSubscriberState::WAITING)
80 {
81 LibXR::Memory::FastCopy(async->buff.addr_, data.addr_, data.size_);
82 async->timestamp = timestamp;
83 async->state.store(ASyncSubscriberState::DATA_READY, std::memory_order_release);
84 }
85 break;
86 }
88 {
89 auto queue_block = static_cast<QueueBlock*>(&block);
90 queue_block->fun(timestamp, data, *queue_block);
91 break;
92 }
94 {
95 auto cb_block = static_cast<CallbackBlock*>(&block);
96 cb_block->cb.Run(from_callback && in_isr, timestamp, data);
97 break;
98 }
99 }
100}
101
102void Topic::DispatchSubscribers(TopicHandle topic, MicrosecondTimestamp timestamp,
103 RawData data, bool from_callback, bool in_isr)
104{
105 topic->data_.subers.Foreach<SuberBlock>(
106 [=](SuberBlock& block)
107 {
108 DispatchSubscriber(block, timestamp, data, from_callback, in_isr);
109 return ErrorCode::OK;
110 });
111}
112
113void Topic::PublishRaw(void* addr, uint32_t size, MicrosecondTimestamp timestamp,
114 bool from_callback, bool in_isr)
115{
116 if (from_callback)
117 {
119 }
120 else
121 {
122 Lock(block_);
123 }
124
125 CheckPublishSize(block_, size);
126 RawData data = StorePublishedData(block_, addr, size, timestamp);
127 DispatchSubscribers(block_, timestamp, data, from_callback, in_isr);
128
129 if (from_callback)
130 {
132 }
133 else
134 {
135 Unlock(block_);
136 }
137}
138
139void Topic::Publish(void* addr, uint32_t size) { Publish(addr, size, NowTimestamp()); }
140
141void Topic::Publish(void* addr, uint32_t size, MicrosecondTimestamp timestamp)
142{
143 PublishRaw(addr, size, timestamp, false, false);
144}
145
146void Topic::PublishFromCallback(void* addr, uint32_t size, bool in_isr)
147{
148 PublishFromCallback(addr, size, NowTimestamp(), in_isr);
149}
150
151void Topic::PublishFromCallback(void* addr, uint32_t size, MicrosecondTimestamp timestamp,
152 bool in_isr)
153{
154 PublishRaw(addr, size, timestamp, true, in_isr);
155}
回调函数封装块,提供参数绑定与擦除调用入口 / Callback block with bound argument and erased invoke entry
Definition libxr_cb.hpp:41
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy
Definition libxr_mem.cpp:5
微秒时间戳 / Microsecond timestamp
可写原始数据视图 / Mutable raw data view
size_t size_
数据字节数 / Data size in bytes
void * addr_
数据起始地址 / Data start address
static Timebase * timebase
静态指针,用于存储全局时间基对象。 Static pointer storing the global timebase instance.
Definition timebase.hpp:119
static MicrosecondTimestamp GetMicroseconds()
获取当前时间的微秒级时间戳。 Gets the current timestamp in microseconds.
Definition timebase.hpp:49
@ SYNC
同步订阅者。Synchronous subscriber.
@ ASYNC
异步订阅者。Asynchronous subscriber.
@ QUEUE
队列订阅者。Queued subscriber.
@ CALLBACK
回调订阅者。Callback subscriber.
void Publish(Data &data)
发布数据 Publishes data
Definition message.hpp:381
static void Unlock(TopicHandle topic)
解锁主题。Unlock the topic.
Definition topic.cpp:48
static MicrosecondTimestamp NowTimestamp()
生成默认发布时刻。Create the default publish timestamp.
Definition publish.cpp:9
static void Lock(TopicHandle topic)
锁定主题,防止其被多个订阅者同时访问。Lock the topic to prevent it from being accessed by multiple subscribers at the sa...
Definition topic.cpp:30
static void UnlockFromCallback(TopicHandle topic)
从回调中解锁主题。Unlock the topic from a callback.
Definition topic.cpp:78
static void LockFromCallback(TopicHandle topic)
从回调中锁定主题,防止其被多个订阅者同时访问。Lock the topic from a callback to prevent it from being accessed by multiple s...
Definition topic.cpp:60
void PublishFromCallback(Data &data, bool in_isr)
在回调函数中发布数据 Publishes data in a callback
Definition message.hpp:412
TopicHandle block_
主题句柄,指向当前主题的内存块 Topic handle pointing to the memory block of the current topic
Definition message.hpp:547
LibXR 命名空间
Definition ch32_can.hpp:14
@ OK
操作成功 | Operation successful