Skip to content

Commit 5b2b274

Browse files
Merge pull request #189 from stanford-ssi/payload/heartbeat
Created heartbeat_check function in payload_task.c
2 parents e3634ae + 88cbfdc commit 5b2b274

File tree

6 files changed

+139
-72
lines changed

6 files changed

+139
-72
lines changed

src/drivers/payload_uart/payload_uart.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#define PARITY UART_PARITY_NONE
2626
#define WRITE_MAX_TIMEOUT 10000
2727
#define MAX_WRITE_TRIES 3
28+
#define UART_READ_WRITE_BLOCKING_MS 50
2829

2930
// Packet parameters
3031
#define MAX_PACKET_LEN 4069
@@ -195,10 +196,17 @@ static void send_syn()
195196
}
196197
}
197198

199+
void payload_restart(slate_t *slate)
200+
{
201+
payload_turn_off(slate);
202+
payload_turn_on(slate);
203+
}
204+
198205
void payload_turn_on(slate_t *slate)
199206
{
200207
gpio_put(SAMWISE_RPI_ENAB, 1);
201208
slate->is_payload_on = true;
209+
slate->payload_most_recent_ping_time = get_absolute_time();
202210
}
203211

204212
void payload_turn_off(slate_t *slate)
@@ -399,8 +407,8 @@ uint16_t payload_uart_read_packet(slate_t *slate, uint8_t *packet)
399407

400408
// Receive header
401409
packet_header_t header;
402-
bytes_received =
403-
receive_into(slate, &header, sizeof(packet_header_t), 1000);
410+
bytes_received = receive_into(slate, &header, sizeof(packet_header_t),
411+
UART_READ_WRITE_BLOCKING_MS);
404412

405413
if (bytes_received < sizeof(packet_header_t))
406414
{
@@ -417,7 +425,8 @@ uint16_t payload_uart_read_packet(slate_t *slate, uint8_t *packet)
417425
}
418426

419427
// Read actual packet
420-
bytes_received = receive_into(slate, packet, header.length, 1000);
428+
bytes_received =
429+
receive_into(slate, packet, header.length, UART_READ_WRITE_BLOCKING_MS);
421430

422431
if (bytes_received < header.length)
423432
{

src/drivers/payload_uart/payload_uart.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@ payload_write_error_code payload_uart_write_packet(slate_t *slate,
2323
uint16_t len,
2424
uint16_t seq_num);
2525

26+
void payload_restart(slate_t *slate);
2627
void payload_turn_on(slate_t *slate);
2728
void payload_turn_off(slate_t *slate);

src/slate/slate.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ typedef struct samwise_slate
129129
adcs_packet_t adcs_telemetry;
130130
bool is_adcs_telem_valid;
131131

132+
/*
133+
Payload Heartbeat time: the time at which the Picubed last sent a request to
134+
the payload.
135+
*/
136+
absolute_time_t payload_most_recent_ping_time;
137+
132138
} slate_t;
133139

134140
extern slate_t slate;

src/tasks/command/command_parser.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ void dispatch_command(slate_t *slate, packet_t *packet)
115115
}
116116
break;
117117
}
118-
119118
default:
120119
LOG_ERROR("Unknown command ID: %i", command_id);
121120
break;

src/tasks/payload/payload_task.c

Lines changed: 119 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <stdio.h>
1010

1111
#define MAX_RECEIVED_LEN 1024
12+
#define SEQUENCE_NUMBER_DUMMY 999
1213

1314
void payload_task_init(slate_t *slate)
1415
{
@@ -30,63 +31,139 @@ void payload_task_init(slate_t *slate)
3031
// NOTE: Turning on payload is handled by command_parser
3132
}
3233

34+
bool send_payload_exec(slate_t *slate, char msg[], uint16_t seq_num)
35+
{
36+
LOG_INFO("Executing Payload Command: %s", msg);
37+
// First attempt to execute the command but do not throw it away
38+
// yet.
39+
payload_write_error_code exec_successful =
40+
payload_uart_write_packet(slate, msg, sizeof(msg), seq_num);
41+
42+
if (exec_successful == SUCCESSFUL_WRITE)
43+
{
44+
return true;
45+
}
46+
else if (exec_successful == PACKET_TOO_BIG)
47+
{
48+
LOG_DEBUG("Packet exceeds 4096 bytes...");
49+
return false;
50+
}
51+
else if (exec_successful == SYN_UNSUCCESSFUL)
52+
{
53+
LOG_DEBUG("PiCubed was unable to sync with the Payload...");
54+
return false;
55+
}
56+
else if (exec_successful == UART_WRITE_TIMEDOUT)
57+
{
58+
LOG_DEBUG("The transmission took too long and the write timed "
59+
"out...");
60+
return false;
61+
}
62+
else if (exec_successful == HEADER_UNACKNOWLEDGED)
63+
{
64+
LOG_DEBUG("Payload did not acknowledge the header...");
65+
return false;
66+
}
67+
else if (exec_successful == FINAL_WRITE_UNSUCCESSFUL)
68+
{
69+
LOG_DEBUG("Final packet transmission timed out...");
70+
return false;
71+
}
72+
else
73+
{
74+
LOG_DEBUG("Payload command execution failed, retrying...");
75+
// If the command was not successful, we will not remove it
76+
// from the queue and will try again next time.
77+
return false;
78+
}
79+
}
80+
81+
bool ping_command(slate_t *slate)
82+
{
83+
char packet[] = "[\"ping\", [], {}]";
84+
bool write_success =
85+
send_payload_exec(slate, packet, SEQUENCE_NUMBER_DUMMY);
86+
if (!write_success)
87+
{
88+
LOG_INFO("Writing packet to payload was not successful!");
89+
return false;
90+
}
91+
92+
char received[MAX_RECEIVED_LEN];
93+
uint16_t received_len = payload_uart_read_packet(slate, received);
94+
if (received_len == 0)
95+
{
96+
LOG_INFO("ACK was not received!");
97+
return false;
98+
}
99+
else
100+
{
101+
LOG_INFO("ACK received!");
102+
LOG_INFO("ACK:");
103+
for (uint16_t i = 0; i < received_len; i++)
104+
{
105+
printf("%c", received[i]);
106+
}
107+
printf("\n");
108+
return true;
109+
}
110+
}
111+
112+
bool send_heartbeat(slate_t *slate)
113+
{
114+
if (slate->is_payload_on)
115+
{
116+
uint64_t timeDelta =
117+
absolute_time_diff_us(slate->payload_most_recent_ping_time,
118+
get_absolute_time()) /
119+
1000;
120+
if (timeDelta >= PAYLOAD_HEARTBEAT_TIMEOUT_MS)
121+
{
122+
payload_restart(slate); // this resets the most_recent_ping_time.
123+
// still return false; don't let the payload send commands (since we
124+
// aren't getting responses.)
125+
return false;
126+
}
127+
else
128+
{
129+
bool response_received = ping_command(slate);
130+
if (response_received)
131+
{
132+
slate->payload_most_recent_ping_time = get_absolute_time();
133+
return true;
134+
// operational! we can send commands now.
135+
}
136+
// if we don't get a response back, don't update the time.
137+
return false;
138+
}
139+
}
140+
return false;
141+
}
142+
33143
bool try_execute_payload_command(slate_t *slate)
34144
{
35145
if (!queue_is_empty(&slate->payload_command_data))
36146
{
37147
PAYLOAD_COMMAND_DATA payload_command;
38148
if (queue_try_peek(&slate->payload_command_data, &payload_command))
39149
{
40-
LOG_INFO("Executing Payload Command: %s",
41-
payload_command.serialized_command);
42-
// First attempt to execute the command but do not throw it away
43-
// yet.
44-
payload_write_error_code exec_successful =
45-
payload_uart_write_packet(
46-
slate, payload_command.serialized_command,
47-
sizeof(payload_command.serialized_command),
48-
payload_command.seq_num);
150+
bool writeSuccess =
151+
send_payload_exec(slate, payload_command.serialized_command,
152+
payload_command.seq_num);
153+
// removeFromQueue is true if we succesfully sent the packet to the
154+
// payload
155+
49156
// If the command was successful, remove it from the queue.
50157
// Alternatively, if we have already retried the command up to
51158
// a maximum number of times, remove it from the queue.
52-
if (exec_successful == SUCCESSFUL_WRITE ||
53-
RETRY_COUNT >= MAX_PAYLOAD_RETRY_COUNT)
159+
if (writeSuccess || RETRY_COUNT > MAX_PAYLOAD_RETRY_COUNT)
54160
{
55161
// Return success when the command is removed.
56162
return queue_try_remove(&slate->payload_command_data,
57163
&payload_command);
58164
}
59-
else if (exec_successful == PACKET_TOO_BIG)
60-
{
61-
LOG_DEBUG("Packet exceeds 4096 bytes...");
62-
return false;
63-
}
64-
else if (exec_successful == SYN_UNSUCCESSFUL)
65-
{
66-
LOG_DEBUG("PiCubed was unable to sync with the Payload...");
67-
return false;
68-
}
69-
else if (exec_successful == UART_WRITE_TIMEDOUT)
70-
{
71-
LOG_DEBUG("The transmission took too long and the write timed "
72-
"out...");
73-
return false;
74-
}
75-
else if (exec_successful == HEADER_UNACKNOWLEDGED)
76-
{
77-
LOG_DEBUG("Payload did not acknowledge the header...");
78-
return false;
79-
}
80-
else if (exec_successful == FINAL_WRITE_UNSUCCESSFUL)
81-
{
82-
LOG_DEBUG("Final packet transmission timed out...");
83-
return false;
84-
}
85165
else
86166
{
87-
LOG_DEBUG("Payload command execution failed, retrying...");
88-
// If the command was not successful, we will not remove it
89-
// from the queue and will try again next time.
90167
return false;
91168
}
92169
}
@@ -135,32 +212,6 @@ void beacon_down_command_test(slate_t *slate)
135212
}
136213
}
137214

138-
void ping_command_test(slate_t *slate)
139-
{
140-
char packet[] = "[\"ping\", [], {}]";
141-
int len = sizeof(packet) - 1;
142-
payload_uart_write_packet(slate, packet, len, 999);
143-
144-
safe_sleep_ms(1000);
145-
146-
char received[MAX_RECEIVED_LEN];
147-
uint16_t received_len = payload_uart_read_packet(slate, received);
148-
if (received_len == 0)
149-
{
150-
LOG_INFO("ACK was not received!");
151-
}
152-
else
153-
{
154-
LOG_INFO("ACK received!");
155-
LOG_INFO("ACK:");
156-
for (uint16_t i = 0; i < received_len; i++)
157-
{
158-
printf("%c", received[i]);
159-
}
160-
printf("\n");
161-
}
162-
}
163-
164215
/*** BRINGUP TESTS ***/
165216
void power_on_off_payload_test(slate_t *slate)
166217
{
@@ -258,13 +309,13 @@ void payload_task_dispatch(slate_t *slate)
258309
neopixel_set_color_rgb(PAYLOAD_TASK_COLOR);
259310
LOG_INFO("Sending an Info Request Command to the RPI...");
260311
// beacon_down_command_test(slate);
261-
// ping_command_test(slate);
312+
// ping_command(slate);
262313

263314
payload_uart_write_on_test(slate);
264315

265316
return;
266317

267-
if (slate->is_payload_on)
318+
if (send_heartbeat(slate))
268319
{
269320
LOG_INFO("Payload is ON, executing commands...");
270321
// Attempts to execute k commands per dispatch.

src/tasks/payload/payload_task.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#define MAX_PAYLOAD_COMMANDS_PER_DISPATCH 3
1818
#define MAX_PAYLOAD_RETRY_COUNT 3
19+
#define PAYLOAD_HEARTBEAT_TIMEOUT_MS 10000
1920

2021
void payload_task_init(slate_t *slate);
2122
void payload_task_dispatch(slate_t *slate);

0 commit comments

Comments
 (0)