Skip to content

Commit 6a3b1f8

Browse files
committed
feat: zephyr mutexes and thread example
1 parent ed5da89 commit 6a3b1f8

File tree

2 files changed

+114
-8
lines changed

2 files changed

+114
-8
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include <Arduino_BridgeImola.h>
2+
3+
4+
void setup() {
5+
BRIDGE.begin();
6+
}
7+
8+
void loop() {
9+
delay(10);
10+
}

src/bridge.h

Lines changed: 104 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define RESET_METHOD "$/reset"
77
#define BIND_METHOD "$/register"
88

9+
#include <zephyr/kernel.h>
910
#include <Arduino_RPClite.h>
1011

1112

@@ -15,14 +16,22 @@ class Bridge {
1516
RPCServer* server = nullptr;
1617
ITransport* transport;
1718

19+
struct k_mutex read_mutex;
20+
struct k_mutex write_mutex;
21+
1822
public:
1923
Bridge(ITransport& t) : transport(&t) {}
24+
2025
Bridge(Stream& stream) {
2126
transport = new SerialTransport(stream);
2227
}
2328

2429
// Initialize the bridge
2530
bool begin() {
31+
32+
k_mutex_init(&read_mutex);
33+
k_mutex_init(&write_mutex);
34+
2635
client = new RPCClient(*transport);
2736
server = new RPCServer(*transport);
2837
bool res;
@@ -38,19 +47,60 @@ class Bridge {
3847
return server->bind(name, func);
3948
}
4049

50+
template<typename F>
51+
bool provide_safe(const MsgPack::str_t& name, F&& func) {
52+
bool res;
53+
if (!call(BIND_METHOD, res, name)) {
54+
return false;
55+
}
56+
57+
return server->bind(name, func, "__safe__");
58+
59+
}
60+
4161
void update() {
42-
// Protect the following calls with a mutex if necessary
43-
// server->read_request(); // <- inbound
44-
// server->serve(); // -> outbound
45-
server->run();
62+
63+
// Lock read mutex
64+
while(1){
65+
k_mutex_lock(&read_mutex, K_FOREVER);
66+
if (server->get_rpc()) {
67+
k_mutex_unlock(&read_mutex);
68+
break;
69+
}
70+
k_mutex_unlock(&read_mutex);
71+
k_msleep(1);
72+
}
73+
74+
server->process_request();
75+
76+
// Lock write mutex
77+
k_mutex_lock(&write_mutex, K_FOREVER);
78+
server->send_response();
79+
k_mutex_unlock(&write_mutex);
80+
4681
}
4782

4883
template<typename RType, typename... Args>
4984
bool call(const MsgPack::str_t method, RType& result, Args&&... args) {
50-
// Protect the following calls with a mutex if necessary
51-
// client->send_call(); // -> outbound
52-
// client->read_response(); // <- inbound
53-
return client->call(method, result, std::forward<Args>(args)...);
85+
86+
// Lock write mutex
87+
k_mutex_lock(&write_mutex, K_FOREVER);
88+
client->send_rpc(method, std::forward<Args>(args)...);
89+
k_mutex_unlock(&write_mutex);
90+
91+
// Lock read mutex
92+
while(1) {
93+
k_mutex_lock(&read_mutex, K_FOREVER);
94+
if (client->get_response(result)) {
95+
k_mutex_unlock(&read_mutex);
96+
break;
97+
}
98+
k_mutex_unlock(&read_mutex);
99+
k_msleep(1);
100+
}
101+
102+
return (client->lastError.code == NO_ERR);
103+
54104
}
55105

56106
template<typename... Args>
@@ -66,6 +116,52 @@ class Bridge {
66116
return (uint8_t) client->lastError.code;
67117
}
68118

119+
private:
120+
121+
void update_safe() {
122+
123+
// Lock read mutex
124+
while(1){
125+
k_mutex_lock(&read_mutex, K_FOREVER);
126+
if (server->get_rpc()) {
127+
k_mutex_unlock(&read_mutex);
128+
break;
129+
}
130+
k_mutex_unlock(&read_mutex);
131+
k_msleep(1);
132+
}
133+
134+
server->process_request("__safe__");
135+
136+
// Lock write mutex
137+
k_mutex_lock(&write_mutex, K_FOREVER);
138+
server->send_response();
139+
k_mutex_unlock(&write_mutex);
140+
141+
}
142+
143+
friend class BridgeUpdater;
144+
69145
};
70146

147+
class BridgeUpdater {
148+
public:
149+
static void safeUpdate(Bridge& bridge) {
150+
bridge.update_safe(); // access private method
151+
}
152+
153+
private:
154+
BridgeUpdater() = delete; // prevents instantiation
155+
};
156+
157+
Bridge BRIDGE(Serial1);
158+
159+
static void safeUpdate(){
160+
BridgeUpdater::safeUpdate(BRIDGE);
161+
}
162+
163+
void __loopHook(){
164+
safeUpdate();
165+
}
166+
71167
#endif // BRIDGE_IMOLA_H

0 commit comments

Comments
 (0)