SAE Teensy ECU
IIT SAE Microcontroller programming
Loading...
Searching...
No Matches
messageModule.hpp
1#pragma once
2
3#include "activeModule.hpp"
4
5namespace Module {
6
8public:
9 static const int classID = 2;
10
11 virtual int getClassID() const { return classID; }
12
13 struct Msg_t {
14 private:
15 std::mutex waitMux; // IMPROVE: modules that have other modules waiting on them should be bumped up in priority
16 enum Status {
17 SENT,
18 RECEIVED,
19 REPLY,
20 ERROR,
21 NIL
22 } status = NIL;
23 Msg_t(const MessengerModule_t *sender, const MessengerModule_t *receiver, const void *value) : status(SENT), sender(sender), receiver(receiver), value(value) { waitMux.lock(); }
24 Msg_t() {}
25
26 friend MessengerModule_t;
27
28 public:
29 const MessengerModule_t *sender = 0;
30 const MessengerModule_t *receiver = 0;
31 const void *value;
32
33 void wait() {
34 waitMux.lock();
35 }
36
37 void timeout() {
38 status = ERROR;
39 waitMux.unlock();
40 }
41
42 void reply() {
43 status = REPLY;
44 waitMux.unlock();
45 }
46
47 void finish() {
48 status = NIL;
49 waitMux.unlock();
50 }
51 };
52
53 using Module::ActiveModule_t::ActiveModule_t;
54
55private:
56 std::queue<Msg_t *> incoming; // TODO: allow concurrent produce and consume
57
58 void _queueMsg(Msg_t *msg) {
59 incoming.push(msg); // TODO: mutex if necessary, make modules wait to push if needed
60 }
61
62protected:
63 Msg_t *sendMessage(MessengerModule_t *receiver, const void *value) {
64 Msg_t *msg = new Msg_t(this, receiver, value);
65 receiver->_queueMsg(msg);
66 return msg;
67 }
68
69 // Wait for a reply
70 void sendMessageWait(MessengerModule_t *receiver, const void *value) {
71 Msg_t msg(this, receiver, value);
72 receiver->_queueMsg(&msg);
73 msg.wait();
74 }
75
76 // Up to the sender and receiver to send and accept the correct data/structs
77 Msg_t *receiveMessage() {
78 if (incoming.empty())
79 return nullptr;
80 Msg_t *msg = incoming.front();
81 incoming.pop();
82 msg->status = Msg_t::RECEIVED;
83 return msg;
84 }
85};
86
87} // namespace Module