Retransmits » Historie » Version 15
Maximilian Seesslen, 03.04.2025 15:23
1 | 3 | Maximilian Seesslen | h1. Modes |
---|---|---|---|
2 | |||
3 | 4 | Maximilian Seesslen | h2. Unrelated |
4 | 3 | Maximilian Seesslen | |
5 | * Send CAN messages as Broadcast messages; fire and forget |
||
6 | * Good enough for sensor values |
||
7 | * Robust code, not much that can fail |
||
8 | * Not good enough for e.g. Flashing firmware on remote device or even scanning nodes. |
||
9 | |||
10 | 4 | Maximilian Seesslen | h2. Related |
11 | 3 | Maximilian Seesslen | |
12 | * Each package need an acknowledge |
||
13 | * Retransmitts are send if acknowledge is missing |
||
14 | 1 | Maximilian Seesslen | * Heavy traffic if nodes are blocking each other. |
15 | * Complex code, but ok |
||
16 | 4 | Maximilian Seesslen | * Order may not be guearanteed / optional |
17 | 1 | Maximilian Seesslen | |
18 | 4 | Maximilian Seesslen | h1. Related |
19 | 1 | Maximilian Seesslen | |
20 | 4 | Maximilian Seesslen | h2. Retransmits |
21 | |||
22 | 2 | Maximilian Seesslen | * In starting phase there is an auto-tune which requires traffic |
23 | * There are at least some CRC errors |
||
24 | |||
25 | 4 | Maximilian Seesslen | h2. Send package |
26 | 2 | Maximilian Seesslen | |
27 | * ringTransmitted.canPush()? |
||
28 | * store essage there |
||
29 | * Send it via RFM69 |
||
30 | |||
31 | h2. Receive package |
||
32 | |||
33 | * If type is "Acknowledge" |
||
34 | ** find corresponding message |
||
35 | ** mark slot as acked/nacked |
||
36 | |||
37 | * If regular message/resend |
||
38 | ** If resend: is the package older than the last?, drop it |
||
39 | ** is it not last+1? send NACK via RFM69 |
||
40 | ** fill it in the receive buffer |
||
41 | ** directly send acknowledge via RFM69 |
||
42 | |||
43 | h2. Loop |
||
44 | |||
45 | * iterate Slots |
||
46 | * If WAITing: is message is older than ??ms, perform an resend |
||
47 | * If ACKed, pop it from the ring. Not the first non-ACKed? Error |
||
48 | 5 | Maximilian Seesslen | * If NACKed, resend it, if there is no WAITing before |
49 | 2 | Maximilian Seesslen | |
50 | h2. Open points |
||
51 | |||
52 | * Acknowledge gets lost; retransmit started |
||
53 | ** last-id for every net. Drop message if it matches |
||
54 | |||
55 | * RFM-Class receives messages in ISR as fast as possible. Sending acknowledge is done in the loop. |
||
56 | ** Order should be preserved. |
||
57 | 1 | Maximilian Seesslen | ** Makes things super slow |
58 | 5 | Maximilian Seesslen | |
59 | h2. State machine |
||
60 | |||
61 | h3. Sender event loop |
||
62 | |||
63 | * Each node sends a heartbeat every 5 seconds with the current message counter. |
||
64 | * A node has a list of (expected) package counter of other devices |
||
65 | * When a node received a message via can, it sends it as broadcast and sets the open-ack-mask to the node-mask |
||
66 | * If there was no ACK after 10ms, send retransmit to each Ack-missing node. |
||
67 | * If there was no ACK after 10 Seconds, remove remaing nodes from Node-List. |
||
68 | * If there is no Heartbeat from a Node for 1 Minute, remove node from |
||
69 | |||
70 | h3. Receiver Event loop |
||
71 | |||
72 | * When receiving a message via radio with correct order, an acknowledge is send immediately. Process and drop the message. |
||
73 | * When receiving a message via radio with to low order, send an acknowledge again and drop the message. |
||
74 | * When receiving a message via radio with too high order, act like in (1), but warn becuase of lost message. |
||
75 | 6 | Maximilian Seesslen | |
76 | h3. Keep order |
||
77 | |||
78 | To keep the order of the messages, the event loop need to handle only the oldest message in the list. |
||
79 | This may slow down everything. All messages are blocked till a last node send an ACK. |
||
80 | 9 | Maximilian Seesslen | -This can be tested by making it optional.- This has to be the implemented or the message-counter does not work any more. |
81 | |||
82 | h3. Overflow |
||
83 | |||
84 | It may make sence to have a small message counter of 8bit, a bigger one is not really needed. |
||
85 | |||
86 | 0 ... 127, -128 ... -1 |
||
87 | |||
88 | 10 | Maximilian Seesslen | Overflow-save operations: |
89 | <pre><code class="cpp"> |
||
90 | #define TYPE signed char |
||
91 | |||
92 | 11 | Maximilian Seesslen | // Don't cast the types anywhere! |
93 | 14 | Maximilian Seesslen | constexpr TYPE counterDistance( TYPE c1, TYPE c2) |
94 | 10 | Maximilian Seesslen | { |
95 | return( c2 - c1 ); |
||
96 | } |
||
97 | |||
98 | 15 | Maximilian Seesslen | static_assert( counterDistance( 127, -128 ) == 1, "A" ); |
99 | static_assert( counterDistance(0x7F, 0x80) == 1, "B" ); |
||
100 | static_assert( counterDistance(0xFF, 0x00) == 1, "C" ); |
||
101 | static_assert( counterDistance(0x80, 0x7F) == -1, "D" ); |
||
102 | static_assert( counterDistance(0x00, 0xFF) == -1, "E" ); |
||
103 | 14 | Maximilian Seesslen | </code></pre> |
104 | 15 | Maximilian Seesslen | |
105 | 7 | Maximilian Seesslen | |
106 | h3. CANRec |
||
107 | |||
108 | 8 | Maximilian Seesslen | Replay-Messages (seperate function code) will be skipped. The order has to be kept anyways because of the message counter. |
109 | |||
110 | 12 | Maximilian Seesslen | h3. Diagnose |
111 | |||
112 | Timing measurements would be nice but at high cost. Skip it for now. |
||
113 | |||
114 | h3. Methods |
||
115 | |||
116 | 8 | Maximilian Seesslen | * enqueueReceiveRadioMessage |
117 | * enqueueTransmitRadioMessage |
||
118 | * receiveRadioMessage; physical transition of radio module to CANBridge state machine |
||
119 | * transmitRadioMessage; physical transition of radio module to CANBridge state machine |
||
120 | 13 | Maximilian Seesslen | |
121 | h3. States |
||
122 | |||
123 | * Invalid |
||
124 | * Unsend |
||
125 | * WaitForAck |