Skip to content

Commit 3ccb30c

Browse files
committed
Decouple App from Arduino's runloop and Serial global
Signed-off-by: Javier Balloffet <javier.balloffet@gmail.com>
1 parent 3da85f7 commit 3ccb30c

4 files changed

Lines changed: 68 additions & 57 deletions

File tree

andino_firmware/include/andino/app/shell.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ class Shell {
4949
/// @brief Sets the default callback for unknown commands.
5050
///
5151
/// @param callback Callback function.
52-
void set_default_callback(CommandCallback callback);
52+
/// @param context Context pointer to pass to the callback.
53+
void set_default_callback(CommandCallback callback, void* context = nullptr);
5354

5455
/// @brief Adds a command registry entry to the shell.
5556
///
@@ -97,6 +98,9 @@ class Shell {
9798
/// Default callback for unknown commands.
9899
CommandCallback default_callback_{nullptr};
99100

101+
/// Context pointer to pass to the default callback.
102+
void* default_callback_context_{nullptr};
103+
100104
/// Command registry.
101105
Command commands_[kCommandsMax];
102106

andino_firmware/src/app/app.cpp

Lines changed: 51 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@
6565
#include "andino/app/app.h"
6666

6767
#include <stdio.h>
68+
#include <stdlib.h>
69+
#include <string.h>
6870

6971
#include <Adafruit_BNO055.h>
7072
#include <Adafruit_Sensor.h>
@@ -78,9 +80,6 @@
7880
namespace andino {
7981

8082
void App::setup() {
81-
// Required by Arduino libraries to work.
82-
init();
83-
8483
serial_stream_.begin(Constants::kBaudrate);
8584

8685
left_encoder_.begin();
@@ -96,7 +95,7 @@ void App::setup() {
9695

9796
// Initialize command shell.
9897
shell_.set_serial_stream(&serial_stream_);
99-
shell_.set_default_callback(cmd_unknown_cb);
98+
shell_.set_default_callback(cmd_unknown_cb, this);
10099
shell_.register_command(Commands::kReadAnalogGpio, cmd_read_analog_gpio_cb, this);
101100
shell_.register_command(Commands::kReadDigitalGpio, cmd_read_digital_gpio_cb, this);
102101
shell_.register_command(Commands::kReadEncoders, cmd_read_encoders_cb, this);
@@ -129,40 +128,38 @@ void App::loop() {
129128
last_set_motors_speed_cmd_ = clock_.millis();
130129
stop_motors();
131130
}
132-
133-
// Required by Arduino libraries to work.
134-
if (serialEventRun) {
135-
serialEventRun();
136-
}
137131
}
138132

139-
void App::cmd_unknown_cb(void*, int, char**) {
140-
Serial.println("Unknown command.");
133+
void App::cmd_unknown_cb(void* context, int, char**) {
134+
App* app = static_cast<App*>(context);
135+
app->serial_stream_.println("Unknown command.");
141136
}
142137

143-
void App::cmd_read_analog_gpio_cb(void*, int argc, char** argv) {
138+
void App::cmd_read_analog_gpio_cb(void* context, int argc, char** argv) {
144139
if (argc < 2) {
145140
return;
146141
}
147142

143+
App* app = static_cast<App*>(context);
148144
const int pin = atoi(argv[1]);
149-
Serial.println(analogRead(pin));
145+
app->serial_stream_.println(analogRead(pin));
150146
}
151147

152-
void App::cmd_read_digital_gpio_cb(void*, int argc, char** argv) {
148+
void App::cmd_read_digital_gpio_cb(void* context, int argc, char** argv) {
153149
if (argc < 2) {
154150
return;
155151
}
156152

153+
App* app = static_cast<App*>(context);
157154
const int pin = atoi(argv[1]);
158-
Serial.println(digitalRead(pin));
155+
app->serial_stream_.println(digitalRead(pin));
159156
}
160157

161158
void App::cmd_read_encoders_cb(void* context, int, char**) {
162159
App* app = static_cast<App*>(context);
163-
Serial.print(app->left_encoder_.read());
164-
Serial.print(" ");
165-
Serial.println(app->right_encoder_.read());
160+
app->serial_stream_.print(app->left_encoder_.read());
161+
app->serial_stream_.print(" ");
162+
app->serial_stream_.println(app->right_encoder_.read());
166163
}
167164

168165
void App::cmd_reset_encoders_cb(void* context, int, char**) {
@@ -171,7 +168,7 @@ void App::cmd_reset_encoders_cb(void* context, int, char**) {
171168
app->right_encoder_.reset();
172169
app->left_pid_controller_.reset(app->left_encoder_.read());
173170
app->right_pid_controller_.reset(app->right_encoder_.read());
174-
Serial.println("OK");
171+
app->serial_stream_.println("OK");
175172
}
176173

177174
void App::cmd_set_motors_speed_cb(void* context, int argc, char** argv) {
@@ -201,7 +198,7 @@ void App::cmd_set_motors_speed_cb(void* context, int argc, char** argv) {
201198
// Constants::kPidRate.
202199
app->left_pid_controller_.set_setpoint(left_motor_speed / Constants::kPidRate);
203200
app->right_pid_controller_.set_setpoint(right_motor_speed / Constants::kPidRate);
204-
Serial.println("OK");
201+
app->serial_stream_.println("OK");
205202
}
206203

207204
void App::cmd_set_motors_pwm_cb(void* context, int argc, char** argv) {
@@ -224,7 +221,7 @@ void App::cmd_set_motors_pwm_cb(void* context, int argc, char** argv) {
224221

225222
app->left_motor_.set_speed(left_motor_pwm);
226223
app->right_motor_.set_speed(right_motor_pwm);
227-
Serial.println("OK");
224+
app->serial_stream_.println("OK");
228225
}
229226

230227
void App::cmd_set_pid_tuning_gains_cb(void* context, int argc, char** argv) {
@@ -249,63 +246,63 @@ void App::cmd_set_pid_tuning_gains_cb(void* context, int argc, char** argv) {
249246
}
250247
app->left_pid_controller_.set_tunings(pid_args[0], pid_args[1], pid_args[2], pid_args[3]);
251248
app->right_pid_controller_.set_tunings(pid_args[0], pid_args[1], pid_args[2], pid_args[3]);
252-
Serial.print("PID Updated: ");
253-
Serial.print(pid_args[0]);
254-
Serial.print(" ");
255-
Serial.print(pid_args[1]);
256-
Serial.print(" ");
257-
Serial.print(pid_args[2]);
258-
Serial.print(" ");
259-
Serial.println(pid_args[3]);
260-
Serial.println("OK");
249+
app->serial_stream_.print("PID Updated: ");
250+
app->serial_stream_.print(pid_args[0]);
251+
app->serial_stream_.print(" ");
252+
app->serial_stream_.print(pid_args[1]);
253+
app->serial_stream_.print(" ");
254+
app->serial_stream_.print(pid_args[2]);
255+
app->serial_stream_.print(" ");
256+
app->serial_stream_.println(pid_args[3]);
257+
app->serial_stream_.println("OK");
261258
}
262259

263260
void App::cmd_get_is_imu_connected_cb(void* context, int, char**) {
264261
App* app = static_cast<App*>(context);
265-
Serial.println(app->is_imu_connected);
262+
app->serial_stream_.println(app->is_imu_connected);
266263
}
267264

268265
void App::cmd_read_encoders_and_imu_cb(void* context, int, char**) {
269266
App* app = static_cast<App*>(context);
270-
Serial.print(app->left_encoder_.read());
271-
Serial.print(" ");
272-
Serial.print(app->right_encoder_.read());
273-
Serial.print(" ");
267+
app->serial_stream_.print(app->left_encoder_.read());
268+
app->serial_stream_.print(" ");
269+
app->serial_stream_.print(app->right_encoder_.read());
270+
app->serial_stream_.print(" ");
274271

275272
// Retrieve absolute orientation (quaternion). See
276273
// https://learn.adafruit.com/adafruit-bno055-absolute-orientation-sensor/overview for further
277274
// information.
278275
imu::Quaternion orientation = app->bno055_imu_.getQuat();
279-
Serial.print(orientation.x(), 4);
280-
Serial.print(" ");
281-
Serial.print(orientation.y(), 4);
282-
Serial.print(" ");
283-
Serial.print(orientation.z(), 4);
284-
Serial.print(" ");
285-
Serial.print(orientation.w(), 4);
286-
Serial.print(" ");
276+
app->serial_stream_.print(orientation.x(), 4);
277+
app->serial_stream_.print(" ");
278+
app->serial_stream_.print(orientation.y(), 4);
279+
app->serial_stream_.print(" ");
280+
app->serial_stream_.print(orientation.z(), 4);
281+
app->serial_stream_.print(" ");
282+
app->serial_stream_.print(orientation.w(), 4);
283+
app->serial_stream_.print(" ");
287284

288285
// Retrieve angular velocity (rad/s). See
289286
// https://learn.adafruit.com/adafruit-bno055-absolute-orientation-sensor/overview for further
290287
// information.
291288
imu::Vector<3> angular_velocity = app->bno055_imu_.getVector(Adafruit_BNO055::VECTOR_GYROSCOPE);
292-
Serial.print(angular_velocity.x());
293-
Serial.print(" ");
294-
Serial.print(angular_velocity.y());
295-
Serial.print(" ");
296-
Serial.print(angular_velocity.z());
297-
Serial.print(" ");
289+
app->serial_stream_.print(angular_velocity.x());
290+
app->serial_stream_.print(" ");
291+
app->serial_stream_.print(angular_velocity.y());
292+
app->serial_stream_.print(" ");
293+
app->serial_stream_.print(angular_velocity.z());
294+
app->serial_stream_.print(" ");
298295

299296
// Retrieve linear acceleration (m/s^2). See
300297
// https://learn.adafruit.com/adafruit-bno055-absolute-orientation-sensor/overview for further
301298
// information.
302299
imu::Vector<3> linear_acceleration =
303300
app->bno055_imu_.getVector(Adafruit_BNO055::VECTOR_LINEARACCEL);
304-
Serial.print(linear_acceleration.x());
305-
Serial.print(" ");
306-
Serial.print(linear_acceleration.y());
307-
Serial.print(" ");
308-
Serial.print(linear_acceleration.z());
301+
app->serial_stream_.print(linear_acceleration.x());
302+
app->serial_stream_.print(" ");
303+
app->serial_stream_.print(linear_acceleration.y());
304+
app->serial_stream_.print(" ");
305+
app->serial_stream_.print(linear_acceleration.z());
309306
}
310307

311308
void App::adjust_motors_speed() {

andino_firmware/src/app/shell.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ void Shell::set_serial_stream(const SerialStream* serial_stream) {
3838
serial_stream_ = serial_stream;
3939
}
4040

41-
void Shell::set_default_callback(CommandCallback callback) {
41+
void Shell::set_default_callback(CommandCallback callback, void* context) {
4242
default_callback_ = callback;
43+
default_callback_context_ = context;
4344
}
4445

4546
void Shell::register_command(const char* name, CommandCallback callback, void* context) {
@@ -105,7 +106,7 @@ void Shell::execute_callback(int argc, char** argv) {
105106

106107
// Unknown command received, executing default callback.
107108
if (default_callback_ != nullptr) {
108-
default_callback_(nullptr, argc, argv);
109+
default_callback_(default_callback_context_, argc, argv);
109110
}
110111
}
111112

andino_firmware/src/main.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2929
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3030
#include <Adafruit_BNO055.h>
31+
#include <Arduino.h>
3132
#include <Wire.h>
3233

3334
#include "andino/app/app.h"
@@ -63,12 +64,20 @@ static andino::App app(sys_clock, serial_stream, left_motor_enable, left_motor_f
6364
///
6465
/// @return Execution final status (never reached).
6566
int main(void) {
67+
// Required by Arduino libraries to work.
68+
init();
69+
6670
// Application configuration.
6771
app.setup();
6872

6973
// Application main run loop.
7074
while (1) {
7175
app.loop();
76+
77+
// Required by Arduino libraries to work.
78+
if (serialEventRun) {
79+
serialEventRun();
80+
}
7281
}
7382

7483
return 0;

0 commit comments

Comments
 (0)